summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleks Kissinger <aleks0@gmail.com>2018-07-20 11:01:34 +0200
committerAleks Kissinger <aleks0@gmail.com>2018-07-20 11:01:34 +0200
commit59eee652c5fea36945a4a8ce2936843bd90d0e1b (patch)
treeeffcdbf741a104f71e4fc395993dfbdb6644f6b4 /src
parent7c4faa67f4b45671884bdccd99d83f92ca655366 (diff)
...
Diffstat (limited to 'src')
-rw-r--r--src/data/edge.cpp826
-rw-r--r--src/data/edge.h260
-rw-r--r--src/data/edgestyle.cpp262
-rw-r--r--src/data/edgestyle.h112
-rw-r--r--src/data/graph.cpp546
-rw-r--r--src/data/graph.h218
-rw-r--r--src/data/graphelementdata.cpp410
-rw-r--r--src/data/graphelementdata.h178
-rw-r--r--src/data/graphelementproperty.cpp154
-rw-r--r--src/data/graphelementproperty.h116
-rw-r--r--src/data/node.cpp236
-rw-r--r--src/data/node.h144
-rw-r--r--src/data/nodestyle.cpp214
-rw-r--r--src/data/nodestyle.h102
-rw-r--r--src/data/style.cpp156
-rw-r--r--src/data/style.h108
-rw-r--r--src/data/tikzassembler.cpp144
-rw-r--r--src/data/tikzassembler.h120
-rw-r--r--src/data/tikzdocument.cpp382
-rw-r--r--src/data/tikzdocument.h138
-rw-r--r--src/data/tikzlexer.l382
-rw-r--r--src/data/tikzparser.y568
-rw-r--r--src/data/tikzparserdefs.h80
-rw-r--r--src/data/tikzstyles.cpp142
-rw-r--r--src/data/tikzstyles.h102
-rw-r--r--src/gui/commands.h8
-rw-r--r--src/gui/edgeitem.cpp442
-rw-r--r--src/gui/edgeitem.h124
-rw-r--r--src/gui/mainmenu.cpp302
-rw-r--r--src/gui/mainmenu.h128
-rw-r--r--src/gui/mainmenu.ui418
-rw-r--r--src/gui/mainwindow.cpp320
-rw-r--r--src/gui/mainwindow.h120
-rw-r--r--src/gui/mainwindow.ui410
-rw-r--r--src/gui/nodeitem.cpp318
-rw-r--r--src/gui/nodeitem.h102
-rw-r--r--src/gui/propertypalette.cpp122
-rw-r--r--src/gui/propertypalette.h92
-rw-r--r--src/gui/propertypalette.ui66
-rw-r--r--src/gui/stylepalette.cpp358
-rw-r--r--src/gui/stylepalette.h122
-rw-r--r--src/gui/stylepalette.ui240
-rw-r--r--src/gui/tikzscene.cpp1560
-rw-r--r--src/gui/tikzscene.h214
-rw-r--r--src/gui/tikzview.cpp256
-rw-r--r--src/gui/tikzview.h104
-rw-r--r--src/gui/toolpalette.cpp172
-rw-r--r--src/gui/toolpalette.h106
-rw-r--r--src/gui/undocommands.cpp856
-rw-r--r--src/gui/undocommands.h388
-rw-r--r--src/main.cpp96
-rw-r--r--src/test/testmain.cpp44
-rw-r--r--src/test/testparser.cpp326
-rw-r--r--src/test/testparser.h36
-rw-r--r--src/test/testtest.cpp20
-rw-r--r--src/test/testtest.h34
-rw-r--r--src/test/testtikzoutput.cpp194
-rw-r--r--src/test/testtikzoutput.h34
-rw-r--r--src/tikzit.cpp422
-rw-r--r--src/tikzit.h282
-rw-r--r--src/util.cpp144
-rw-r--r--src/util.h96
62 files changed, 7588 insertions, 7588 deletions
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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "edge.h"
-#include "tikzit.h"
-#include "util.h"
-
-#include <QDebug>
-#include <QPointF>
-
-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<Node*,Node*> *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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "edge.h"
+#include "tikzit.h"
+#include "util.h"
+
+#include <QDebug>
+#include <QPointF>
+
+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<Node*,Node*> *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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef EDGE_H
-#define EDGE_H
-
-#include "graphelementdata.h"
-#include "node.h"
-#include "edgestyle.h"
-
-#include <QObject>
-#include <QPointF>
-
-class Edge : public QObject
-{
- Q_OBJECT
-public:
- explicit Edge(Node *s, Node *t, QObject *parent = 0);
- ~Edge();
- Edge *copy(QMap<Node *, Node *> *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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef EDGE_H
+#define EDGE_H
+
+#include "graphelementdata.h"
+#include "node.h"
+#include "edgestyle.h"
+
+#include <QObject>
+#include <QPointF>
+
+class Edge : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Edge(Node *s, Node *t, QObject *parent = 0);
+ ~Edge();
+ Edge *copy(QMap<Node *, Node *> *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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "edgestyle.h"
-
-#include <QPainter>
-#include <QPixmap>
-
-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<qreal> 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "edgestyle.h"
+
+#include <QPainter>
+#include <QPixmap>
+
+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<qreal> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef EDGESTYLE_H
-#define EDGESTYLE_H
-
-#include "style.h"
-
-#include <QColor>
-#include <QPen>
-#include <QBrush>
-#include <QPainterPath>
-#include <QIcon>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef EDGESTYLE_H
+#define EDGESTYLE_H
+
+#include "style.h"
+
+#include <QColor>
+#include <QPen>
+#include <QBrush>
+#include <QPainterPath>
+#include <QIcon>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "graph.h"
-#include "util.h"
-
-#include <QTextStream>
-#include <QSet>
-#include <QtAlgorithms>
-#include <QDebug>
-#include <algorithm>
-
-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<Node*> &Graph::nodes()
-{
- return _nodes;
-}
-
-const QVector<Edge*> &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<Node *> nds)
-{
- Graph *g = new Graph();
- g->setData(_data->copy());
- QMap<Node*,Node*> 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<Node*,Node*> 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "graph.h"
+#include "util.h"
+
+#include <QTextStream>
+#include <QSet>
+#include <QtAlgorithms>
+#include <QDebug>
+#include <algorithm>
+
+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<Node*> &Graph::nodes()
+{
+ return _nodes;
+}
+
+const QVector<Edge*> &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<Node *> nds)
+{
+ Graph *g = new Graph();
+ g->setData(_data->copy());
+ QMap<Node*,Node*> 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<Node*,Node*> 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * A graph defined by tikz code.
- */
-
-#ifndef GRAPH_H
-#define GRAPH_H
-
-#include "node.h"
-#include "edge.h"
-#include "graphelementdata.h"
-
-#include <QObject>
-#include <QVector>
-#include <QMultiHash>
-#include <QRectF>
-#include <QString>
-
-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<Node *> &nodes();
- const QVector<Edge*> &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<Node*> 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<Node*> _nodes;
- QVector<Edge*> _edges;
- //QMultiHash<Node*,Edge*> inEdges;
- //QMultiHash<Node*,Edge*> 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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A graph defined by tikz code.
+ */
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include "node.h"
+#include "edge.h"
+#include "graphelementdata.h"
+
+#include <QObject>
+#include <QVector>
+#include <QMultiHash>
+#include <QRectF>
+#include <QString>
+
+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<Node *> &nodes();
+ const QVector<Edge*> &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<Node*> 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<Node*> _nodes;
+ QVector<Edge*> _edges;
+ //QMultiHash<Node*,Edge*> inEdges;
+ //QMultiHash<Node*,Edge*> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "graphelementdata.h"
-
-#include <QDebug>
-#include <QTextStream>
-
-GraphElementData::GraphElementData(QVector<GraphElementProperty> 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<GraphElementProperty*>(index.internalPointer());
- if (p == root) return QModelIndex();
- else return createIndex(0,0,static_cast<void*>(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<GraphElementProperty> 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "graphelementdata.h"
+
+#include <QDebug>
+#include <QTextStream>
+
+GraphElementData::GraphElementData(QVector<GraphElementProperty> 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<GraphElementProperty*>(index.internalPointer());
+ if (p == root) return QModelIndex();
+ else return createIndex(0,0,static_cast<void*>(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<GraphElementProperty> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef GRAPHELEMENTDATA_H
-#define GRAPHELEMENTDATA_H
-
-#include "graphelementproperty.h"
-
-#include <QAbstractItemModel>
-#include <QString>
-#include <QVariant>
-#include <QModelIndex>
-#include <QVector>
-
-class GraphElementData : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- explicit GraphElementData(QVector<GraphElementProperty> 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<GraphElementProperty> properties() const;
-
-signals:
-
-public slots:
-
-private:
- QVector<GraphElementProperty> _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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef GRAPHELEMENTDATA_H
+#define GRAPHELEMENTDATA_H
+
+#include "graphelementproperty.h"
+
+#include <QAbstractItemModel>
+#include <QString>
+#include <QVariant>
+#include <QModelIndex>
+#include <QVector>
+
+class GraphElementData : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ explicit GraphElementData(QVector<GraphElementProperty> 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<GraphElementProperty> properties() const;
+
+signals:
+
+public slots:
+
+private:
+ QVector<GraphElementProperty> _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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "graphelementproperty.h"
-
-#include <QRegExp>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "graphelementproperty.h"
+
+#include <QRegExp>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef GRAPHELEMENTPROPERTY_H
-#define GRAPHELEMENTPROPERTY_H
-
-#include <QObject>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef GRAPHELEMENTPROPERTY_H
+#define GRAPHELEMENTPROPERTY_H
+
+#include <QObject>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "node.h"
-#include "tikzit.h"
-
-#include <QDebug>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "node.h"
+#include "tikzit.h"
+
+#include <QDebug>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef NODE_H
-#define NODE_H
-
-#include "graphelementdata.h"
-#include "nodestyle.h"
-
-#include <QObject>
-#include <QPointF>
-#include <QString>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef NODE_H
+#define NODE_H
+
+#include "graphelementdata.h"
+#include "nodestyle.h"
+
+#include <QObject>
+#include <QPointF>
+#include <QString>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "nodestyle.h"
-#include <QPainter>
-
-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<qreal> 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "nodestyle.h"
+#include <QPainter>
+
+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<qreal> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef NODESTYLE_H
-#define NODESTYLE_H
-
-#include "style.h"
-
-#include <QColor>
-#include <QPen>
-#include <QBrush>
-#include <QPainterPath>
-#include <QIcon>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef NODESTYLE_H
+#define NODESTYLE_H
+
+#include "style.h"
+
+#include <QColor>
+#include <QPen>
+#include <QBrush>
+#include <QPainterPath>
+#include <QIcon>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#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 <https://www.gnu.org/licenses/>.
+*/
+
+#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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef STYLE_H
-#define STYLE_H
-
-
-#include "graphelementdata.h"
-
-#include <QColor>
-#include <QPen>
-#include <QBrush>
-#include <QPainterPath>
-#include <QIcon>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef STYLE_H
+#define STYLE_H
+
+
+#include "graphelementdata.h"
+
+#include <QColor>
+#include <QPen>
+#include <QBrush>
+#include <QPainterPath>
+#include <QIcon>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#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 <https://www.gnu.org/licenses/>.
+*/
+
+#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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * 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 <QObject>
-#include <QHash>
-
-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<QString,Node*> _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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * 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 <QObject>
+#include <QHash>
+
+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<QString,Node*> _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 <https://www.gnu.org/licenses/>.
-*/
-
-#include <QFile>
-#include <QFileInfo>
-#include <QSettings>
-#include <QTextStream>
-#include <QMessageBox>
-#include <QFileDialog>
-
-#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<MainWindow*>(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 <https://www.gnu.org/licenses/>.
+*/
+
+#include <QFile>
+#include <QFileInfo>
+#include <QSettings>
+#include <QTextStream>
+#include <QMessageBox>
+#include <QFileDialog>
+
+#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<MainWindow*>(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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * 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 <QObject>
-#include <QUndoStack>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * 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 <QObject>
+#include <QUndoStack>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-
-/*!
- * \file tikzlexer.l
- *
- * The lexer for tikz input.
- */
-
-#include "tikzparserdefs.h"
-#include "tikzparser.parser.hpp"
-
-#include <sstream>
-
-
-#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 */
-<INITIAL,xcoord,ycoord,props,noderef>\r\n|\r|\n {
- yylloc->first_line += 1;
- yylloc->last_line = yylloc->first_line;
- yylloc->first_column = yylloc->last_column = 0;
-}
-<INITIAL,xcoord,ycoord,props,noderef>[\t ]+ { }
-<INITIAL,xcoord,ycoord,props,noderef>%.*$ { }
-
-\\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; }
-<INITIAL>rectangle { return RECTANGLE; }
-<INITIAL>node { return NODE; }
-<INITIAL>at { return AT; }
-<INITIAL>to { return TO; }
-
-\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) {
- yylloc->last_column = yylloc->first_column + 1;
- yyless(1);
- BEGIN(xcoord);
-}
-<xcoord>{FLOAT} {
- yylval->pt = new QPointF();
- yylval->pt->setX(strtod(yytext,NULL));
- BEGIN(ycoord);
-}
-<ycoord>, { }
-<ycoord>{FLOAT} {
- yylval->pt->setY(strtod(yytext,NULL));
-}
-<ycoord>\) {
- BEGIN(INITIAL);
- return TCOORD;
-}
-
- /* when we see "[", change parsing mode */
-\[ /*syntaxhlfix]*/ {
- BEGIN(props);
- return LEFTBRACKET;
-}
-<props>= { return EQUALS; }
-<props>, { 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 */
-<props>[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? {
- char *str = (char*)malloc(sizeof(char)*yyleng + 1);
- strncpy(str, yytext, yyleng + 1);
- yylval->str = str;
- return PROPSTRING;
-}
-<props>\] {
- BEGIN(INITIAL);
- return RIGHTBRACKET;
-}
-
-\( {
- BEGIN(noderef);
- return LEFTPARENTHESIS;
-}
-<noderef>\. {
- return FULLSTOP;
-}
- /* we assume node names (and anchor names) never contain
- newlines */
-<noderef>[^\.\{\)\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;
-}
-<noderef>\) {
- BEGIN(INITIAL);
- return RIGHTPARENTHESIS;
-}
-
-<INITIAL,props>\{ {
- 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; }
-<INITIAL,xcoord,ycoord,props,noderef>. { 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 <https://www.gnu.org/licenses/>.
+*/
+
+
+/*!
+ * \file tikzlexer.l
+ *
+ * The lexer for tikz input.
+ */
+
+#include "tikzparserdefs.h"
+#include "tikzparser.parser.hpp"
+
+#include <sstream>
+
+
+#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 */
+<INITIAL,xcoord,ycoord,props,noderef>\r\n|\r|\n {
+ yylloc->first_line += 1;
+ yylloc->last_line = yylloc->first_line;
+ yylloc->first_column = yylloc->last_column = 0;
+}
+<INITIAL,xcoord,ycoord,props,noderef>[\t ]+ { }
+<INITIAL,xcoord,ycoord,props,noderef>%.*$ { }
+
+\\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; }
+<INITIAL>rectangle { return RECTANGLE; }
+<INITIAL>node { return NODE; }
+<INITIAL>at { return AT; }
+<INITIAL>to { return TO; }
+
+\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) {
+ yylloc->last_column = yylloc->first_column + 1;
+ yyless(1);
+ BEGIN(xcoord);
+}
+<xcoord>{FLOAT} {
+ yylval->pt = new QPointF();
+ yylval->pt->setX(strtod(yytext,NULL));
+ BEGIN(ycoord);
+}
+<ycoord>, { }
+<ycoord>{FLOAT} {
+ yylval->pt->setY(strtod(yytext,NULL));
+}
+<ycoord>\) {
+ BEGIN(INITIAL);
+ return TCOORD;
+}
+
+ /* when we see "[", change parsing mode */
+\[ /*syntaxhlfix]*/ {
+ BEGIN(props);
+ return LEFTBRACKET;
+}
+<props>= { return EQUALS; }
+<props>, { 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 */
+<props>[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? {
+ char *str = (char*)malloc(sizeof(char)*yyleng + 1);
+ strncpy(str, yytext, yyleng + 1);
+ yylval->str = str;
+ return PROPSTRING;
+}
+<props>\] {
+ BEGIN(INITIAL);
+ return RIGHTBRACKET;
+}
+
+\( {
+ BEGIN(noderef);
+ return LEFTPARENTHESIS;
+}
+<noderef>\. {
+ return FULLSTOP;
+}
+ /* we assume node names (and anchor names) never contain
+ newlines */
+<noderef>[^\.\{\)\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;
+}
+<noderef>\) {
+ BEGIN(INITIAL);
+ return RIGHTPARENTHESIS;
+}
+
+<INITIAL,props>\{ {
+ 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; }
+<INITIAL,xcoord,ycoord,props,noderef>. { 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 <dev@randomguy3.me.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#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 <pt> TCOORD "coordinate"
-%token <str> PROPSTRING "key/value string"
-%token <str> REFSTRING "string"
-%token <str> 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<str> nodename
-%type<str> optanchor
-%type<str> val
-%type<prop> property
-%type<data> extraproperties
-%type<data> properties
-%type<data> optproperties
-%type<node> optedgenode
-%type<noderef> noderef
-%type<noderef> 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 <dev@randomguy3.me.uk>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#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 <pt> TCOORD "coordinate"
+%token <str> PROPSTRING "key/value string"
+%token <str> REFSTRING "string"
+%token <str> 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<str> nodename
+%type<str> optanchor
+%type<str> val
+%type<prop> property
+%type<data> extraproperties
+%type<data> properties
+%type<data> optproperties
+%type<node> optedgenode
+%type<noderef> noderef
+%type<noderef> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#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 <QString>
-#include <QRectF>
-#include <QDebug>
-
-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 <https://www.gnu.org/licenses/>.
+*/
+
+#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 <QString>
+#include <QRectF>
+#include <QDebug>
+
+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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzstyles.h"
-#include "nodestyle.h"
-
-#include <QDebug>
-
-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<NodeStyle *> TikzStyles::nodeStyles() const
-{
- return _nodeStyles;
-}
-
-void TikzStyles::clear()
-{
- _nodeStyles.clear();
- _edgeStyles.clear();
-}
-
-QVector<EdgeStyle *> 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzstyles.h"
+#include "nodestyle.h"
+
+#include <QDebug>
+
+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<NodeStyle *> TikzStyles::nodeStyles() const
+{
+ return _nodeStyles;
+}
+
+void TikzStyles::clear()
+{
+ _nodeStyles.clear();
+ _edgeStyles.clear();
+}
+
+QVector<EdgeStyle *> 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef PROJECT_H
-#define PROJECT_H
-
-#include "graphelementdata.h"
-#include "nodestyle.h"
-#include "edgestyle.h"
-
-#include <QObject>
-#include <QString>
-
-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<NodeStyle *> nodeStyles() const;
- QVector<EdgeStyle *> edgeStyles() const;
- void clear();
-
-signals:
-
-public slots:
-
-private:
- QVector<NodeStyle*> _nodeStyles;
- QVector<EdgeStyle*> _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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef PROJECT_H
+#define PROJECT_H
+
+#include "graphelementdata.h"
+#include "nodestyle.h"
+#include "edgestyle.h"
+
+#include <QObject>
+#include <QString>
+
+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<NodeStyle *> nodeStyles() const;
+ QVector<EdgeStyle *> edgeStyles() const;
+ void clear();
+
+signals:
+
+public slots:
+
+private:
+ QVector<NodeStyle*> _nodeStyles;
+ QVector<EdgeStyle*> _edgeStyles;
+};
+
+#endif // PROJECT_H
diff --git a/src/gui/commands.h b/src/gui/commands.h
index 73bfaa7..9942ba8 100644
--- a/src/gui/commands.h
+++ b/src/gui/commands.h
@@ -1,4 +1,4 @@
-#ifndef COMMANDS_H
-#define COMMANDS_H
-
-#endif // COMMANDS_H
+#ifndef COMMANDS_H
+#define COMMANDS_H
+
+#endif // COMMANDS_H
diff --git a/src/gui/edgeitem.cpp b/src/gui/edgeitem.cpp
index f469506..9cf14c8 100644
--- a/src/gui/edgeitem.cpp
+++ b/src/gui/edgeitem.cpp
@@ -1,221 +1,221 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzit.h"
-#include "edgeitem.h"
-
-#include <QPainterPath>
-#include <QPen>
-
-EdgeItem::EdgeItem(Edge *edge)
-{
- _edge = edge;
- setFlag(QGraphicsItem::ItemIsSelectable);
-
- _cp1Item = new QGraphicsEllipseItem(this);
- _cp1Item->setParentItem(this);
- _cp1Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
- GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
- _cp1Item->setVisible(false);
-
- _cp2Item = new QGraphicsEllipseItem(this);
- _cp2Item->setParentItem(this);
- _cp2Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
- GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
- _cp2Item->setVisible(false);
-
- readPos();
-}
-
-void EdgeItem::readPos()
-{
- //_edge->setAttributesFromData();
- _edge->updateControls();
- QPainterPath path;
-
- path.moveTo (toScreen(_edge->tail()));
-
- if (_edge->bend() != 0 || !_edge->basicBendMode()) {
- path.cubicTo(toScreen(_edge->cp1()),
- toScreen(_edge->cp2()),
- toScreen(_edge->head()));
- }
- else {
- path.lineTo(toScreen(_edge->head()));
- }
-
- setPath(path);
-
- _cp1Item->setPos(toScreen(_edge->cp1()));
- _cp2Item->setPos(toScreen(_edge->cp2()));
-}
-
-void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
-{
- //QGraphicsPathItem::paint(painter, option, widget);
- QPen pen = _edge->style()->pen();
- painter->setPen(pen);
- painter->setBrush(Qt::NoBrush);
- painter->drawPath(path());
-
- QPointF ht = _edge->headTangent();
- QPointF hLeft(-ht.y(), ht.x());
- QPointF hRight(ht.y(), -ht.x());
- QPointF tt = _edge->tailTangent();
- QPointF tLeft(-ht.y(), ht.x());
- QPointF tRight(ht.y(), -ht.x());
-
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
-
-
-
- switch (_edge->style()->arrowHead()) {
- case EdgeStyle::Flat:
- {
- painter->drawLine(
- toScreen(_edge->head() + hLeft),
- toScreen(_edge->head() + hRight));
- break;
- }
- case EdgeStyle::Pointer:
- {
- QPainterPath pth;
- pth.moveTo(toScreen(_edge->head() + ht + hLeft));
- pth.lineTo(toScreen(_edge->head()));
- pth.lineTo(toScreen(_edge->head() + ht + hRight));
- painter->drawPath(pth);
- break;
- }
- }
-
- switch (_edge->style()->arrowTail()) {
- case EdgeStyle::Flat:
- {
- painter->drawLine(
- toScreen(_edge->tail() + tLeft),
- toScreen(_edge->tail() + tRight));
- break;
- }
- case EdgeStyle::Pointer:
- {
- QPainterPath pth;
- pth.moveTo(toScreen(_edge->tail() + tt + tLeft));
- pth.lineTo(toScreen(_edge->tail()));
- pth.lineTo(toScreen(_edge->tail() + tt + tRight));
- painter->drawPath(pth);
- break;
- }
- }
-
- if (isSelected()) {
- QColor draw;
- QColor draw1;
- QColor fill;
-
- if (_edge->basicBendMode()) {
- draw = Qt::blue;
- draw1 = QColor(100,100,255,100);
- fill = QColor(200,200,255,50);
- } else {
- draw = Qt::darkGreen;
- draw1 = QColor(0, 150, 0, 50);
- fill = QColor(200,255,200,150);
- }
-
- painter->setPen(QPen(draw1));
-
- float r = GLOBAL_SCALEF * _edge->cpDist();
- painter->drawEllipse(toScreen(_edge->source()->point()), r, r);
- painter->drawEllipse(toScreen(_edge->target()->point()), r, r);
-
- painter->setPen(QPen(draw));
- painter->setBrush(QBrush(fill));
-
- painter->drawLine(toScreen(_edge->tail()), toScreen(_edge->cp1()));
- painter->drawLine(toScreen(_edge->head()), toScreen(_edge->cp2()));
-
- //painter->drawEllipse(toScreen(_edge->cp1()), r, r);
- //painter->drawEllipse(toScreen(_edge->cp2()), r, r);
-
- _cp1Item->setPen(QPen(draw));
- _cp1Item->setBrush(QBrush(fill));
- _cp1Item->setVisible(true);
-
- _cp2Item->setPen(QPen(draw));
- _cp2Item->setBrush(QBrush(fill));
- _cp2Item->setVisible(true);
-
- r = GLOBAL_SCALEF * 0.05;
- painter->setPen(QPen(Qt::black));
- painter->setBrush(QBrush(QColor(255,255,255,200)));
- painter->drawEllipse(toScreen(_edge->mid()), r, r);
- } else {
- _cp1Item->setVisible(false);
- _cp2Item->setVisible(false);
- }
-}
-
-QRectF EdgeItem::boundingRect() const
-{
- return _boundingRect;
-}
-
-QPainterPath EdgeItem::shape() const
-{
- return _expPath;
-}
-
-Edge *EdgeItem::edge() const
-{
- return _edge;
-}
-
-QGraphicsEllipseItem *EdgeItem::cp1Item() const
-{
- return _cp1Item;
-}
-
-QGraphicsEllipseItem *EdgeItem::cp2Item() const
-{
- return _cp2Item;
-}
-
-QPainterPath EdgeItem::path() const
-{
- return _path;
-}
-
-void EdgeItem::setPath(const QPainterPath &path)
-{
- prepareGeometryChange();
-
- _path = path;
-
- // get the shape of the edge, and expand a bit to make selection easier
- QPainterPathStroker stroker;
- stroker.setWidth(5);
- stroker.setJoinStyle(Qt::MiterJoin);
- _expPath = (stroker.createStroke(_path) + _path).simplified();
-
- float r = GLOBAL_SCALEF * (_edge->cpDist() + 0.2);
- _boundingRect = _path.boundingRect().adjusted(-r,-r,r,r);
-
- update();
-}
-
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "edgeitem.h"
+
+#include <QPainterPath>
+#include <QPen>
+
+EdgeItem::EdgeItem(Edge *edge)
+{
+ _edge = edge;
+ setFlag(QGraphicsItem::ItemIsSelectable);
+
+ _cp1Item = new QGraphicsEllipseItem(this);
+ _cp1Item->setParentItem(this);
+ _cp1Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
+ GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ _cp1Item->setVisible(false);
+
+ _cp2Item = new QGraphicsEllipseItem(this);
+ _cp2Item->setParentItem(this);
+ _cp2Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
+ GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ _cp2Item->setVisible(false);
+
+ readPos();
+}
+
+void EdgeItem::readPos()
+{
+ //_edge->setAttributesFromData();
+ _edge->updateControls();
+ QPainterPath path;
+
+ path.moveTo (toScreen(_edge->tail()));
+
+ if (_edge->bend() != 0 || !_edge->basicBendMode()) {
+ path.cubicTo(toScreen(_edge->cp1()),
+ toScreen(_edge->cp2()),
+ toScreen(_edge->head()));
+ }
+ else {
+ path.lineTo(toScreen(_edge->head()));
+ }
+
+ setPath(path);
+
+ _cp1Item->setPos(toScreen(_edge->cp1()));
+ _cp2Item->setPos(toScreen(_edge->cp2()));
+}
+
+void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ //QGraphicsPathItem::paint(painter, option, widget);
+ QPen pen = _edge->style()->pen();
+ painter->setPen(pen);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(path());
+
+ QPointF ht = _edge->headTangent();
+ QPointF hLeft(-ht.y(), ht.x());
+ QPointF hRight(ht.y(), -ht.x());
+ QPointF tt = _edge->tailTangent();
+ QPointF tLeft(-ht.y(), ht.x());
+ QPointF tRight(ht.y(), -ht.x());
+
+ pen.setStyle(Qt::SolidLine);
+ painter->setPen(pen);
+
+
+
+ switch (_edge->style()->arrowHead()) {
+ case EdgeStyle::Flat:
+ {
+ painter->drawLine(
+ toScreen(_edge->head() + hLeft),
+ toScreen(_edge->head() + hRight));
+ break;
+ }
+ case EdgeStyle::Pointer:
+ {
+ QPainterPath pth;
+ pth.moveTo(toScreen(_edge->head() + ht + hLeft));
+ pth.lineTo(toScreen(_edge->head()));
+ pth.lineTo(toScreen(_edge->head() + ht + hRight));
+ painter->drawPath(pth);
+ break;
+ }
+ }
+
+ switch (_edge->style()->arrowTail()) {
+ case EdgeStyle::Flat:
+ {
+ painter->drawLine(
+ toScreen(_edge->tail() + tLeft),
+ toScreen(_edge->tail() + tRight));
+ break;
+ }
+ case EdgeStyle::Pointer:
+ {
+ QPainterPath pth;
+ pth.moveTo(toScreen(_edge->tail() + tt + tLeft));
+ pth.lineTo(toScreen(_edge->tail()));
+ pth.lineTo(toScreen(_edge->tail() + tt + tRight));
+ painter->drawPath(pth);
+ break;
+ }
+ }
+
+ if (isSelected()) {
+ QColor draw;
+ QColor draw1;
+ QColor fill;
+
+ if (_edge->basicBendMode()) {
+ draw = Qt::blue;
+ draw1 = QColor(100,100,255,100);
+ fill = QColor(200,200,255,50);
+ } else {
+ draw = Qt::darkGreen;
+ draw1 = QColor(0, 150, 0, 50);
+ fill = QColor(200,255,200,150);
+ }
+
+ painter->setPen(QPen(draw1));
+
+ float r = GLOBAL_SCALEF * _edge->cpDist();
+ painter->drawEllipse(toScreen(_edge->source()->point()), r, r);
+ painter->drawEllipse(toScreen(_edge->target()->point()), r, r);
+
+ painter->setPen(QPen(draw));
+ painter->setBrush(QBrush(fill));
+
+ painter->drawLine(toScreen(_edge->tail()), toScreen(_edge->cp1()));
+ painter->drawLine(toScreen(_edge->head()), toScreen(_edge->cp2()));
+
+ //painter->drawEllipse(toScreen(_edge->cp1()), r, r);
+ //painter->drawEllipse(toScreen(_edge->cp2()), r, r);
+
+ _cp1Item->setPen(QPen(draw));
+ _cp1Item->setBrush(QBrush(fill));
+ _cp1Item->setVisible(true);
+
+ _cp2Item->setPen(QPen(draw));
+ _cp2Item->setBrush(QBrush(fill));
+ _cp2Item->setVisible(true);
+
+ r = GLOBAL_SCALEF * 0.05;
+ painter->setPen(QPen(Qt::black));
+ painter->setBrush(QBrush(QColor(255,255,255,200)));
+ painter->drawEllipse(toScreen(_edge->mid()), r, r);
+ } else {
+ _cp1Item->setVisible(false);
+ _cp2Item->setVisible(false);
+ }
+}
+
+QRectF EdgeItem::boundingRect() const
+{
+ return _boundingRect;
+}
+
+QPainterPath EdgeItem::shape() const
+{
+ return _expPath;
+}
+
+Edge *EdgeItem::edge() const
+{
+ return _edge;
+}
+
+QGraphicsEllipseItem *EdgeItem::cp1Item() const
+{
+ return _cp1Item;
+}
+
+QGraphicsEllipseItem *EdgeItem::cp2Item() const
+{
+ return _cp2Item;
+}
+
+QPainterPath EdgeItem::path() const
+{
+ return _path;
+}
+
+void EdgeItem::setPath(const QPainterPath &path)
+{
+ prepareGeometryChange();
+
+ _path = path;
+
+ // get the shape of the edge, and expand a bit to make selection easier
+ QPainterPathStroker stroker;
+ stroker.setWidth(5);
+ stroker.setJoinStyle(Qt::MiterJoin);
+ _expPath = (stroker.createStroke(_path) + _path).simplified();
+
+ float r = GLOBAL_SCALEF * (_edge->cpDist() + 0.2);
+ _boundingRect = _path.boundingRect().adjusted(-r,-r,r,r);
+
+ update();
+}
+
diff --git a/src/gui/edgeitem.h b/src/gui/edgeitem.h
index 3d4758a..060de13 100644
--- a/src/gui/edgeitem.h
+++ b/src/gui/edgeitem.h
@@ -1,62 +1,62 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * A QGraphicsItem that handles drawing a single edge.
- */
-
-#ifndef EDGEITEM_H
-#define EDGEITEM_H
-
-#include "edge.h"
-
-#include <QObject>
-#include <QGraphicsPathItem>
-#include <QPainter>
-#include <QStyleOptionGraphicsItem>
-#include <QWidget>
-#include <QGraphicsEllipseItem>
-#include <QString>
-
-class EdgeItem : public QGraphicsItem
-{
-public:
- EdgeItem(Edge *edge);
- void readPos();
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
- QRectF boundingRect() const;
- QPainterPath shape() const;
- Edge *edge() const;
- QGraphicsEllipseItem *cp1Item() const;
- QGraphicsEllipseItem *cp2Item() const;
-
-
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
-
-
-private:
- Edge *_edge;
- QPainterPath _path;
- QPainterPath _expPath;
- QRectF _boundingRect;
- QGraphicsEllipseItem *_cp1Item;
- QGraphicsEllipseItem *_cp2Item;
-};
-
-#endif // EDGEITEM_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A QGraphicsItem that handles drawing a single edge.
+ */
+
+#ifndef EDGEITEM_H
+#define EDGEITEM_H
+
+#include "edge.h"
+
+#include <QObject>
+#include <QGraphicsPathItem>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QWidget>
+#include <QGraphicsEllipseItem>
+#include <QString>
+
+class EdgeItem : public QGraphicsItem
+{
+public:
+ EdgeItem(Edge *edge);
+ void readPos();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ Edge *edge() const;
+ QGraphicsEllipseItem *cp1Item() const;
+ QGraphicsEllipseItem *cp2Item() const;
+
+
+ QPainterPath path() const;
+ void setPath(const QPainterPath &path);
+
+
+private:
+ Edge *_edge;
+ QPainterPath _path;
+ QPainterPath _expPath;
+ QRectF _boundingRect;
+ QGraphicsEllipseItem *_cp1Item;
+ QGraphicsEllipseItem *_cp2Item;
+};
+
+#endif // EDGEITEM_H
diff --git a/src/gui/mainmenu.cpp b/src/gui/mainmenu.cpp
index 3625338..69159d2 100644
--- a/src/gui/mainmenu.cpp
+++ b/src/gui/mainmenu.cpp
@@ -1,151 +1,151 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "mainmenu.h"
-#include "tikzit.h"
-
-#include <QDebug>
-
-MainMenu::MainMenu()
-{
- ui.setupUi(this);
-}
-
-// File
-void MainMenu::on_actionNew_triggered()
-{
- tikzit->newDoc();
-}
-
-void MainMenu::on_actionOpen_triggered()
-{
- tikzit->open();
-}
-
-void MainMenu::on_actionClose_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->close();
-}
-
-void MainMenu::on_actionSave_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzDocument()->save();
-}
-
-void MainMenu::on_actionSave_As_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzDocument()->saveAs();
-}
-
-void MainMenu::on_actionExit_triggered()
-{
- tikzit->quit();
-}
-
-
-// Edit
-void MainMenu::on_actionUndo_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzDocument()->undoStack()->undo();
-}
-
-void MainMenu::on_actionRedo_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzDocument()->undoStack()->redo();
-}
-
-void MainMenu::on_actionCut_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->cutToClipboard();
-}
-
-void MainMenu::on_actionCopy_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->copyToClipboard();
-}
-
-void MainMenu::on_actionPaste_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->pasteFromClipboard();
-}
-
-void MainMenu::on_actionDelete_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->deleteSelectedItems();
-}
-
-void MainMenu::on_actionSelect_All_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->selectAllNodes();
-}
-
-void MainMenu::on_actionDeselect_All_triggered()
-{
- if (tikzit->activeWindow() != 0)
- tikzit->activeWindow()->tikzScene()->deselectAll();
-}
-
-
-// Tikz
-void MainMenu::on_actionParse_triggered()
-{
- MainWindow *win = tikzit->activeWindow();
- if (win != 0) {
- win->tikzScene()->parseTikz(win->tikzSource());
- }
-}
-
-void MainMenu::on_actionRevert_triggered()
-{
- MainWindow *win = tikzit->activeWindow();
- if (win != 0) {
- win->tikzDocument()->refreshTikz();
- win->tikzScene()->setEnabled(true);
- }
-}
-
-void MainMenu::on_actionJump_to_Selection_triggered()
-{
- MainWindow *win = tikzit->activeWindow();
- if (win != 0) {
- qDebug() << "jump to selection on line:" << win->tikzScene()->lineNumberForSelection();
- win->setSourceLine(win->tikzScene()->lineNumberForSelection());
- }
-}
-
-
-// View
-void MainMenu::on_actionZoom_In_triggered()
-{
- if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomIn();
-}
-
-void MainMenu::on_actionZoom_Out_triggered()
-{
- if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomOut();
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "mainmenu.h"
+#include "tikzit.h"
+
+#include <QDebug>
+
+MainMenu::MainMenu()
+{
+ ui.setupUi(this);
+}
+
+// File
+void MainMenu::on_actionNew_triggered()
+{
+ tikzit->newDoc();
+}
+
+void MainMenu::on_actionOpen_triggered()
+{
+ tikzit->open();
+}
+
+void MainMenu::on_actionClose_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->close();
+}
+
+void MainMenu::on_actionSave_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->save();
+}
+
+void MainMenu::on_actionSave_As_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->saveAs();
+}
+
+void MainMenu::on_actionExit_triggered()
+{
+ tikzit->quit();
+}
+
+
+// Edit
+void MainMenu::on_actionUndo_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->undoStack()->undo();
+}
+
+void MainMenu::on_actionRedo_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->undoStack()->redo();
+}
+
+void MainMenu::on_actionCut_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->cutToClipboard();
+}
+
+void MainMenu::on_actionCopy_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->copyToClipboard();
+}
+
+void MainMenu::on_actionPaste_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->pasteFromClipboard();
+}
+
+void MainMenu::on_actionDelete_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->deleteSelectedItems();
+}
+
+void MainMenu::on_actionSelect_All_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->selectAllNodes();
+}
+
+void MainMenu::on_actionDeselect_All_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->deselectAll();
+}
+
+
+// Tikz
+void MainMenu::on_actionParse_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ win->tikzScene()->parseTikz(win->tikzSource());
+ }
+}
+
+void MainMenu::on_actionRevert_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ win->tikzDocument()->refreshTikz();
+ win->tikzScene()->setEnabled(true);
+ }
+}
+
+void MainMenu::on_actionJump_to_Selection_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ qDebug() << "jump to selection on line:" << win->tikzScene()->lineNumberForSelection();
+ win->setSourceLine(win->tikzScene()->lineNumberForSelection());
+ }
+}
+
+
+// View
+void MainMenu::on_actionZoom_In_triggered()
+{
+ if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomIn();
+}
+
+void MainMenu::on_actionZoom_Out_triggered()
+{
+ if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomOut();
+}
diff --git a/src/gui/mainmenu.h b/src/gui/mainmenu.h
index aa5c727..8cb7a3a 100644
--- a/src/gui/mainmenu.h
+++ b/src/gui/mainmenu.h
@@ -1,64 +1,64 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef MAINMENU_H
-#define MAINMENU_H
-
-#include "ui_mainmenu.h"
-
-#include <QMenuBar>
-
-class MainMenu : public QMenuBar
-{
- Q_OBJECT
-public:
- MainMenu();
-
-private:
- Ui::MainMenu ui;
-
-public slots:
- // File
- void on_actionNew_triggered();
- void on_actionOpen_triggered();
- void on_actionClose_triggered();
- void on_actionSave_triggered();
- void on_actionSave_As_triggered();
- void on_actionExit_triggered();
-
- // Edit
- void on_actionUndo_triggered();
- void on_actionRedo_triggered();
- void on_actionCut_triggered();
- void on_actionCopy_triggered();
- void on_actionPaste_triggered();
- void on_actionDelete_triggered();
- void on_actionSelect_All_triggered();
- void on_actionDeselect_All_triggered();
-
- // Tikz
- void on_actionParse_triggered();
- void on_actionRevert_triggered();
- void on_actionJump_to_Selection_triggered();
-
- // View
- void on_actionZoom_In_triggered();
- void on_actionZoom_Out_triggered();
-};
-
-#endif // MAINMENU_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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef MAINMENU_H
+#define MAINMENU_H
+
+#include "ui_mainmenu.h"
+
+#include <QMenuBar>
+
+class MainMenu : public QMenuBar
+{
+ Q_OBJECT
+public:
+ MainMenu();
+
+private:
+ Ui::MainMenu ui;
+
+public slots:
+ // File
+ void on_actionNew_triggered();
+ void on_actionOpen_triggered();
+ void on_actionClose_triggered();
+ void on_actionSave_triggered();
+ void on_actionSave_As_triggered();
+ void on_actionExit_triggered();
+
+ // Edit
+ void on_actionUndo_triggered();
+ void on_actionRedo_triggered();
+ void on_actionCut_triggered();
+ void on_actionCopy_triggered();
+ void on_actionPaste_triggered();
+ void on_actionDelete_triggered();
+ void on_actionSelect_All_triggered();
+ void on_actionDeselect_All_triggered();
+
+ // Tikz
+ void on_actionParse_triggered();
+ void on_actionRevert_triggered();
+ void on_actionJump_to_Selection_triggered();
+
+ // View
+ void on_actionZoom_In_triggered();
+ void on_actionZoom_Out_triggered();
+};
+
+#endif // MAINMENU_H
diff --git a/src/gui/mainmenu.ui b/src/gui/mainmenu.ui
index 6a2511e..ce7d41d 100644
--- a/src/gui/mainmenu.ui
+++ b/src/gui/mainmenu.ui
@@ -1,209 +1,209 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainMenu</class>
- <widget class="QMenuBar" name="MainMenu">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>476</width>
- <height>22</height>
- </rect>
- </property>
- <widget class="QMenu" name="menuFile">
- <property name="title">
- <string>File</string>
- </property>
- <addaction name="actionNew"/>
- <addaction name="actionOpen"/>
- <addaction name="separator"/>
- <addaction name="actionClose"/>
- <addaction name="actionSave"/>
- <addaction name="actionSave_As"/>
- <addaction name="separator"/>
- <addaction name="actionExit"/>
- </widget>
- <widget class="QMenu" name="menuEdit">
- <property name="title">
- <string>Edit</string>
- </property>
- <addaction name="actionUndo"/>
- <addaction name="actionRedo"/>
- <addaction name="separator"/>
- <addaction name="actionCut"/>
- <addaction name="actionCopy"/>
- <addaction name="actionPaste"/>
- <addaction name="actionDelete"/>
- <addaction name="separator"/>
- <addaction name="actionSelect_All"/>
- <addaction name="actionDeselect_All"/>
- </widget>
- <widget class="QMenu" name="menuTikz">
- <property name="title">
- <string>Tikz</string>
- </property>
- <addaction name="actionParse"/>
- <addaction name="actionRevert"/>
- <addaction name="actionJump_to_Selection"/>
- </widget>
- <widget class="QMenu" name="menuView">
- <property name="title">
- <string>View</string>
- </property>
- <addaction name="actionZoom_In"/>
- <addaction name="actionZoom_Out"/>
- </widget>
- <action name="actionNew">
- <property name="text">
- <string>New...</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+N</string>
- </property>
- </action>
- <action name="actionOpen">
- <property name="text">
- <string>Open...</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+O</string>
- </property>
- </action>
- <action name="actionClose">
- <property name="text">
- <string>Close</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+W</string>
- </property>
- </action>
- <action name="actionSave">
- <property name="text">
- <string>Save</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+S</string>
- </property>
- </action>
- <action name="actionSave_As">
- <property name="text">
- <string>Save As...</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+Shift+S</string>
- </property>
- </action>
- <action name="actionUndo">
- <property name="text">
- <string>Undo</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+Z</string>
- </property>
- </action>
- <action name="actionRedo">
- <property name="text">
- <string>Redo</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+Shift+Z</string>
- </property>
- </action>
- <action name="actionCut">
- <property name="text">
- <string>Cut</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+X</string>
- </property>
- </action>
- <action name="actionCopy">
- <property name="text">
- <string>Copy</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+C</string>
- </property>
- </action>
- <action name="actionPaste">
- <property name="text">
- <string>Paste</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+V</string>
- </property>
- </action>
- <action name="actionDelete">
- <property name="text">
- <string>Delete</string>
- </property>
- <property name="shortcut">
- <string>Backspace</string>
- </property>
- </action>
- <action name="actionSelect_All">
- <property name="text">
- <string>Select All</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+A</string>
- </property>
- </action>
- <action name="actionDeselect_All">
- <property name="text">
- <string>Deselect All</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+D</string>
- </property>
- </action>
- <action name="actionParse">
- <property name="text">
- <string>Parse Tikz</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+T</string>
- </property>
- </action>
- <action name="actionZoom_In">
- <property name="text">
- <string>Zoom In</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+=</string>
- </property>
- </action>
- <action name="actionZoom_Out">
- <property name="text">
- <string>Zoom Out</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+-</string>
- </property>
- </action>
- <action name="actionExit">
- <property name="text">
- <string>Exit</string>
- </property>
- </action>
- <action name="actionRevert">
- <property name="text">
- <string>Revert Tikz</string>
- </property>
- </action>
- <action name="actionJump_to_Selection">
- <property name="text">
- <string>Jump to Selection</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+J</string>
- </property>
- </action>
- <addaction name="menuFile"/>
- <addaction name="menuEdit"/>
- <addaction name="menuView"/>
- <addaction name="menuTikz"/>
- </widget>
- <resources/>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainMenu</class>
+ <widget class="QMenuBar" name="MainMenu">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>476</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="actionNew"/>
+ <addaction name="actionOpen"/>
+ <addaction name="separator"/>
+ <addaction name="actionClose"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSave_As"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <widget class="QMenu" name="menuEdit">
+ <property name="title">
+ <string>Edit</string>
+ </property>
+ <addaction name="actionUndo"/>
+ <addaction name="actionRedo"/>
+ <addaction name="separator"/>
+ <addaction name="actionCut"/>
+ <addaction name="actionCopy"/>
+ <addaction name="actionPaste"/>
+ <addaction name="actionDelete"/>
+ <addaction name="separator"/>
+ <addaction name="actionSelect_All"/>
+ <addaction name="actionDeselect_All"/>
+ </widget>
+ <widget class="QMenu" name="menuTikz">
+ <property name="title">
+ <string>Tikz</string>
+ </property>
+ <addaction name="actionParse"/>
+ <addaction name="actionRevert"/>
+ <addaction name="actionJump_to_Selection"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>View</string>
+ </property>
+ <addaction name="actionZoom_In"/>
+ <addaction name="actionZoom_Out"/>
+ </widget>
+ <action name="actionNew">
+ <property name="text">
+ <string>New...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="actionOpen">
+ <property name="text">
+ <string>Open...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+W</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionSave_As">
+ <property name="text">
+ <string>Save As...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+S</string>
+ </property>
+ </action>
+ <action name="actionUndo">
+ <property name="text">
+ <string>Undo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Z</string>
+ </property>
+ </action>
+ <action name="actionRedo">
+ <property name="text">
+ <string>Redo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+Z</string>
+ </property>
+ </action>
+ <action name="actionCut">
+ <property name="text">
+ <string>Cut</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+X</string>
+ </property>
+ </action>
+ <action name="actionCopy">
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionPaste">
+ <property name="text">
+ <string>Paste</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+V</string>
+ </property>
+ </action>
+ <action name="actionDelete">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Backspace</string>
+ </property>
+ </action>
+ <action name="actionSelect_All">
+ <property name="text">
+ <string>Select All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+A</string>
+ </property>
+ </action>
+ <action name="actionDeselect_All">
+ <property name="text">
+ <string>Deselect All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+D</string>
+ </property>
+ </action>
+ <action name="actionParse">
+ <property name="text">
+ <string>Parse Tikz</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ <action name="actionZoom_In">
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+=</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out">
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+-</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </action>
+ <action name="actionRevert">
+ <property name="text">
+ <string>Revert Tikz</string>
+ </property>
+ </action>
+ <action name="actionJump_to_Selection">
+ <property name="text">
+ <string>Jump to Selection</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+J</string>
+ </property>
+ </action>
+ <addaction name="menuFile"/>
+ <addaction name="menuEdit"/>
+ <addaction name="menuView"/>
+ <addaction name="menuTikz"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index 15b6943..953889e 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -1,160 +1,160 @@
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-
-#include "mainmenu.h"
-#include "tikzassembler.h"
-#include "toolpalette.h"
-#include "tikzit.h"
-
-#include <QDebug>
-#include <QFile>
-#include <QList>
-#include <QSettings>
-#include <QMessageBox>
-#include <QFileDialog>
-#include <QTextEdit>
-#include <QTextBlock>
-
-int MainWindow::_numWindows = 0;
-
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
-{
- _windowId = _numWindows;
- _numWindows++;
- ui->setupUi(this);
- setAttribute(Qt::WA_DeleteOnClose, true);
- _tikzDocument = new TikzDocument(this);
-
- _toolPalette = new ToolPalette(this);
- addToolBar(_toolPalette);
-
- _stylePalette = new StylePalette(this);
- addDockWidget(Qt::RightDockWidgetArea, _stylePalette);
-
- _tikzScene = new TikzScene(_tikzDocument, _toolPalette, _stylePalette, this);
- ui->tikzView->setScene(_tikzScene);
-
- // TODO: check if each window should have a menu
- _menu = new MainMenu();
- _menu->setParent(this);
-
- setMenuBar(_menu);
-
- // initially, the source view should be collapsed
- QList<int> sz = ui->splitter->sizes();
- sz[0] = sz[0] + sz[1];
- sz[1] = 0;
- ui->splitter->setSizes(sz);
-
- _tikzDocument->refreshTikz();
-
- connect(_tikzDocument->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateFileName()));
-}
-
-MainWindow::~MainWindow()
-{
- tikzit->removeWindow(this);
- delete ui;
-}
-
-void MainWindow::open(QString fileName)
-{
- _tikzDocument->open(fileName);
-
- //ui->tikzSource->setText(_tikzDocument->tikz());
-
-
- if (_tikzDocument->parseSuccess()) {
- statusBar()->showMessage("TiKZ parsed successfully", 2000);
- //setWindowTitle("TiKZiT - " + _tikzDocument->shortName());
- _tikzScene->setTikzDocument(_tikzDocument);
- updateFileName();
- } else {
- statusBar()->showMessage("Cannot read TiKZ source");
- }
-
-}
-
-void MainWindow::closeEvent(QCloseEvent *event)
-{
- qDebug() << "got close event";
- QMainWindow::closeEvent(event);
-}
-
-void MainWindow::changeEvent(QEvent *event)
-{
- if (event->type() == QEvent::ActivationChange && isActiveWindow()) {
- tikzit->setActiveWindow(this);
- //tikzit->stylePalette()->raise();
- }
- QMainWindow::changeEvent(event);
-}
-
-StylePalette *MainWindow::stylePalette() const
-{
- return _stylePalette;
-}
-
-QString MainWindow::tikzSource()
-{
- return ui->tikzSource->toPlainText();
-}
-
-void MainWindow::setSourceLine(int line)
-{
- QTextCursor cursor(ui->tikzSource->document()->findBlockByLineNumber(line));
- cursor.movePosition(QTextCursor::EndOfLine);
- //ui->tikzSource->moveCursor(QTextCursor::End);
- ui->tikzSource->setTextCursor(cursor);
- ui->tikzSource->setFocus();
-}
-
-void MainWindow::updateFileName()
-{
- QString nm = _tikzDocument->shortName();
- if (nm.isEmpty()) nm = "untitled";
- if (!_tikzDocument->isClean()) nm += "*";
- setWindowTitle("TiKZiT - " + nm);
-}
-
-void MainWindow::refreshTikz()
-{
- // don't emit textChanged() when we update the tikz
- ui->tikzSource->blockSignals(true);
- ui->tikzSource->setText(_tikzDocument->tikz());
- ui->tikzSource->blockSignals(false);
-}
-
-ToolPalette *MainWindow::toolPalette() const
-{
- return _toolPalette;
-}
-
-TikzDocument *MainWindow::tikzDocument() const
-{
- return _tikzDocument;
-}
-
-TikzScene *MainWindow::tikzScene() const
-{
- return _tikzScene;
-}
-
-int MainWindow::windowId() const
-{
- return _windowId;
-}
-
-TikzView *MainWindow::tikzView() const
-{
- return ui->tikzView;
-}
-
-void MainWindow::on_tikzSource_textChanged()
-{
- if (_tikzScene->enabled()) _tikzScene->setEnabled(false);
-}
-
-
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include "mainmenu.h"
+#include "tikzassembler.h"
+#include "toolpalette.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QFile>
+#include <QList>
+#include <QSettings>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QTextEdit>
+#include <QTextBlock>
+
+int MainWindow::_numWindows = 0;
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ _windowId = _numWindows;
+ _numWindows++;
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ _tikzDocument = new TikzDocument(this);
+
+ _toolPalette = new ToolPalette(this);
+ addToolBar(_toolPalette);
+
+ _stylePalette = new StylePalette(this);
+ addDockWidget(Qt::RightDockWidgetArea, _stylePalette);
+
+ _tikzScene = new TikzScene(_tikzDocument, _toolPalette, _stylePalette, this);
+ ui->tikzView->setScene(_tikzScene);
+
+ // TODO: check if each window should have a menu
+ _menu = new MainMenu();
+ _menu->setParent(this);
+
+ setMenuBar(_menu);
+
+ // initially, the source view should be collapsed
+ QList<int> sz = ui->splitter->sizes();
+ sz[0] = sz[0] + sz[1];
+ sz[1] = 0;
+ ui->splitter->setSizes(sz);
+
+ _tikzDocument->refreshTikz();
+
+ connect(_tikzDocument->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateFileName()));
+}
+
+MainWindow::~MainWindow()
+{
+ tikzit->removeWindow(this);
+ delete ui;
+}
+
+void MainWindow::open(QString fileName)
+{
+ _tikzDocument->open(fileName);
+
+ //ui->tikzSource->setText(_tikzDocument->tikz());
+
+
+ if (_tikzDocument->parseSuccess()) {
+ statusBar()->showMessage("TiKZ parsed successfully", 2000);
+ //setWindowTitle("TiKZiT - " + _tikzDocument->shortName());
+ _tikzScene->setTikzDocument(_tikzDocument);
+ updateFileName();
+ } else {
+ statusBar()->showMessage("Cannot read TiKZ source");
+ }
+
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ qDebug() << "got close event";
+ QMainWindow::closeEvent(event);
+}
+
+void MainWindow::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::ActivationChange && isActiveWindow()) {
+ tikzit->setActiveWindow(this);
+ //tikzit->stylePalette()->raise();
+ }
+ QMainWindow::changeEvent(event);
+}
+
+StylePalette *MainWindow::stylePalette() const
+{
+ return _stylePalette;
+}
+
+QString MainWindow::tikzSource()
+{
+ return ui->tikzSource->toPlainText();
+}
+
+void MainWindow::setSourceLine(int line)
+{
+ QTextCursor cursor(ui->tikzSource->document()->findBlockByLineNumber(line));
+ cursor.movePosition(QTextCursor::EndOfLine);
+ //ui->tikzSource->moveCursor(QTextCursor::End);
+ ui->tikzSource->setTextCursor(cursor);
+ ui->tikzSource->setFocus();
+}
+
+void MainWindow::updateFileName()
+{
+ QString nm = _tikzDocument->shortName();
+ if (nm.isEmpty()) nm = "untitled";
+ if (!_tikzDocument->isClean()) nm += "*";
+ setWindowTitle("TiKZiT - " + nm);
+}
+
+void MainWindow::refreshTikz()
+{
+ // don't emit textChanged() when we update the tikz
+ ui->tikzSource->blockSignals(true);
+ ui->tikzSource->setText(_tikzDocument->tikz());
+ ui->tikzSource->blockSignals(false);
+}
+
+ToolPalette *MainWindow::toolPalette() const
+{
+ return _toolPalette;
+}
+
+TikzDocument *MainWindow::tikzDocument() const
+{
+ return _tikzDocument;
+}
+
+TikzScene *MainWindow::tikzScene() const
+{
+ return _tikzScene;
+}
+
+int MainWindow::windowId() const
+{
+ return _windowId;
+}
+
+TikzView *MainWindow::tikzView() const
+{
+ return ui->tikzView;
+}
+
+void MainWindow::on_tikzSource_textChanged()
+{
+ if (_tikzScene->enabled()) _tikzScene->setEnabled(false);
+}
+
+
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index 1e05239..3ab641c 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -1,60 +1,60 @@
-/*!
- * A top-level window, which contains a single TikzDocument.
- */
-
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include "tikzscene.h"
-#include "tikzview.h"
-#include "graph.h"
-#include "tikzdocument.h"
-#include "mainmenu.h"
-#include "toolpalette.h"
-#include "stylepalette.h"
-
-#include <QMainWindow>
-#include <QGraphicsView>
-
-namespace Ui {
-class MainWindow;
-}
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
-
- void open(QString fileName);
- int windowId() const;
- TikzView *tikzView() const;
- TikzScene *tikzScene() const;
- TikzDocument *tikzDocument() const;
- ToolPalette *toolPalette() const;
- StylePalette *stylePalette() const;
- QString tikzSource();
- void setSourceLine(int line);
-
-public slots:
- void on_tikzSource_textChanged();
- void updateFileName();
- void refreshTikz();
-protected:
- void closeEvent(QCloseEvent *event);
- void changeEvent(QEvent *event);
-
-private:
- TikzScene *_tikzScene;
- TikzDocument *_tikzDocument;
- MainMenu *_menu;
- ToolPalette *_toolPalette;
- StylePalette *_stylePalette;
- Ui::MainWindow *ui;
- int _windowId;
- static int _numWindows;
-};
-
-#endif // MAINWINDOW_H
+/*!
+ * A top-level window, which contains a single TikzDocument.
+ */
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "tikzscene.h"
+#include "tikzview.h"
+#include "graph.h"
+#include "tikzdocument.h"
+#include "mainmenu.h"
+#include "toolpalette.h"
+#include "stylepalette.h"
+
+#include <QMainWindow>
+#include <QGraphicsView>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ void open(QString fileName);
+ int windowId() const;
+ TikzView *tikzView() const;
+ TikzScene *tikzScene() const;
+ TikzDocument *tikzDocument() const;
+ ToolPalette *toolPalette() const;
+ StylePalette *stylePalette() const;
+ QString tikzSource();
+ void setSourceLine(int line);
+
+public slots:
+ void on_tikzSource_textChanged();
+ void updateFileName();
+ void refreshTikz();
+protected:
+ void closeEvent(QCloseEvent *event);
+ void changeEvent(QEvent *event);
+
+private:
+ TikzScene *_tikzScene;
+ TikzDocument *_tikzDocument;
+ MainMenu *_menu;
+ ToolPalette *_toolPalette;
+ StylePalette *_stylePalette;
+ Ui::MainWindow *ui;
+ int _windowId;
+ static int _numWindows;
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui
index 137d6cf..3df579f 100644
--- a/src/gui/mainwindow.ui
+++ b/src/gui/mainwindow.ui
@@ -1,205 +1,205 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>640</width>
- <height>580</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>TikZiT - untitled</string>
- </property>
- <widget class="QWidget" name="centralWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QSplitter" name="splitter">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <widget class="TikzView" name="tikzView"/>
- <widget class="QTextEdit" name="tikzSource">
- <property name="font">
- <font>
- <family>Courier New</family>
- <pointsize>10</pointsize>
- </font>
- </property>
- <property name="lineWrapMode">
- <enum>QTextEdit::NoWrap</enum>
- </property>
- <property name="html">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'.SF NS Text'; font-size:13pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="tabStopWidth">
- <number>20</number>
- </property>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QStatusBar" name="statusBar"/>
- <action name="actionNew">
- <property name="text">
- <string>New...</string>
- </property>
- </action>
- <action name="actionOpen">
- <property name="text">
- <string>Open...</string>
- </property>
- </action>
- <action name="actionClose">
- <property name="text">
- <string>Close</string>
- </property>
- </action>
- <action name="actionSave">
- <property name="text">
- <string>Save</string>
- </property>
- </action>
- <action name="actionSave_As">
- <property name="text">
- <string>Save As...</string>
- </property>
- </action>
- <action name="actionUndo">
- <property name="text">
- <string>Undo</string>
- </property>
- </action>
- <action name="actionRedo">
- <property name="text">
- <string>Redo</string>
- </property>
- </action>
- <action name="actionCut">
- <property name="text">
- <string>Cut</string>
- </property>
- </action>
- <action name="actionCopy">
- <property name="text">
- <string>Copy</string>
- </property>
- </action>
- <action name="actionPase">
- <property name="text">
- <string>Paste</string>
- </property>
- </action>
- <action name="actionDelete">
- <property name="text">
- <string>Delete</string>
- </property>
- </action>
- <action name="actionSelect_All">
- <property name="text">
- <string>Select All</string>
- </property>
- </action>
- <action name="actionDeselect_All">
- <property name="text">
- <string>Deselect All</string>
- </property>
- </action>
- <action name="actionParse">
- <property name="text">
- <string>Parse</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+T</string>
- </property>
- </action>
- <action name="actionZoom_In">
- <property name="text">
- <string>Zoom In</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+=</string>
- </property>
- </action>
- <action name="actionZoom_Out">
- <property name="text">
- <string>Zoom Out</string>
- </property>
- <property name="shortcut">
- <string>Ctrl+-</string>
- </property>
- </action>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <customwidgets>
- <customwidget>
- <class>TikzView</class>
- <extends>QGraphicsView</extends>
- <header>tikzview.h</header>
- <slots>
- <slot>zoomIn()</slot>
- <slot>zoomOut()</slot>
- </slots>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections>
- <connection>
- <sender>actionZoom_In</sender>
- <signal>triggered()</signal>
- <receiver>tikzView</receiver>
- <slot>zoomIn()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>-1</x>
- <y>-1</y>
- </hint>
- <hint type="destinationlabel">
- <x>237</x>
- <y>103</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>actionZoom_Out</sender>
- <signal>triggered()</signal>
- <receiver>tikzView</receiver>
- <slot>zoomOut()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>-1</x>
- <y>-1</y>
- </hint>
- <hint type="destinationlabel">
- <x>237</x>
- <y>103</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>640</width>
+ <height>580</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>TikZiT - untitled</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="TikzView" name="tikzView"/>
+ <widget class="QTextEdit" name="tikzSource">
+ <property name="font">
+ <font>
+ <family>Courier New</family>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property name="lineWrapMode">
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
+ <property name="html">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'.SF NS Text'; font-size:13pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="tabStopWidth">
+ <number>20</number>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ <action name="actionNew">
+ <property name="text">
+ <string>New...</string>
+ </property>
+ </action>
+ <action name="actionOpen">
+ <property name="text">
+ <string>Open...</string>
+ </property>
+ </action>
+ <action name="actionClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </action>
+ <action name="actionSave_As">
+ <property name="text">
+ <string>Save As...</string>
+ </property>
+ </action>
+ <action name="actionUndo">
+ <property name="text">
+ <string>Undo</string>
+ </property>
+ </action>
+ <action name="actionRedo">
+ <property name="text">
+ <string>Redo</string>
+ </property>
+ </action>
+ <action name="actionCut">
+ <property name="text">
+ <string>Cut</string>
+ </property>
+ </action>
+ <action name="actionCopy">
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ </action>
+ <action name="actionPase">
+ <property name="text">
+ <string>Paste</string>
+ </property>
+ </action>
+ <action name="actionDelete">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </action>
+ <action name="actionSelect_All">
+ <property name="text">
+ <string>Select All</string>
+ </property>
+ </action>
+ <action name="actionDeselect_All">
+ <property name="text">
+ <string>Deselect All</string>
+ </property>
+ </action>
+ <action name="actionParse">
+ <property name="text">
+ <string>Parse</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ <action name="actionZoom_In">
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+=</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out">
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+-</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>TikzView</class>
+ <extends>QGraphicsView</extends>
+ <header>tikzview.h</header>
+ <slots>
+ <slot>zoomIn()</slot>
+ <slot>zoomOut()</slot>
+ </slots>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>actionZoom_In</sender>
+ <signal>triggered()</signal>
+ <receiver>tikzView</receiver>
+ <slot>zoomIn()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>237</x>
+ <y>103</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>actionZoom_Out</sender>
+ <signal>triggered()</signal>
+ <receiver>tikzView</receiver>
+ <slot>zoomOut()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>237</x>
+ <y>103</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/gui/nodeitem.cpp b/src/gui/nodeitem.cpp
index b452848..d308dd2 100644
--- a/src/gui/nodeitem.cpp
+++ b/src/gui/nodeitem.cpp
@@ -1,159 +1,159 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzit.h"
-#include "nodeitem.h"
-#include "tikzscene.h"
-#include <cmath>
-
-#include <QPen>
-#include <QApplication>
-#include <QBrush>
-#include <QDebug>
-#include <QFont>
-#include <QFontMetrics>
-#include <QPainterPathStroker>
-
-NodeItem::NodeItem(Node *node)
-{
- _node = node;
- setFlag(QGraphicsItem::ItemIsSelectable);
- //setFlag(QGraphicsItem::ItemIsMovable);
- //setFlag(QGraphicsItem::ItemSendsGeometryChanges);
- readPos();
- updateBounds();
-}
-
-void NodeItem::readPos()
-{
- setPos(toScreen(_node->point()));
-}
-
-void NodeItem::writePos()
-{
- _node->setPoint(fromScreen(pos()));
-}
-
-QRectF NodeItem::labelRect() const {
- QString label = _node->label();
- //QFont f("Courier", 9);
- QFontMetrics fm(Tikzit::LABEL_FONT);
-
- QRectF rect = fm.boundingRect(label);
- //rect.adjust(-2,-2,2,2);
- rect.moveCenter(QPointF(0,0));
- return rect;
-}
-
-void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
-{
- if (_node->style()->isNone()) {
- QColor c(180,180,200);
- painter->setPen(QPen(c));
- painter->setBrush(QBrush(c));
- painter->drawEllipse(QPointF(0,0), 1,1);
-
- QPen pen(QColor(180,180,220));
- QVector<qreal> p;
- p << 1.0 << 2.0;
- pen.setDashPattern(p);
- pen.setWidthF(2.0f);
- painter->setPen(pen);
- painter->setBrush(Qt::NoBrush);
- painter->drawPath(shape());
- } else {
- QPen pen(_node->style()->strokeColor());
- pen.setWidth(_node->style()->strokeThickness());
- painter->setPen(pen);
- painter->setBrush(QBrush(_node->style()->fillColor()));
- painter->drawPath(shape());
- }
-
- if (_node->label() != "") {
- QRectF rect = labelRect();
- QPen pen(QColor(200,0,0,120));
- QVector<qreal> d;
- d << 2.0 << 2.0;
- pen.setDashPattern(d);
- painter->setPen(pen);
- painter->setBrush(QBrush(QColor(255,255,100,120)));
- painter->drawRect(rect);
-
- painter->setPen(QPen(Qt::black));
- painter->setFont(Tikzit::LABEL_FONT);
- painter->drawText(rect, Qt::AlignCenter, _node->label());
- }
-
- if (isSelected()) {
- QPainterPath sh = shape();
- QPainterPathStroker stroker;
- stroker.setWidth(4);
- QPainterPath outline = (stroker.createStroke(sh) + sh).simplified();
- painter->setPen(Qt::NoPen);
- painter->setBrush(QBrush(QColor(150,200,255,100)));
- painter->drawPath(outline);
- }
-
-}
-
-QPainterPath NodeItem::shape() const
-{
- QPainterPath path;
- path.addEllipse(QPointF(0,0), GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
- return path;
-}
-
-// TODO: nodeitem should sync boundingRect()-relevant stuff (label etc) explicitly,
-// to allow prepareGeometryChange()
-QRectF NodeItem::boundingRect() const
-{
- return _boundingRect;
-}
-
-void NodeItem::updateBounds()
-{
- prepareGeometryChange();
- QString label = _node->label();
- if (label != "") {
- QFontMetrics fm(Tikzit::LABEL_FONT);
- QRectF labelRect = fm.boundingRect(label);
- labelRect.moveCenter(QPointF(0, 0));
- _boundingRect = labelRect.united(shape().boundingRect()).adjusted(-4, -4, 4, 4);
- } else {
- _boundingRect = shape().boundingRect().adjusted(-4, -4, 4, 4);
- }
-}
-
-Node *NodeItem::node() const
-{
- return _node;
-}
-
-//QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value)
-//{
-// if (change == ItemPositionChange) {
-// QPointF newPos = value.toPointF();
-// int gridSize = GLOBAL_SCALE / 8;
-// QPointF gridPos(round(newPos.x()/gridSize)*gridSize, round(newPos.y()/gridSize)*gridSize);
-// _node->setPoint(fromScreen(gridPos));
-//
-// return gridPos;
-// } else {
-// return QGraphicsItem::itemChange(change, 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "nodeitem.h"
+#include "tikzscene.h"
+#include <cmath>
+
+#include <QPen>
+#include <QApplication>
+#include <QBrush>
+#include <QDebug>
+#include <QFont>
+#include <QFontMetrics>
+#include <QPainterPathStroker>
+
+NodeItem::NodeItem(Node *node)
+{
+ _node = node;
+ setFlag(QGraphicsItem::ItemIsSelectable);
+ //setFlag(QGraphicsItem::ItemIsMovable);
+ //setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ readPos();
+ updateBounds();
+}
+
+void NodeItem::readPos()
+{
+ setPos(toScreen(_node->point()));
+}
+
+void NodeItem::writePos()
+{
+ _node->setPoint(fromScreen(pos()));
+}
+
+QRectF NodeItem::labelRect() const {
+ QString label = _node->label();
+ //QFont f("Courier", 9);
+ QFontMetrics fm(Tikzit::LABEL_FONT);
+
+ QRectF rect = fm.boundingRect(label);
+ //rect.adjust(-2,-2,2,2);
+ rect.moveCenter(QPointF(0,0));
+ return rect;
+}
+
+void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ if (_node->style()->isNone()) {
+ QColor c(180,180,200);
+ painter->setPen(QPen(c));
+ painter->setBrush(QBrush(c));
+ painter->drawEllipse(QPointF(0,0), 1,1);
+
+ QPen pen(QColor(180,180,220));
+ QVector<qreal> p;
+ p << 1.0 << 2.0;
+ pen.setDashPattern(p);
+ pen.setWidthF(2.0f);
+ painter->setPen(pen);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(shape());
+ } else {
+ QPen pen(_node->style()->strokeColor());
+ pen.setWidth(_node->style()->strokeThickness());
+ painter->setPen(pen);
+ painter->setBrush(QBrush(_node->style()->fillColor()));
+ painter->drawPath(shape());
+ }
+
+ if (_node->label() != "") {
+ QRectF rect = labelRect();
+ QPen pen(QColor(200,0,0,120));
+ QVector<qreal> d;
+ d << 2.0 << 2.0;
+ pen.setDashPattern(d);
+ painter->setPen(pen);
+ painter->setBrush(QBrush(QColor(255,255,100,120)));
+ painter->drawRect(rect);
+
+ painter->setPen(QPen(Qt::black));
+ painter->setFont(Tikzit::LABEL_FONT);
+ painter->drawText(rect, Qt::AlignCenter, _node->label());
+ }
+
+ if (isSelected()) {
+ QPainterPath sh = shape();
+ QPainterPathStroker stroker;
+ stroker.setWidth(4);
+ QPainterPath outline = (stroker.createStroke(sh) + sh).simplified();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QBrush(QColor(150,200,255,100)));
+ painter->drawPath(outline);
+ }
+
+}
+
+QPainterPath NodeItem::shape() const
+{
+ QPainterPath path;
+ path.addEllipse(QPointF(0,0), GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ return path;
+}
+
+// TODO: nodeitem should sync boundingRect()-relevant stuff (label etc) explicitly,
+// to allow prepareGeometryChange()
+QRectF NodeItem::boundingRect() const
+{
+ return _boundingRect;
+}
+
+void NodeItem::updateBounds()
+{
+ prepareGeometryChange();
+ QString label = _node->label();
+ if (label != "") {
+ QFontMetrics fm(Tikzit::LABEL_FONT);
+ QRectF labelRect = fm.boundingRect(label);
+ labelRect.moveCenter(QPointF(0, 0));
+ _boundingRect = labelRect.united(shape().boundingRect()).adjusted(-4, -4, 4, 4);
+ } else {
+ _boundingRect = shape().boundingRect().adjusted(-4, -4, 4, 4);
+ }
+}
+
+Node *NodeItem::node() const
+{
+ return _node;
+}
+
+//QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value)
+//{
+// if (change == ItemPositionChange) {
+// QPointF newPos = value.toPointF();
+// int gridSize = GLOBAL_SCALE / 8;
+// QPointF gridPos(round(newPos.x()/gridSize)*gridSize, round(newPos.y()/gridSize)*gridSize);
+// _node->setPoint(fromScreen(gridPos));
+//
+// return gridPos;
+// } else {
+// return QGraphicsItem::itemChange(change, value);
+// }
+//}
diff --git a/src/gui/nodeitem.h b/src/gui/nodeitem.h
index 678a7e8..efd32f1 100644
--- a/src/gui/nodeitem.h
+++ b/src/gui/nodeitem.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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * A QGraphicsItem that handles drawing a single node.
- */
-
-#ifndef NODEITEM_H
-#define NODEITEM_H
-
-#include "node.h"
-
-#include <QObject>
-#include <QGraphicsItem>
-#include <QPainterPath>
-#include <QRectF>
-
-class NodeItem : public QGraphicsItem
-{
-public:
- NodeItem(Node *node);
- void readPos();
- void writePos();
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
- QPainterPath shape() const override;
- QRectF boundingRect() const override;
- void updateBounds();
- Node *node() const;
-
-private:
- Node *_node;
- QRectF labelRect() const;
- QRectF _boundingRect;
-};
-
-#endif // NODEITEM_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A QGraphicsItem that handles drawing a single node.
+ */
+
+#ifndef NODEITEM_H
+#define NODEITEM_H
+
+#include "node.h"
+
+#include <QObject>
+#include <QGraphicsItem>
+#include <QPainterPath>
+#include <QRectF>
+
+class NodeItem : public QGraphicsItem
+{
+public:
+ NodeItem(Node *node);
+ void readPos();
+ void writePos();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
+ QPainterPath shape() const override;
+ QRectF boundingRect() const override;
+ void updateBounds();
+ Node *node() const;
+
+private:
+ Node *_node;
+ QRectF labelRect() const;
+ QRectF _boundingRect;
+};
+
+#endif // NODEITEM_H
diff --git a/src/gui/propertypalette.cpp b/src/gui/propertypalette.cpp
index c27b8b2..e2b8b8d 100644
--- a/src/gui/propertypalette.cpp
+++ b/src/gui/propertypalette.cpp
@@ -1,61 +1,61 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "propertypalette.h"
-#include "graphelementdata.h"
-#include "ui_propertypalette.h"
-
-#include <QModelIndex>
-#include <QDebug>
-#include <QCloseEvent>
-#include <QSettings>
-
-PropertyPalette::PropertyPalette(QWidget *parent) :
- QDockWidget(parent),
- ui(new Ui::PropertyPalette)
-{
- setWindowFlags(Qt::Window
- | Qt::CustomizeWindowHint
- | Qt::WindowTitleHint);
- //setFocusPolicy(Qt::NoFocus);
- ui->setupUi(this);
- GraphElementData *d = new GraphElementData();
- d->setProperty("key 1", "value 1");
- d->setAtom("atom 1");
- d->setProperty("key 2", "value 2");
-
- //QModelIndex i = d->index(0,0);
- //ui->treeView->setModel(d);
-
- QSettings settings("tikzit", "tikzit");
- QVariant geom = settings.value("property-palette-geometry");
- if (geom != QVariant()) {
- restoreGeometry(geom.toByteArray());
- }
-}
-
-PropertyPalette::~PropertyPalette()
-{
- delete ui;
-}
-
-void PropertyPalette::closeEvent(QCloseEvent *event) {
- QSettings settings("tikzit", "tikzit");
- settings.setValue("property-palette-geometry", saveGeometry());
- QDockWidget::closeEvent(event);
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "propertypalette.h"
+#include "graphelementdata.h"
+#include "ui_propertypalette.h"
+
+#include <QModelIndex>
+#include <QDebug>
+#include <QCloseEvent>
+#include <QSettings>
+
+PropertyPalette::PropertyPalette(QWidget *parent) :
+ QDockWidget(parent),
+ ui(new Ui::PropertyPalette)
+{
+ setWindowFlags(Qt::Window
+ | Qt::CustomizeWindowHint
+ | Qt::WindowTitleHint);
+ //setFocusPolicy(Qt::NoFocus);
+ ui->setupUi(this);
+ GraphElementData *d = new GraphElementData();
+ d->setProperty("key 1", "value 1");
+ d->setAtom("atom 1");
+ d->setProperty("key 2", "value 2");
+
+ //QModelIndex i = d->index(0,0);
+ //ui->treeView->setModel(d);
+
+ QSettings settings("tikzit", "tikzit");
+ QVariant geom = settings.value("property-palette-geometry");
+ if (geom != QVariant()) {
+ restoreGeometry(geom.toByteArray());
+ }
+}
+
+PropertyPalette::~PropertyPalette()
+{
+ delete ui;
+}
+
+void PropertyPalette::closeEvent(QCloseEvent *event) {
+ QSettings settings("tikzit", "tikzit");
+ settings.setValue("property-palette-geometry", saveGeometry());
+ QDockWidget::closeEvent(event);
+}
diff --git a/src/gui/propertypalette.h b/src/gui/propertypalette.h
index 29fb0af..1241123 100644
--- a/src/gui/propertypalette.h
+++ b/src/gui/propertypalette.h
@@ -1,46 +1,46 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * Enables the user to edit properties of the graph, as well as the selected node/edge.
- */
-
-#ifndef PROPERTYPALETTE_H
-#define PROPERTYPALETTE_H
-
-#include <QDockWidget>
-
-namespace Ui {
-class PropertyPalette;
-}
-
-class PropertyPalette : public QDockWidget
-{
- Q_OBJECT
-
-public:
- explicit PropertyPalette(QWidget *parent = 0);
- ~PropertyPalette();
-
-protected:
- void closeEvent(QCloseEvent *event);
-private:
- Ui::PropertyPalette *ui;
-};
-
-#endif // PROPERTYPALETTE_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Enables the user to edit properties of the graph, as well as the selected node/edge.
+ */
+
+#ifndef PROPERTYPALETTE_H
+#define PROPERTYPALETTE_H
+
+#include <QDockWidget>
+
+namespace Ui {
+class PropertyPalette;
+}
+
+class PropertyPalette : public QDockWidget
+{
+ Q_OBJECT
+
+public:
+ explicit PropertyPalette(QWidget *parent = 0);
+ ~PropertyPalette();
+
+protected:
+ void closeEvent(QCloseEvent *event);
+private:
+ Ui::PropertyPalette *ui;
+};
+
+#endif // PROPERTYPALETTE_H
diff --git a/src/gui/propertypalette.ui b/src/gui/propertypalette.ui
index a8ba5d2..f5ccebd 100644
--- a/src/gui/propertypalette.ui
+++ b/src/gui/propertypalette.ui
@@ -1,33 +1,33 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>PropertyPalette</class>
- <widget class="QDockWidget" name="PropertyPalette">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>194</width>
- <height>341</height>
- </rect>
- </property>
- <property name="floating">
- <bool>false</bool>
- </property>
- <property name="windowTitle">
- <string>Properties</string>
- </property>
- <widget class="QWidget" name="dockWidgetContents">
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QTreeView" name="treeView">
- <property name="indentation">
- <number>0</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PropertyPalette</class>
+ <widget class="QDockWidget" name="PropertyPalette">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>194</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="floating">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string>Properties</string>
+ </property>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/stylepalette.cpp b/src/gui/stylepalette.cpp
index e3fea0b..42d440e 100644
--- a/src/gui/stylepalette.cpp
+++ b/src/gui/stylepalette.cpp
@@ -1,179 +1,179 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "stylepalette.h"
-#include "ui_stylepalette.h"
-#include "tikzit.h"
-
-#include <QDebug>
-#include <QIcon>
-#include <QSize>
-#include <QSettings>
-#include <QPainter>
-#include <QPixmap>
-#include <QPainterPath>
-
-StylePalette::StylePalette(QWidget *parent) :
- QDockWidget(parent),
- ui(new Ui::StylePalette)
-{
- ui->setupUi(this);
-
-// QSettings settings("tikzit", "tikzit");
-// QVariant geom = settings.value("style-palette-geometry");
-// if (geom != QVariant()) {
-// restoreGeometry(geom.toByteArray());
-// }
-
- _nodeModel = new QStandardItemModel(this);
- _edgeModel = new QStandardItemModel(this);
-
- ui->styleListView->setModel(_nodeModel);
- ui->styleListView->setViewMode(QListView::IconMode);
- ui->styleListView->setMovement(QListView::Static);
- ui->styleListView->setGridSize(QSize(48,48));
-
-
- ui->edgeStyleListView->setModel(_edgeModel);
- ui->edgeStyleListView->setViewMode(QListView::IconMode);
- ui->edgeStyleListView->setMovement(QListView::Static);
- ui->edgeStyleListView->setGridSize(QSize(48,48));
-
- reloadStyles();
-
- connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( nodeStyleDoubleClicked(const QModelIndex&)) );
-}
-
-StylePalette::~StylePalette()
-{
- delete ui;
-}
-
-void StylePalette::reloadStyles()
-{
- _nodeModel->clear();
- _edgeModel->clear();
- QString f = tikzit->styleFile();
- ui->styleFile->setText(f);
-
- QStandardItem *it;
-
- it = new QStandardItem(noneStyle->icon(), noneStyle->name());
- it->setEditable(false);
- it->setData(noneStyle->name());
- _nodeModel->appendRow(it);
-
- foreach(NodeStyle *ns, tikzit->styles()->nodeStyles()) {
- it = new QStandardItem(ns->icon(), ns->name());
- it->setEditable(false);
- it->setData(ns->name());
- _nodeModel->appendRow(it);
- }
-
- it = new QStandardItem(noneEdgeStyle->icon(), noneEdgeStyle->name());
- it->setEditable(false);
- it->setData(noneEdgeStyle->name());
- _edgeModel->appendRow(it);
-
- foreach(EdgeStyle *es, tikzit->styles()->edgeStyles()) {
- it = new QStandardItem(es->icon(), es->name());
- it->setEditable(false);
- it->setData(es->name());
- _edgeModel->appendRow(it);
- }
-}
-
-void StylePalette::changeNodeStyle(int increment)
-{
- QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
- int row = 0;
- if (!i.isEmpty()) {
- int row = (i[0].row()+increment)%_nodeModel->rowCount();
- if (row < 0) row += _nodeModel->rowCount();
- }
-
- QModelIndex i1 = ui->styleListView->rootIndex().child(row, 0);
- ui->styleListView->selectionModel()->select(i1, QItemSelectionModel::ClearAndSelect);
- ui->styleListView->scrollTo(i1);
-}
-
-void StylePalette::nextNodeStyle()
-{
- changeNodeStyle(1);
-}
-
-void StylePalette::previousNodeStyle()
-{
- changeNodeStyle(-1);
-}
-
-QString StylePalette::activeNodeStyleName()
-{
- const QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
-
- if (i.isEmpty()) {
- return "none";
- } else {
- return i[0].data().toString();
- }
-}
-
-QString StylePalette::activeEdgeStyleName()
-{
- const QModelIndexList i = ui->edgeStyleListView->selectionModel()->selectedIndexes();
-
- if (i.isEmpty()) {
- return "none";
- } else {
- return i[0].data().toString();
- }
-}
-
-void StylePalette::nodeStyleDoubleClicked(const QModelIndex &index)
-{
- tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
-}
-
-void StylePalette::edgeStyleDoubleClicked(const QModelIndex &index)
-{
- // TODO
-}
-
-void StylePalette::on_buttonOpenTikzstyles_clicked()
-{
- tikzit->openTikzStyles();
-}
-
-void StylePalette::on_buttonRefreshTikzstyles_clicked()
-{
- QSettings settings("tikzit", "tikzit");
- QString path = settings.value("previous-tikzstyles-file").toString();
- if (!path.isEmpty()) tikzit->loadStyles(path);
-}
-
-//void StylePalette::on_buttonApplyNodeStyle_clicked()
-//{
-// if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
-//}
-
-void StylePalette::closeEvent(QCloseEvent *event)
-{
- QSettings settings("tikzit", "tikzit");
- settings.setValue("style-palette-geometry", saveGeometry());
- QDockWidget::closeEvent(event);
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "stylepalette.h"
+#include "ui_stylepalette.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QIcon>
+#include <QSize>
+#include <QSettings>
+#include <QPainter>
+#include <QPixmap>
+#include <QPainterPath>
+
+StylePalette::StylePalette(QWidget *parent) :
+ QDockWidget(parent),
+ ui(new Ui::StylePalette)
+{
+ ui->setupUi(this);
+
+// QSettings settings("tikzit", "tikzit");
+// QVariant geom = settings.value("style-palette-geometry");
+// if (geom != QVariant()) {
+// restoreGeometry(geom.toByteArray());
+// }
+
+ _nodeModel = new QStandardItemModel(this);
+ _edgeModel = new QStandardItemModel(this);
+
+ ui->styleListView->setModel(_nodeModel);
+ ui->styleListView->setViewMode(QListView::IconMode);
+ ui->styleListView->setMovement(QListView::Static);
+ ui->styleListView->setGridSize(QSize(48,48));
+
+
+ ui->edgeStyleListView->setModel(_edgeModel);
+ ui->edgeStyleListView->setViewMode(QListView::IconMode);
+ ui->edgeStyleListView->setMovement(QListView::Static);
+ ui->edgeStyleListView->setGridSize(QSize(48,48));
+
+ reloadStyles();
+
+ connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( nodeStyleDoubleClicked(const QModelIndex&)) );
+}
+
+StylePalette::~StylePalette()
+{
+ delete ui;
+}
+
+void StylePalette::reloadStyles()
+{
+ _nodeModel->clear();
+ _edgeModel->clear();
+ QString f = tikzit->styleFile();
+ ui->styleFile->setText(f);
+
+ QStandardItem *it;
+
+ it = new QStandardItem(noneStyle->icon(), noneStyle->name());
+ it->setEditable(false);
+ it->setData(noneStyle->name());
+ _nodeModel->appendRow(it);
+
+ foreach(NodeStyle *ns, tikzit->styles()->nodeStyles()) {
+ it = new QStandardItem(ns->icon(), ns->name());
+ it->setEditable(false);
+ it->setData(ns->name());
+ _nodeModel->appendRow(it);
+ }
+
+ it = new QStandardItem(noneEdgeStyle->icon(), noneEdgeStyle->name());
+ it->setEditable(false);
+ it->setData(noneEdgeStyle->name());
+ _edgeModel->appendRow(it);
+
+ foreach(EdgeStyle *es, tikzit->styles()->edgeStyles()) {
+ it = new QStandardItem(es->icon(), es->name());
+ it->setEditable(false);
+ it->setData(es->name());
+ _edgeModel->appendRow(it);
+ }
+}
+
+void StylePalette::changeNodeStyle(int increment)
+{
+ QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
+ int row = 0;
+ if (!i.isEmpty()) {
+ int row = (i[0].row()+increment)%_nodeModel->rowCount();
+ if (row < 0) row += _nodeModel->rowCount();
+ }
+
+ QModelIndex i1 = ui->styleListView->rootIndex().child(row, 0);
+ ui->styleListView->selectionModel()->select(i1, QItemSelectionModel::ClearAndSelect);
+ ui->styleListView->scrollTo(i1);
+}
+
+void StylePalette::nextNodeStyle()
+{
+ changeNodeStyle(1);
+}
+
+void StylePalette::previousNodeStyle()
+{
+ changeNodeStyle(-1);
+}
+
+QString StylePalette::activeNodeStyleName()
+{
+ const QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
+
+ if (i.isEmpty()) {
+ return "none";
+ } else {
+ return i[0].data().toString();
+ }
+}
+
+QString StylePalette::activeEdgeStyleName()
+{
+ const QModelIndexList i = ui->edgeStyleListView->selectionModel()->selectedIndexes();
+
+ if (i.isEmpty()) {
+ return "none";
+ } else {
+ return i[0].data().toString();
+ }
+}
+
+void StylePalette::nodeStyleDoubleClicked(const QModelIndex &index)
+{
+ tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
+}
+
+void StylePalette::edgeStyleDoubleClicked(const QModelIndex &index)
+{
+ // TODO
+}
+
+void StylePalette::on_buttonOpenTikzstyles_clicked()
+{
+ tikzit->openTikzStyles();
+}
+
+void StylePalette::on_buttonRefreshTikzstyles_clicked()
+{
+ QSettings settings("tikzit", "tikzit");
+ QString path = settings.value("previous-tikzstyles-file").toString();
+ if (!path.isEmpty()) tikzit->loadStyles(path);
+}
+
+//void StylePalette::on_buttonApplyNodeStyle_clicked()
+//{
+// if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
+//}
+
+void StylePalette::closeEvent(QCloseEvent *event)
+{
+ QSettings settings("tikzit", "tikzit");
+ settings.setValue("style-palette-geometry", saveGeometry());
+ QDockWidget::closeEvent(event);
+}
diff --git a/src/gui/stylepalette.h b/src/gui/stylepalette.h
index 45dc8da..01daa90 100644
--- a/src/gui/stylepalette.h
+++ b/src/gui/stylepalette.h
@@ -1,61 +1,61 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#ifndef STYLEPALETTE_H
-#define STYLEPALETTE_H
-
-#include <QDockWidget>
-#include <QStandardItemModel>
-
-namespace Ui {
-class StylePalette;
-}
-
-class StylePalette : public QDockWidget
-{
- Q_OBJECT
-
-public:
- explicit StylePalette(QWidget *parent = 0);
- ~StylePalette();
- void reloadStyles();
- void nextNodeStyle();
- void previousNodeStyle();
- QString activeNodeStyleName();
- QString activeEdgeStyleName();
-
-
-public slots:
- void nodeStyleDoubleClicked(const QModelIndex &index);
- void edgeStyleDoubleClicked(const QModelIndex &index);
- void on_buttonOpenTikzstyles_clicked();
- void on_buttonRefreshTikzstyles_clicked();
- //void on_buttonApplyNodeStyle_clicked();
-
-private:
- void changeNodeStyle(int increment);
-
- Ui::StylePalette *ui;
- QStandardItemModel *_nodeModel;
- QStandardItemModel *_edgeModel;
-
-protected:
- void closeEvent(QCloseEvent *event) override;
-};
-
-#endif // STYLEPALETTE_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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef STYLEPALETTE_H
+#define STYLEPALETTE_H
+
+#include <QDockWidget>
+#include <QStandardItemModel>
+
+namespace Ui {
+class StylePalette;
+}
+
+class StylePalette : public QDockWidget
+{
+ Q_OBJECT
+
+public:
+ explicit StylePalette(QWidget *parent = 0);
+ ~StylePalette();
+ void reloadStyles();
+ void nextNodeStyle();
+ void previousNodeStyle();
+ QString activeNodeStyleName();
+ QString activeEdgeStyleName();
+
+
+public slots:
+ void nodeStyleDoubleClicked(const QModelIndex &index);
+ void edgeStyleDoubleClicked(const QModelIndex &index);
+ void on_buttonOpenTikzstyles_clicked();
+ void on_buttonRefreshTikzstyles_clicked();
+ //void on_buttonApplyNodeStyle_clicked();
+
+private:
+ void changeNodeStyle(int increment);
+
+ Ui::StylePalette *ui;
+ QStandardItemModel *_nodeModel;
+ QStandardItemModel *_edgeModel;
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+};
+
+#endif // STYLEPALETTE_H
diff --git a/src/gui/stylepalette.ui b/src/gui/stylepalette.ui
index 4f5b58d..be8263e 100644
--- a/src/gui/stylepalette.ui
+++ b/src/gui/stylepalette.ui
@@ -1,120 +1,120 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>StylePalette</class>
- <widget class="QDockWidget" name="StylePalette">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>88</width>
- <height>518</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>88</width>
- <height>191</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>88</width>
- <height>524287</height>
- </size>
- </property>
- <property name="floating">
- <bool>false</bool>
- </property>
- <property name="windowTitle">
- <string/>
- </property>
- <widget class="QWidget" name="dockWidgetContents">
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>2</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QToolButton" name="buttonOpenTikzstyles">
- <property name="toolTip">
- <string>New Project</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../../tikzit.qrc">
- <normaloff>:/images/document-open.svg</normaloff>:/images/document-open.svg</iconset>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="buttonRefreshTikzstyles">
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../../tikzit.qrc">
- <normaloff>:/images/refresh.svg</normaloff>:/images/refresh.svg</iconset>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QLabel" name="styleFile">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>[default]</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="styleListView">
- <property name="font">
- <font>
- <pointsize>8</pointsize>
- <italic>true</italic>
- </font>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="edgeStyleListView"/>
- </item>
- </layout>
- </widget>
- </widget>
- <resources>
- <include location="../../tikzit.qrc"/>
- </resources>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StylePalette</class>
+ <widget class="QDockWidget" name="StylePalette">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>88</width>
+ <height>518</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>88</width>
+ <height>191</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>88</width>
+ <height>524287</height>
+ </size>
+ </property>
+ <property name="floating">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonOpenTikzstyles">
+ <property name="toolTip">
+ <string>New Project</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../tikzit.qrc">
+ <normaloff>:/images/document-open.svg</normaloff>:/images/document-open.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonRefreshTikzstyles">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../tikzit.qrc">
+ <normaloff>:/images/refresh.svg</normaloff>:/images/refresh.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="styleFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>[default]</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="styleListView">
+ <property name="font">
+ <font>
+ <pointsize>8</pointsize>
+ <italic>true</italic>
+ </font>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="edgeStyleListView"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../../tikzit.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp
index 47464fe..6f2994b 100644
--- a/src/gui/tikzscene.cpp
+++ b/src/gui/tikzscene.cpp
@@ -1,780 +1,780 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzit.h"
-#include "util.h"
-#include "tikzscene.h"
-#include "undocommands.h"
-#include "tikzassembler.h"
-
-#include <QPen>
-#include <QBrush>
-#include <QDebug>
-#include <QClipboard>
-#include <QInputDialog>
-#include <cmath>
-
-
-TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools,
- StylePalette *styles, QObject *parent) :
- QGraphicsScene(parent), _tikzDocument(tikzDocument), _tools(tools), _styles(styles)
-{
- _modifyEdgeItem = 0;
- _edgeStartNodeItem = 0;
- _drawEdgeItem = new QGraphicsLineItem();
- _rubberBandItem = new QGraphicsRectItem();
- _enabled = true;
- //setSceneRect(-310,-230,620,450);
- setSceneRect(-1000,-1000,2000,2000);
-
- QPen pen;
- pen.setColor(QColor::fromRgbF(0.5f, 0.0f, 0.5f));
- //pen.setWidth(3.0f);
- pen.setCosmetic(true);
- _drawEdgeItem->setPen(pen);
- _drawEdgeItem->setLine(0,0,0,0);
- _drawEdgeItem->setVisible(false);
- addItem(_drawEdgeItem);
-
- pen.setColor(QColor::fromRgbF(0.6f, 0.6f, 0.8f));
- //pen.setWidth(3.0f);
- //QVector<qreal> dash;
- //dash << 4.0 << 4.0;
- pen.setStyle(Qt::DashLine);
- //pen.setDashPattern(dash);
- _rubberBandItem->setPen(pen);
-
- QBrush brush(QColor::fromRgbF(0.6,0.6,0.8,0.2));
- _rubberBandItem->setBrush(brush);
-
- _rubberBandItem->setVisible(false);
- addItem(_rubberBandItem);
-}
-
-TikzScene::~TikzScene() {
-}
-
-Graph *TikzScene::graph()
-{
- return _tikzDocument->graph();
-}
-
-void TikzScene::graphReplaced()
-{
-
- foreach (NodeItem *ni, _nodeItems) {
- removeItem(ni);
- delete ni;
- }
- _nodeItems.clear();
-
- foreach (EdgeItem *ei, _edgeItems) {
- removeItem(ei);
- delete ei;
- }
- _edgeItems.clear();
-
- foreach (Edge *e, graph()->edges()) {
- e->attachStyle();
- EdgeItem *ei = new EdgeItem(e);
- _edgeItems.insert(e, ei);
- addItem(ei);
- }
-
- foreach (Node *n, graph()->nodes()) {
- n->attachStyle();
- NodeItem *ni = new NodeItem(n);
- _nodeItems.insert(n, ni);
- addItem(ni);
- }
-}
-
-void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- if (!_enabled) return;
-
- // current mouse position, in scene coordinates
- _mouseDownPos = event->scenePos();
-
- _draggingNodes = false;
-
- // disable rubber band drag, which will clear the selection. Only re-enable it
- // for the SELECT tool, and when no control point has been clicked.
- //views()[0]->setDragMode(QGraphicsView::NoDrag);
-
- // radius of a control point for bezier edges, in scene coordinates
- qreal cpR = GLOBAL_SCALEF * (0.1);
- qreal cpR2 = cpR * cpR;
-
- switch (_tools->currentTool()) {
- case ToolPalette::SELECT:
- // check if we grabbed a control point of an edge
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
- qreal dx, dy;
-
- dx = ei->cp1Item()->pos().x() - _mouseDownPos.x();
- dy = ei->cp1Item()->pos().y() - _mouseDownPos.y();
-
- if (dx*dx + dy*dy <= cpR2) {
- _modifyEdgeItem = ei;
- _firstControlPoint = true;
- break;
- }
-
- dx = ei->cp2Item()->pos().x() - _mouseDownPos.x();
- dy = ei->cp2Item()->pos().y() - _mouseDownPos.y();
-
- if (dx*dx + dy*dy <= cpR2) {
- _modifyEdgeItem = ei;
- _firstControlPoint = false;
- break;
- }
- }
- }
-
- if (_modifyEdgeItem != 0) {
- // store for undo purposes
- Edge *e = _modifyEdgeItem->edge();
- _oldBend = e->bend();
- _oldInAngle = e->inAngle();
- _oldOutAngle = e->outAngle();
- _oldWeight = e->weight();
- } else {
- // since we are not dragging a control point, process the click normally
- //views()[0]->setDragMode(QGraphicsView::RubberBandDrag);
- QGraphicsScene::mousePressEvent(event);
-
- if (items(_mouseDownPos).isEmpty()) {
- _rubberBandItem->setRect(QRectF(_mouseDownPos,_mouseDownPos));
- _rubberBandItem->setVisible(true);
- qDebug() << "starting rubber band drag";
- }
-
-// foreach (QGraphicsItem *gi, items()) {
-// if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
-// //qDebug() << "got an edge item: " << ei;
-// ei->setFlag(QGraphicsItem::ItemIsSelectable, false);
-// //ei->setSelected(true);
-// }
-// }
-
- // save current node positions for undo support
- _oldNodePositions.clear();
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- _oldNodePositions.insert(ni->node(), ni->node()->point());
- }
- }
-
- auto its = items(_mouseDownPos);
- if (!its.isEmpty() && dynamic_cast<NodeItem*>(its[0]))
- _draggingNodes = true;
- }
-
- break;
- case ToolPalette::VERTEX:
- break;
- case ToolPalette::EDGE:
- foreach (QGraphicsItem *gi, items(_mouseDownPos)) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
- _edgeStartNodeItem = ni;
- _edgeEndNodeItem = ni;
- QLineF line(toScreen(ni->node()->point()), _mouseDownPos);
- _drawEdgeItem->setLine(line);
- _drawEdgeItem->setVisible(true);
- break;
- }
- }
- break;
- case ToolPalette::CROP:
- break;
- }
-}
-
-void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- if (!_enabled) return;
-
- // current mouse position, in scene coordinates
- QPointF mousePos = event->scenePos();
- //QRectF rb = views()[0]->rubberBandRect();
- //invalidate(-800,-800,1600,1600);
- //invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
-
- switch (_tools->currentTool()) {
- case ToolPalette::SELECT:
- if (_modifyEdgeItem != 0) {
- Edge *e = _modifyEdgeItem->edge();
-
- // dragging a control point
- QPointF src = toScreen(e->source()->point());
- QPointF targ = toScreen(e->target()->point());
- float dx1 = targ.x() - src.x();
- float dy1 = targ.y() - src.y();
- float dx2, dy2;
- if (_firstControlPoint) {
- dx2 = mousePos.x() - src.x();
- dy2 = mousePos.y() - src.y();
- } else {
- dx2 = mousePos.x() - targ.x();
- dy2 = mousePos.y() - targ.y();
- }
-
- float baseDist = sqrt(dx1*dx1 + dy1*dy1);
- float handleDist = sqrt(dx2*dx2 + dy2*dy2);
- float wcoarseness = 0.1f;
-
- if (!e->isSelfLoop()) {
- if (baseDist != 0) {
- e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist));
- } else {
- e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF));
- }
- }
-
- float control_angle = atan2(-dy2, dx2);
-
- int bcoarseness = 15;
-
- if(e->basicBendMode()) {
- float bnd;
- float base_angle = atan2(-dy1, dx1);
- if (_firstControlPoint) {
- bnd = base_angle - control_angle;
- } else {
- bnd = control_angle - base_angle + M_PI;
- if (bnd > M_PI) bnd -= 2*M_PI;
- }
-
- e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness);
-
- } else {
- int bnd = round(control_angle * (180.0f / M_PI) *
- (1.0f / (float)bcoarseness)) *
- bcoarseness;
- if (_firstControlPoint) {
- // TODO: enable moving both control points
-// if ([theEvent modifierFlags] & NSAlternateKeyMask) {
-// if ([modifyEdge isSelfLoop]) {
-// [modifyEdge setInAngle:[modifyEdge inAngle] +
-// (bnd - [modifyEdge outAngle])];
-// } else {
-// [modifyEdge setInAngle:[modifyEdge inAngle] -
-// (bnd - [modifyEdge outAngle])];
-// }
-// }
-
- e->setOutAngle(bnd);
- } else {
-// if (theEvent.modifierFlags & NSAlternateKeyMask) {
-// if ([modifyEdge isSelfLoop]) {
-// [modifyEdge setOutAngle:[modifyEdge outAngle] +
-// (bnd - [modifyEdge inAngle])];
-// } else {
-// [modifyEdge setOutAngle:[modifyEdge outAngle] -
-// (bnd - [modifyEdge inAngle])];
-// }
-// }
-
- e->setInAngle(bnd);
- }
- }
-
- _modifyEdgeItem->readPos();
-
- } else if (_draggingNodes) { // nodes being dragged
- QGraphicsScene::mouseMoveEvent(event);
-
- // apply the same offset to all nodes, otherwise we get odd rounding behaviour with
- // multiple selection.
- QPointF shift = mousePos - _mouseDownPos;
- shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
-
- foreach (Node *n, _oldNodePositions.keys()) {
- NodeItem *ni = _nodeItems[n];
-
- // in (rare) cases, the graph can change while we are dragging
- if (ni != 0) {
- ni->setPos(toScreen(_oldNodePositions[n]) + shift);
- ni->writePos();
- }
- }
-
- refreshAdjacentEdges(_oldNodePositions.keys());
- } else {
- // otherwise, process mouse move normally
- QGraphicsScene::mouseMoveEvent(event);
-
- if (_rubberBandItem->isVisible()) {
- qreal left = std::min(_mouseDownPos.x(), mousePos.x());
- qreal top = std::min(_mouseDownPos.y(), mousePos.y());
- qreal w = std::abs(_mouseDownPos.x() - mousePos.x());
- qreal h = std::abs(_mouseDownPos.y() - mousePos.y());
-
- _rubberBandItem->setRect(QRectF(left, top, w, h));
- }
- }
-
- break;
- case ToolPalette::VERTEX:
- break;
- case ToolPalette::EDGE:
- if (_drawEdgeItem->isVisible()) {
- _edgeEndNodeItem = 0;
- foreach (QGraphicsItem *gi, items(mousePos)) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
- _edgeEndNodeItem = ni;
- break;
- }
- }
- QPointF p1 = _drawEdgeItem->line().p1();
- QPointF p2 = (_edgeEndNodeItem != 0) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos;
- QLineF line(p1, p2);
-
- _drawEdgeItem->setLine(line);
- }
- break;
- case ToolPalette::CROP:
- break;
- }
-}
-
-void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- if (!_enabled) return;
-
- // current mouse position, in scene coordinates
- QPointF mousePos = event->scenePos();
-
- switch (_tools->currentTool()) {
- case ToolPalette::SELECT:
- if (_modifyEdgeItem != 0) {
- // finished dragging a control point
- Edge *e = _modifyEdgeItem->edge();
-
- if (_oldWeight != e->weight() ||
- _oldBend != e->bend() ||
- _oldInAngle != e->inAngle() ||
- _oldOutAngle != e->outAngle())
- {
- EdgeBendCommand *cmd = new EdgeBendCommand(this, e, _oldWeight, _oldBend, _oldInAngle, _oldOutAngle);
- _tikzDocument->undoStack()->push(cmd);
- }
-
- _modifyEdgeItem = 0;
- } else {
- // otherwise, process mouse move normally
- QGraphicsScene::mouseReleaseEvent(event);
-
- if (_rubberBandItem->isVisible()) {
- QPainterPath sel;
- sel.addRect(_rubberBandItem->rect());
- foreach (QGraphicsItem *gi, items()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- if (sel.contains(toScreen(ni->node()->point()))) ni->setSelected(true);
- }
- }
- //setSelectionArea(sel);
- }
-
- _rubberBandItem->setVisible(false);
-
- if (!_oldNodePositions.empty()) {
- QPointF shift = mousePos - _mouseDownPos;
- shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
-
- if (shift.x() != 0 || shift.y() != 0) {
- QMap<Node*,QPointF> newNodePositions;
-
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- ni->writePos();
- newNodePositions.insert(ni->node(), ni->node()->point());
- }
- }
-
- //qDebug() << _oldNodePositions;
- //qDebug() << newNodePositions;
-
- _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions));
- }
-
- _oldNodePositions.clear();
- }
- }
-
- break;
- case ToolPalette::VERTEX:
- {
- QPointF gridPos(round(mousePos.x()/GRID_SEP)*GRID_SEP, round(mousePos.y()/GRID_SEP)*GRID_SEP);
- Node *n = new Node(_tikzDocument);
- n->setName(graph()->freshNodeName());
- n->setPoint(fromScreen(gridPos));
- n->setStyleName(_styles->activeNodeStyleName());
-
- QRectF grow(gridPos.x() - GLOBAL_SCALEF, gridPos.y() - GLOBAL_SCALEF, 2 * GLOBAL_SCALEF, 2 * GLOBAL_SCALEF);
- QRectF newBounds = sceneRect().united(grow);
- //qDebug() << grow;
- //qDebug() << newBounds;
-
- AddNodeCommand *cmd = new AddNodeCommand(this, n, newBounds);
- _tikzDocument->undoStack()->push(cmd);
- }
- break;
- case ToolPalette::EDGE:
- if (_edgeStartNodeItem != 0 && _edgeEndNodeItem != 0) {
- Edge *e = new Edge(_edgeStartNodeItem->node(), _edgeEndNodeItem->node(), _tikzDocument);
- e->setStyleName(_styles->activeEdgeStyleName());
- AddEdgeCommand *cmd = new AddEdgeCommand(this, e);
- _tikzDocument->undoStack()->push(cmd);
- }
- _edgeStartNodeItem = 0;
- _edgeEndNodeItem = 0;
- _drawEdgeItem->setVisible(false);
- break;
- case ToolPalette::CROP:
- break;
- }
-
- // clear artefacts from rubber band selection
- invalidate(QRect(), QGraphicsScene::BackgroundLayer);
-}
-
-
-
-void TikzScene::keyReleaseEvent(QKeyEvent *event)
-{
- if (!_enabled) return;
-
- if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
- deleteSelectedItems();
- } else if (event->modifiers() == Qt::NoModifier) {
- switch(event->key()) {
- case Qt::Key_S:
- tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::SELECT);
- break;
- case Qt::Key_V:
- case Qt::Key_N:
- tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::VERTEX);
- break;
- case Qt::Key_E:
- tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::EDGE);
- break;
- case Qt::Key_B:
- tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::CROP);
- break;
- }
- }
-}
-
-void TikzScene::keyPressEvent(QKeyEvent *event)
-{
- bool capture = false;
-
- if (event->key() == Qt::Key_QuoteLeft) {
- capture = true;
- _styles->nextNodeStyle();
- }
-
- if (event->modifiers() & Qt::ControlModifier) {
- QPointF delta(0,0);
- float shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0f : 10.0f;
- switch(event->key()) {
- case Qt::Key_Left:
- delta.setX(-0.025f * shift);
- break;
- case Qt::Key_Right:
- delta.setX(0.025f * shift);
- break;
- case Qt::Key_Up:
- delta.setY(0.025f * shift);
- break;
- case Qt::Key_Down:
- delta.setY(-0.025f * shift);
- break;
- }
-
- if (!delta.isNull()) {
- capture = true;
- QMap<Node*,QPointF> oldNodePositions;
- QMap<Node*,QPointF> newNodePositions;
- QPointF pos;
-
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
- pos = ni->node()->point();
- oldNodePositions.insert(ni->node(), pos);
- newNodePositions.insert(ni->node(), pos + delta);
- }
- }
-
- MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions);
- _tikzDocument->undoStack()->push(cmd);
- }
- }
-
- if (!capture) QGraphicsScene::keyPressEvent(event);
-}
-
-void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
-{
- if (!_enabled) return;
-
- QPointF mousePos = event->scenePos();
-
- foreach (QGraphicsItem *it, items(mousePos)) {
- if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
- ChangeEdgeModeCommand *cmd = new ChangeEdgeModeCommand(this, ei->edge());
- _tikzDocument->undoStack()->push(cmd);
- break;
- } else if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
- bool ok;
- QString newLabel = QInputDialog::getText(views()[0], tr("Node label"),
- tr("Label:"), QLineEdit::Normal,
- ni->node()->label(), &ok);
- if (ok && !newLabel.isEmpty()) {
- QMap<Node*,QString> oldLabels;
- oldLabels.insert(ni->node(), ni->node()->label());
- ChangeLabelCommand *cmd = new ChangeLabelCommand(this, graph(), oldLabels, newLabel);
- _tikzDocument->undoStack()->push(cmd);
- }
- break;
- }
- }
-}
-
-bool TikzScene::enabled() const
-{
- return _enabled;
-}
-
-void TikzScene::setEnabled(bool enabled)
-{
- _enabled = enabled;
- update();
-}
-
-int TikzScene::lineNumberForSelection()
-{
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) return ni->node()->tikzLine();
- if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) return ei->edge()->tikzLine();
- }
- return 0;
-}
-
-
-void TikzScene::applyActiveStyleToNodes() {
- ApplyStyleToNodesCommand *cmd = new ApplyStyleToNodesCommand(this, _styles->activeNodeStyleName());
- _tikzDocument->undoStack()->push(cmd);
-}
-
-void TikzScene::deleteSelectedItems()
-{
- QSet<Node*> selNodes;
- QSet<Edge*> selEdges;
- getSelection(selNodes, selEdges);
-
- QMap<int,Node*> deleteNodes;
- QMap<int,Edge*> deleteEdges;
-
- for (int i = 0; i < _tikzDocument->graph()->nodes().length(); ++i) {
- Node *n = _tikzDocument->graph()->nodes()[i];
- if (selNodes.contains(n)) deleteNodes.insert(i, n);
- }
-
- for (int i = 0; i < _tikzDocument->graph()->edges().length(); ++i) {
- Edge *e = _tikzDocument->graph()->edges()[i];
- if (selEdges.contains(e) ||
- selNodes.contains(e->source()) ||
- selNodes.contains(e->target())) deleteEdges.insert(i, e);
- }
-
- //qDebug() << "nodes:" << deleteNodes;
- //qDebug() << "edges:" << deleteEdges;
- DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges);
- _tikzDocument->undoStack()->push(cmd);
-}
-
-void TikzScene::copyToClipboard()
-{
- Graph *g = graph()->copyOfSubgraphWithNodes(getSelectedNodes());
- QGuiApplication::clipboard()->setText(g->tikz());
- delete g;
-}
-
-void TikzScene::cutToClipboard()
-{
- copyToClipboard();
- deleteSelectedItems();
-}
-
-
-void TikzScene::pasteFromClipboard()
-{
- QString tikz = QGuiApplication::clipboard()->text();
- Graph *g = new Graph();
- TikzAssembler ass(g);
-
- // attempt to parse whatever's on the clipboard, if we get a
- // non-empty tikz graph, insert it.
- if (ass.parse(tikz) && !g->nodes().isEmpty()) {
- // make sure names in the new subgraph are fresh
- g->renameApart(graph());
-
- QRectF srcRect = g->realBbox();
- QRectF tgtRect = graph()->realBbox();
- QPointF shift(tgtRect.right() - srcRect.left(), 0.0f);
-
- if (shift.x() > 0) {
- foreach (Node *n, g->nodes()) {
- n->setPoint(n->point() + shift);
- }
- }
-
- PasteCommand *cmd = new PasteCommand(this, g);
- _tikzDocument->undoStack()->push(cmd);
- }
-}
-
-void TikzScene::selectAllNodes()
-{
- foreach (NodeItem *ni, _nodeItems.values()) {
- ni->setSelected(true);
- }
-}
-
-void TikzScene::deselectAll()
-{
- selectedItems().clear();
-}
-
-void TikzScene::parseTikz(QString tikz)
-{
- Graph *newGraph = new Graph(this);
- TikzAssembler ass(newGraph);
- if (ass.parse(tikz)) {
- ReplaceGraphCommand *cmd = new ReplaceGraphCommand(this, graph(), newGraph);
- tikzDocument()->undoStack()->push(cmd);
- setEnabled(true);
- }
-}
-
-void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges)
-{
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
- if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) selEdges << ei->edge();
- }
-}
-
-QSet<Node *> TikzScene::getSelectedNodes()
-{
- QSet<Node*> selNodes;
- foreach (QGraphicsItem *gi, selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
- }
- return selNodes;
-}
-
-
-TikzDocument *TikzScene::tikzDocument() const
-{
- return _tikzDocument;
-}
-
-void TikzScene::setTikzDocument(TikzDocument *tikzDocument)
-{
- _tikzDocument = tikzDocument;
- graphReplaced();
-}
-
-void TikzScene::reloadStyles()
-{
- _styles->reloadStyles();
- foreach(EdgeItem *ei, _edgeItems) {
- ei->edge()->attachStyle();
- ei->readPos(); // trigger a repaint
- }
-
- foreach (NodeItem *ni, _nodeItems) {
- ni->node()->attachStyle();
- ni->readPos(); // trigger a repaint
- }
-}
-
-// void TikzScene::refreshSceneBounds()
-// {
-// // if (!views().empty()) {
-// // QGraphicsView *v = views().first();
-// // QRectF viewB = v->mapToScene(v->viewport()->rect()).boundingRect();
-// // //QPointF tl = v->mapToScene(viewB.topLeft());
-// // //viewB.setTopLeft(tl);
-//
-// // QRectF bounds = viewB.united(rectToScreen(graph()->realBbox().adjusted(-1.0f, -1.0f, 1.0f, 1.0f)));
-// // //qDebug() << viewB;
-//
-// // if (bounds != sceneRect()) {
-// // QPointF c = viewB.center();
-// // setSceneRect(bounds);
-// // v->centerOn(c);
-// // }
-// // }
-// //setBounds(graphB);
-// }
-
-void TikzScene::refreshAdjacentEdges(QList<Node*> nodes)
-{
- if (nodes.empty()) return;
- foreach (Edge *e, _edgeItems.keys()) {
- EdgeItem *ei = _edgeItems[e];
-
- // the list "nodes" can be out of date, e.g. if the graph changes while dragging
- if (ei != 0) {
- if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) {
- ei->edge()->updateControls();
- ei->readPos();
- }
- }
- }
-}
-
-//void TikzScene::setBounds(QRectF bounds)
-//{
-// if (bounds != sceneRect()) {
-// if (!views().empty()) {
-// QGraphicsView *v = views().first();
-// QPointF c = v->mapToScene(v->viewport()->rect().center());
-// setSceneRect(bounds);
-// v->centerOn(c);
-// } else {
-// setSceneRect(bounds);
-// }
-// }
-//}
-
-QMap<Node*,NodeItem *> &TikzScene::nodeItems()
-{
- return _nodeItems;
-}
-
-QMap<Edge*,EdgeItem*> &TikzScene::edgeItems()
-{
- return _edgeItems;
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "util.h"
+#include "tikzscene.h"
+#include "undocommands.h"
+#include "tikzassembler.h"
+
+#include <QPen>
+#include <QBrush>
+#include <QDebug>
+#include <QClipboard>
+#include <QInputDialog>
+#include <cmath>
+
+
+TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools,
+ StylePalette *styles, QObject *parent) :
+ QGraphicsScene(parent), _tikzDocument(tikzDocument), _tools(tools), _styles(styles)
+{
+ _modifyEdgeItem = 0;
+ _edgeStartNodeItem = 0;
+ _drawEdgeItem = new QGraphicsLineItem();
+ _rubberBandItem = new QGraphicsRectItem();
+ _enabled = true;
+ //setSceneRect(-310,-230,620,450);
+ setSceneRect(-1000,-1000,2000,2000);
+
+ QPen pen;
+ pen.setColor(QColor::fromRgbF(0.5f, 0.0f, 0.5f));
+ //pen.setWidth(3.0f);
+ pen.setCosmetic(true);
+ _drawEdgeItem->setPen(pen);
+ _drawEdgeItem->setLine(0,0,0,0);
+ _drawEdgeItem->setVisible(false);
+ addItem(_drawEdgeItem);
+
+ pen.setColor(QColor::fromRgbF(0.6f, 0.6f, 0.8f));
+ //pen.setWidth(3.0f);
+ //QVector<qreal> dash;
+ //dash << 4.0 << 4.0;
+ pen.setStyle(Qt::DashLine);
+ //pen.setDashPattern(dash);
+ _rubberBandItem->setPen(pen);
+
+ QBrush brush(QColor::fromRgbF(0.6,0.6,0.8,0.2));
+ _rubberBandItem->setBrush(brush);
+
+ _rubberBandItem->setVisible(false);
+ addItem(_rubberBandItem);
+}
+
+TikzScene::~TikzScene() {
+}
+
+Graph *TikzScene::graph()
+{
+ return _tikzDocument->graph();
+}
+
+void TikzScene::graphReplaced()
+{
+
+ foreach (NodeItem *ni, _nodeItems) {
+ removeItem(ni);
+ delete ni;
+ }
+ _nodeItems.clear();
+
+ foreach (EdgeItem *ei, _edgeItems) {
+ removeItem(ei);
+ delete ei;
+ }
+ _edgeItems.clear();
+
+ foreach (Edge *e, graph()->edges()) {
+ e->attachStyle();
+ EdgeItem *ei = new EdgeItem(e);
+ _edgeItems.insert(e, ei);
+ addItem(ei);
+ }
+
+ foreach (Node *n, graph()->nodes()) {
+ n->attachStyle();
+ NodeItem *ni = new NodeItem(n);
+ _nodeItems.insert(n, ni);
+ addItem(ni);
+ }
+}
+
+void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ _mouseDownPos = event->scenePos();
+
+ _draggingNodes = false;
+
+ // disable rubber band drag, which will clear the selection. Only re-enable it
+ // for the SELECT tool, and when no control point has been clicked.
+ //views()[0]->setDragMode(QGraphicsView::NoDrag);
+
+ // radius of a control point for bezier edges, in scene coordinates
+ qreal cpR = GLOBAL_SCALEF * (0.1);
+ qreal cpR2 = cpR * cpR;
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ // check if we grabbed a control point of an edge
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
+ qreal dx, dy;
+
+ dx = ei->cp1Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp1Item()->pos().y() - _mouseDownPos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = true;
+ break;
+ }
+
+ dx = ei->cp2Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp2Item()->pos().y() - _mouseDownPos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = false;
+ break;
+ }
+ }
+ }
+
+ if (_modifyEdgeItem != 0) {
+ // store for undo purposes
+ Edge *e = _modifyEdgeItem->edge();
+ _oldBend = e->bend();
+ _oldInAngle = e->inAngle();
+ _oldOutAngle = e->outAngle();
+ _oldWeight = e->weight();
+ } else {
+ // since we are not dragging a control point, process the click normally
+ //views()[0]->setDragMode(QGraphicsView::RubberBandDrag);
+ QGraphicsScene::mousePressEvent(event);
+
+ if (items(_mouseDownPos).isEmpty()) {
+ _rubberBandItem->setRect(QRectF(_mouseDownPos,_mouseDownPos));
+ _rubberBandItem->setVisible(true);
+ qDebug() << "starting rubber band drag";
+ }
+
+// foreach (QGraphicsItem *gi, items()) {
+// if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
+// //qDebug() << "got an edge item: " << ei;
+// ei->setFlag(QGraphicsItem::ItemIsSelectable, false);
+// //ei->setSelected(true);
+// }
+// }
+
+ // save current node positions for undo support
+ _oldNodePositions.clear();
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ _oldNodePositions.insert(ni->node(), ni->node()->point());
+ }
+ }
+
+ auto its = items(_mouseDownPos);
+ if (!its.isEmpty() && dynamic_cast<NodeItem*>(its[0]))
+ _draggingNodes = true;
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ break;
+ case ToolPalette::EDGE:
+ foreach (QGraphicsItem *gi, items(_mouseDownPos)) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
+ _edgeStartNodeItem = ni;
+ _edgeEndNodeItem = ni;
+ QLineF line(toScreen(ni->node()->point()), _mouseDownPos);
+ _drawEdgeItem->setLine(line);
+ _drawEdgeItem->setVisible(true);
+ break;
+ }
+ }
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+}
+
+void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ QPointF mousePos = event->scenePos();
+ //QRectF rb = views()[0]->rubberBandRect();
+ //invalidate(-800,-800,1600,1600);
+ //invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ if (_modifyEdgeItem != 0) {
+ Edge *e = _modifyEdgeItem->edge();
+
+ // dragging a control point
+ QPointF src = toScreen(e->source()->point());
+ QPointF targ = toScreen(e->target()->point());
+ float dx1 = targ.x() - src.x();
+ float dy1 = targ.y() - src.y();
+ float dx2, dy2;
+ if (_firstControlPoint) {
+ dx2 = mousePos.x() - src.x();
+ dy2 = mousePos.y() - src.y();
+ } else {
+ dx2 = mousePos.x() - targ.x();
+ dy2 = mousePos.y() - targ.y();
+ }
+
+ float baseDist = sqrt(dx1*dx1 + dy1*dy1);
+ float handleDist = sqrt(dx2*dx2 + dy2*dy2);
+ float wcoarseness = 0.1f;
+
+ if (!e->isSelfLoop()) {
+ if (baseDist != 0) {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist));
+ } else {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF));
+ }
+ }
+
+ float control_angle = atan2(-dy2, dx2);
+
+ int bcoarseness = 15;
+
+ if(e->basicBendMode()) {
+ float bnd;
+ float base_angle = atan2(-dy1, dx1);
+ if (_firstControlPoint) {
+ bnd = base_angle - control_angle;
+ } else {
+ bnd = control_angle - base_angle + M_PI;
+ if (bnd > M_PI) bnd -= 2*M_PI;
+ }
+
+ e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness);
+
+ } else {
+ int bnd = round(control_angle * (180.0f / M_PI) *
+ (1.0f / (float)bcoarseness)) *
+ bcoarseness;
+ if (_firstControlPoint) {
+ // TODO: enable moving both control points
+// if ([theEvent modifierFlags] & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setInAngle:[modifyEdge inAngle] +
+// (bnd - [modifyEdge outAngle])];
+// } else {
+// [modifyEdge setInAngle:[modifyEdge inAngle] -
+// (bnd - [modifyEdge outAngle])];
+// }
+// }
+
+ e->setOutAngle(bnd);
+ } else {
+// if (theEvent.modifierFlags & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] +
+// (bnd - [modifyEdge inAngle])];
+// } else {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] -
+// (bnd - [modifyEdge inAngle])];
+// }
+// }
+
+ e->setInAngle(bnd);
+ }
+ }
+
+ _modifyEdgeItem->readPos();
+
+ } else if (_draggingNodes) { // nodes being dragged
+ QGraphicsScene::mouseMoveEvent(event);
+
+ // apply the same offset to all nodes, otherwise we get odd rounding behaviour with
+ // multiple selection.
+ QPointF shift = mousePos - _mouseDownPos;
+ shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
+
+ foreach (Node *n, _oldNodePositions.keys()) {
+ NodeItem *ni = _nodeItems[n];
+
+ // in (rare) cases, the graph can change while we are dragging
+ if (ni != 0) {
+ ni->setPos(toScreen(_oldNodePositions[n]) + shift);
+ ni->writePos();
+ }
+ }
+
+ refreshAdjacentEdges(_oldNodePositions.keys());
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseMoveEvent(event);
+
+ if (_rubberBandItem->isVisible()) {
+ qreal left = std::min(_mouseDownPos.x(), mousePos.x());
+ qreal top = std::min(_mouseDownPos.y(), mousePos.y());
+ qreal w = std::abs(_mouseDownPos.x() - mousePos.x());
+ qreal h = std::abs(_mouseDownPos.y() - mousePos.y());
+
+ _rubberBandItem->setRect(QRectF(left, top, w, h));
+ }
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ break;
+ case ToolPalette::EDGE:
+ if (_drawEdgeItem->isVisible()) {
+ _edgeEndNodeItem = 0;
+ foreach (QGraphicsItem *gi, items(mousePos)) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
+ _edgeEndNodeItem = ni;
+ break;
+ }
+ }
+ QPointF p1 = _drawEdgeItem->line().p1();
+ QPointF p2 = (_edgeEndNodeItem != 0) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos;
+ QLineF line(p1, p2);
+
+ _drawEdgeItem->setLine(line);
+ }
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+}
+
+void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ QPointF mousePos = event->scenePos();
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ if (_modifyEdgeItem != 0) {
+ // finished dragging a control point
+ Edge *e = _modifyEdgeItem->edge();
+
+ if (_oldWeight != e->weight() ||
+ _oldBend != e->bend() ||
+ _oldInAngle != e->inAngle() ||
+ _oldOutAngle != e->outAngle())
+ {
+ EdgeBendCommand *cmd = new EdgeBendCommand(this, e, _oldWeight, _oldBend, _oldInAngle, _oldOutAngle);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+
+ _modifyEdgeItem = 0;
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseReleaseEvent(event);
+
+ if (_rubberBandItem->isVisible()) {
+ QPainterPath sel;
+ sel.addRect(_rubberBandItem->rect());
+ foreach (QGraphicsItem *gi, items()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ if (sel.contains(toScreen(ni->node()->point()))) ni->setSelected(true);
+ }
+ }
+ //setSelectionArea(sel);
+ }
+
+ _rubberBandItem->setVisible(false);
+
+ if (!_oldNodePositions.empty()) {
+ QPointF shift = mousePos - _mouseDownPos;
+ shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
+
+ if (shift.x() != 0 || shift.y() != 0) {
+ QMap<Node*,QPointF> newNodePositions;
+
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ ni->writePos();
+ newNodePositions.insert(ni->node(), ni->node()->point());
+ }
+ }
+
+ //qDebug() << _oldNodePositions;
+ //qDebug() << newNodePositions;
+
+ _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions));
+ }
+
+ _oldNodePositions.clear();
+ }
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ {
+ QPointF gridPos(round(mousePos.x()/GRID_SEP)*GRID_SEP, round(mousePos.y()/GRID_SEP)*GRID_SEP);
+ Node *n = new Node(_tikzDocument);
+ n->setName(graph()->freshNodeName());
+ n->setPoint(fromScreen(gridPos));
+ n->setStyleName(_styles->activeNodeStyleName());
+
+ QRectF grow(gridPos.x() - GLOBAL_SCALEF, gridPos.y() - GLOBAL_SCALEF, 2 * GLOBAL_SCALEF, 2 * GLOBAL_SCALEF);
+ QRectF newBounds = sceneRect().united(grow);
+ //qDebug() << grow;
+ //qDebug() << newBounds;
+
+ AddNodeCommand *cmd = new AddNodeCommand(this, n, newBounds);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ break;
+ case ToolPalette::EDGE:
+ if (_edgeStartNodeItem != 0 && _edgeEndNodeItem != 0) {
+ Edge *e = new Edge(_edgeStartNodeItem->node(), _edgeEndNodeItem->node(), _tikzDocument);
+ e->setStyleName(_styles->activeEdgeStyleName());
+ AddEdgeCommand *cmd = new AddEdgeCommand(this, e);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ _edgeStartNodeItem = 0;
+ _edgeEndNodeItem = 0;
+ _drawEdgeItem->setVisible(false);
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+
+ // clear artefacts from rubber band selection
+ invalidate(QRect(), QGraphicsScene::BackgroundLayer);
+}
+
+
+
+void TikzScene::keyReleaseEvent(QKeyEvent *event)
+{
+ if (!_enabled) return;
+
+ if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
+ deleteSelectedItems();
+ } else if (event->modifiers() == Qt::NoModifier) {
+ switch(event->key()) {
+ case Qt::Key_S:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::SELECT);
+ break;
+ case Qt::Key_V:
+ case Qt::Key_N:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::VERTEX);
+ break;
+ case Qt::Key_E:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::EDGE);
+ break;
+ case Qt::Key_B:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::CROP);
+ break;
+ }
+ }
+}
+
+void TikzScene::keyPressEvent(QKeyEvent *event)
+{
+ bool capture = false;
+
+ if (event->key() == Qt::Key_QuoteLeft) {
+ capture = true;
+ _styles->nextNodeStyle();
+ }
+
+ if (event->modifiers() & Qt::ControlModifier) {
+ QPointF delta(0,0);
+ float shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0f : 10.0f;
+ switch(event->key()) {
+ case Qt::Key_Left:
+ delta.setX(-0.025f * shift);
+ break;
+ case Qt::Key_Right:
+ delta.setX(0.025f * shift);
+ break;
+ case Qt::Key_Up:
+ delta.setY(0.025f * shift);
+ break;
+ case Qt::Key_Down:
+ delta.setY(-0.025f * shift);
+ break;
+ }
+
+ if (!delta.isNull()) {
+ capture = true;
+ QMap<Node*,QPointF> oldNodePositions;
+ QMap<Node*,QPointF> newNodePositions;
+ QPointF pos;
+
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ pos = ni->node()->point();
+ oldNodePositions.insert(ni->node(), pos);
+ newNodePositions.insert(ni->node(), pos + delta);
+ }
+ }
+
+ MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ }
+
+ if (!capture) QGraphicsScene::keyPressEvent(event);
+}
+
+void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ QPointF mousePos = event->scenePos();
+
+ foreach (QGraphicsItem *it, items(mousePos)) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
+ ChangeEdgeModeCommand *cmd = new ChangeEdgeModeCommand(this, ei->edge());
+ _tikzDocument->undoStack()->push(cmd);
+ break;
+ } else if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
+ bool ok;
+ QString newLabel = QInputDialog::getText(views()[0], tr("Node label"),
+ tr("Label:"), QLineEdit::Normal,
+ ni->node()->label(), &ok);
+ if (ok && !newLabel.isEmpty()) {
+ QMap<Node*,QString> oldLabels;
+ oldLabels.insert(ni->node(), ni->node()->label());
+ ChangeLabelCommand *cmd = new ChangeLabelCommand(this, graph(), oldLabels, newLabel);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ break;
+ }
+ }
+}
+
+bool TikzScene::enabled() const
+{
+ return _enabled;
+}
+
+void TikzScene::setEnabled(bool enabled)
+{
+ _enabled = enabled;
+ update();
+}
+
+int TikzScene::lineNumberForSelection()
+{
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) return ni->node()->tikzLine();
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) return ei->edge()->tikzLine();
+ }
+ return 0;
+}
+
+
+void TikzScene::applyActiveStyleToNodes() {
+ ApplyStyleToNodesCommand *cmd = new ApplyStyleToNodesCommand(this, _styles->activeNodeStyleName());
+ _tikzDocument->undoStack()->push(cmd);
+}
+
+void TikzScene::deleteSelectedItems()
+{
+ QSet<Node*> selNodes;
+ QSet<Edge*> selEdges;
+ getSelection(selNodes, selEdges);
+
+ QMap<int,Node*> deleteNodes;
+ QMap<int,Edge*> deleteEdges;
+
+ for (int i = 0; i < _tikzDocument->graph()->nodes().length(); ++i) {
+ Node *n = _tikzDocument->graph()->nodes()[i];
+ if (selNodes.contains(n)) deleteNodes.insert(i, n);
+ }
+
+ for (int i = 0; i < _tikzDocument->graph()->edges().length(); ++i) {
+ Edge *e = _tikzDocument->graph()->edges()[i];
+ if (selEdges.contains(e) ||
+ selNodes.contains(e->source()) ||
+ selNodes.contains(e->target())) deleteEdges.insert(i, e);
+ }
+
+ //qDebug() << "nodes:" << deleteNodes;
+ //qDebug() << "edges:" << deleteEdges;
+ DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges);
+ _tikzDocument->undoStack()->push(cmd);
+}
+
+void TikzScene::copyToClipboard()
+{
+ Graph *g = graph()->copyOfSubgraphWithNodes(getSelectedNodes());
+ QGuiApplication::clipboard()->setText(g->tikz());
+ delete g;
+}
+
+void TikzScene::cutToClipboard()
+{
+ copyToClipboard();
+ deleteSelectedItems();
+}
+
+
+void TikzScene::pasteFromClipboard()
+{
+ QString tikz = QGuiApplication::clipboard()->text();
+ Graph *g = new Graph();
+ TikzAssembler ass(g);
+
+ // attempt to parse whatever's on the clipboard, if we get a
+ // non-empty tikz graph, insert it.
+ if (ass.parse(tikz) && !g->nodes().isEmpty()) {
+ // make sure names in the new subgraph are fresh
+ g->renameApart(graph());
+
+ QRectF srcRect = g->realBbox();
+ QRectF tgtRect = graph()->realBbox();
+ QPointF shift(tgtRect.right() - srcRect.left(), 0.0f);
+
+ if (shift.x() > 0) {
+ foreach (Node *n, g->nodes()) {
+ n->setPoint(n->point() + shift);
+ }
+ }
+
+ PasteCommand *cmd = new PasteCommand(this, g);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+}
+
+void TikzScene::selectAllNodes()
+{
+ foreach (NodeItem *ni, _nodeItems.values()) {
+ ni->setSelected(true);
+ }
+}
+
+void TikzScene::deselectAll()
+{
+ selectedItems().clear();
+}
+
+void TikzScene::parseTikz(QString tikz)
+{
+ Graph *newGraph = new Graph(this);
+ TikzAssembler ass(newGraph);
+ if (ass.parse(tikz)) {
+ ReplaceGraphCommand *cmd = new ReplaceGraphCommand(this, graph(), newGraph);
+ tikzDocument()->undoStack()->push(cmd);
+ setEnabled(true);
+ }
+}
+
+void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges)
+{
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) selEdges << ei->edge();
+ }
+}
+
+QSet<Node *> TikzScene::getSelectedNodes()
+{
+ QSet<Node*> selNodes;
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
+ }
+ return selNodes;
+}
+
+
+TikzDocument *TikzScene::tikzDocument() const
+{
+ return _tikzDocument;
+}
+
+void TikzScene::setTikzDocument(TikzDocument *tikzDocument)
+{
+ _tikzDocument = tikzDocument;
+ graphReplaced();
+}
+
+void TikzScene::reloadStyles()
+{
+ _styles->reloadStyles();
+ foreach(EdgeItem *ei, _edgeItems) {
+ ei->edge()->attachStyle();
+ ei->readPos(); // trigger a repaint
+ }
+
+ foreach (NodeItem *ni, _nodeItems) {
+ ni->node()->attachStyle();
+ ni->readPos(); // trigger a repaint
+ }
+}
+
+// void TikzScene::refreshSceneBounds()
+// {
+// // if (!views().empty()) {
+// // QGraphicsView *v = views().first();
+// // QRectF viewB = v->mapToScene(v->viewport()->rect()).boundingRect();
+// // //QPointF tl = v->mapToScene(viewB.topLeft());
+// // //viewB.setTopLeft(tl);
+//
+// // QRectF bounds = viewB.united(rectToScreen(graph()->realBbox().adjusted(-1.0f, -1.0f, 1.0f, 1.0f)));
+// // //qDebug() << viewB;
+//
+// // if (bounds != sceneRect()) {
+// // QPointF c = viewB.center();
+// // setSceneRect(bounds);
+// // v->centerOn(c);
+// // }
+// // }
+// //setBounds(graphB);
+// }
+
+void TikzScene::refreshAdjacentEdges(QList<Node*> nodes)
+{
+ if (nodes.empty()) return;
+ foreach (Edge *e, _edgeItems.keys()) {
+ EdgeItem *ei = _edgeItems[e];
+
+ // the list "nodes" can be out of date, e.g. if the graph changes while dragging
+ if (ei != 0) {
+ if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) {
+ ei->edge()->updateControls();
+ ei->readPos();
+ }
+ }
+ }
+}
+
+//void TikzScene::setBounds(QRectF bounds)
+//{
+// if (bounds != sceneRect()) {
+// if (!views().empty()) {
+// QGraphicsView *v = views().first();
+// QPointF c = v->mapToScene(v->viewport()->rect().center());
+// setSceneRect(bounds);
+// v->centerOn(c);
+// } else {
+// setSceneRect(bounds);
+// }
+// }
+//}
+
+QMap<Node*,NodeItem *> &TikzScene::nodeItems()
+{
+ return _nodeItems;
+}
+
+QMap<Edge*,EdgeItem*> &TikzScene::edgeItems()
+{
+ return _edgeItems;
+}
diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h
index 4ac56c7..8aafe28 100644
--- a/src/gui/tikzscene.h
+++ b/src/gui/tikzscene.h
@@ -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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * Manage the scene, which contains a single Graph, and respond to user input. This serves as
- * the controller for the MVC (TikzDocument, TikzView, TikzScene).
- */
-
-#ifndef TIKZSCENE_H
-#define TIKZSCENE_H
-
-#include "graph.h"
-#include "nodeitem.h"
-#include "edgeitem.h"
-#include "tikzdocument.h"
-#include "toolpalette.h"
-#include "stylepalette.h"
-
-#include <QWidget>
-#include <QGraphicsScene>
-#include <QPainter>
-#include <QRectF>
-#include <QVector>
-#include <QGraphicsEllipseItem>
-#include <QGraphicsSceneMouseEvent>
-
-class TikzScene : public QGraphicsScene
-{
- Q_OBJECT
-public:
- TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent);
- ~TikzScene();
- Graph *graph();
- QMap<Node*,NodeItem*> &nodeItems();
- QMap<Edge*,EdgeItem*> &edgeItems();
- void refreshAdjacentEdges(QList<Node*> nodes);
-// void setBounds(QRectF bounds);
-
- TikzDocument *tikzDocument() const;
- void setTikzDocument(TikzDocument *tikzDocument);
- void reloadStyles();
- //void refreshSceneBounds();
- void applyActiveStyleToNodes();
- void deleteSelectedItems();
- void copyToClipboard();
- void cutToClipboard();
- void pasteFromClipboard();
- void selectAllNodes();
- void deselectAll();
- void parseTikz(QString tikz);
- bool enabled() const;
- void setEnabled(bool enabled);
- int lineNumberForSelection();
-
-
- void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges);
- QSet<Node*> getSelectedNodes();
-
-public slots:
- void graphReplaced();
-
-protected:
- void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
- void keyReleaseEvent(QKeyEvent *event) override;
- void keyPressEvent(QKeyEvent *event) override;
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
-private:
- TikzDocument *_tikzDocument;
- ToolPalette *_tools;
- StylePalette *_styles;
- QMap<Node*,NodeItem*> _nodeItems;
- QMap<Edge*,EdgeItem*> _edgeItems;
- QGraphicsLineItem *_drawEdgeItem;
- QGraphicsRectItem *_rubberBandItem;
- EdgeItem *_modifyEdgeItem;
- NodeItem *_edgeStartNodeItem;
- NodeItem *_edgeEndNodeItem;
- bool _firstControlPoint;
- QPointF _mouseDownPos;
- bool _draggingNodes;
-
- QMap<Node*,QPointF> _oldNodePositions;
- float _oldWeight;
- int _oldBend;
- int _oldInAngle;
- int _oldOutAngle;
- bool _enabled;
-};
-
-#endif // TIKZSCENE_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Manage the scene, which contains a single Graph, and respond to user input. This serves as
+ * the controller for the MVC (TikzDocument, TikzView, TikzScene).
+ */
+
+#ifndef TIKZSCENE_H
+#define TIKZSCENE_H
+
+#include "graph.h"
+#include "nodeitem.h"
+#include "edgeitem.h"
+#include "tikzdocument.h"
+#include "toolpalette.h"
+#include "stylepalette.h"
+
+#include <QWidget>
+#include <QGraphicsScene>
+#include <QPainter>
+#include <QRectF>
+#include <QVector>
+#include <QGraphicsEllipseItem>
+#include <QGraphicsSceneMouseEvent>
+
+class TikzScene : public QGraphicsScene
+{
+ Q_OBJECT
+public:
+ TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent);
+ ~TikzScene();
+ Graph *graph();
+ QMap<Node*,NodeItem*> &nodeItems();
+ QMap<Edge*,EdgeItem*> &edgeItems();
+ void refreshAdjacentEdges(QList<Node*> nodes);
+// void setBounds(QRectF bounds);
+
+ TikzDocument *tikzDocument() const;
+ void setTikzDocument(TikzDocument *tikzDocument);
+ void reloadStyles();
+ //void refreshSceneBounds();
+ void applyActiveStyleToNodes();
+ void deleteSelectedItems();
+ void copyToClipboard();
+ void cutToClipboard();
+ void pasteFromClipboard();
+ void selectAllNodes();
+ void deselectAll();
+ void parseTikz(QString tikz);
+ bool enabled() const;
+ void setEnabled(bool enabled);
+ int lineNumberForSelection();
+
+
+ void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges);
+ QSet<Node*> getSelectedNodes();
+
+public slots:
+ void graphReplaced();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
+private:
+ TikzDocument *_tikzDocument;
+ ToolPalette *_tools;
+ StylePalette *_styles;
+ QMap<Node*,NodeItem*> _nodeItems;
+ QMap<Edge*,EdgeItem*> _edgeItems;
+ QGraphicsLineItem *_drawEdgeItem;
+ QGraphicsRectItem *_rubberBandItem;
+ EdgeItem *_modifyEdgeItem;
+ NodeItem *_edgeStartNodeItem;
+ NodeItem *_edgeEndNodeItem;
+ bool _firstControlPoint;
+ QPointF _mouseDownPos;
+ bool _draggingNodes;
+
+ QMap<Node*,QPointF> _oldNodePositions;
+ float _oldWeight;
+ int _oldBend;
+ int _oldInAngle;
+ int _oldOutAngle;
+ bool _enabled;
+};
+
+#endif // TIKZSCENE_H
diff --git a/src/gui/tikzview.cpp b/src/gui/tikzview.cpp
index 6cdb17c..f0084fb 100644
--- a/src/gui/tikzview.cpp
+++ b/src/gui/tikzview.cpp
@@ -1,128 +1,128 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzview.h"
-#include "tikzit.h"
-
-#include <QDebug>
-#include <QScrollBar>
-
-TikzView::TikzView(QWidget *parent) : QGraphicsView(parent)
-{
- setRenderHint(QPainter::Antialiasing);
- //setDragMode(QGraphicsView::RubberBandDrag);
-
- _scale = 1.0f;
-}
-
-void TikzView::zoomIn()
-{
- _scale *= 1.6f;
- scale(1.6,1.6);
-}
-
-void TikzView::zoomOut()
-{
- _scale *= 0.625f;
- scale(0.625,0.625);
-}
-
-void TikzView::setScene(QGraphicsScene *scene)
-{
- QGraphicsView::setScene(scene);
- centerOn(QPointF(0.0f,-230.0f));
-}
-
-void TikzView::drawBackground(QPainter *painter, const QRectF &rect)
-{
- // draw a gray background if disabled
- TikzScene *sc = static_cast<TikzScene*>(scene());
- if (!sc->enabled()) painter->fillRect(rect, QBrush(QColor(240,240,240)));
-
- // draw the grid
-
- QPen pen1;
- //pen1.setWidthF(0.5);
- pen1.setCosmetic(true);
- pen1.setColor(QColor(250,250,255));
-
- QPen pen2 = pen1;
- pen2.setColor(QColor(240,240,250));
-
- QPen pen3 = pen1;
- pen3.setColor(QColor(220,220,240));
-
- painter->setPen(pen1);
-
- if (_scale > 0.2f) {
- for (int x = -GRID_SEP; x > rect.left(); x -= GRID_SEP) {
- if (x % (GRID_SEP * GRID_N) != 0) {
- qreal xf = (qreal)x;
- painter->drawLine(xf, rect.top(), xf, rect.bottom());
- }
- }
-
- for (int x = GRID_SEP; x < rect.right(); x += GRID_SEP) {
- if (x % (GRID_SEP * GRID_N) != 0) {
- qreal xf = (qreal)x;
- painter->drawLine(xf, rect.top(), xf, rect.bottom());
- }
- }
-
- for (int y = -GRID_SEP; y > rect.top(); y -= GRID_SEP) {
- if (y % (GRID_SEP * GRID_N) != 0) {
- qreal yf = (qreal)y;
- painter->drawLine(rect.left(), yf, rect.right(), yf);
- }
- }
-
- for (int y = GRID_SEP; y < rect.bottom(); y += GRID_SEP) {
- if (y % (GRID_SEP * GRID_N) != 0) {
- qreal yf = (qreal)y;
- painter->drawLine(rect.left(), yf, rect.right(), yf);
- }
- }
- }
-
- painter->setPen(pen2);
-
- for (int x = -GRID_SEP*GRID_N; x > rect.left(); x -= GRID_SEP*GRID_N) {
- qreal xf = (qreal)x;
- painter->drawLine(xf, rect.top(), xf, rect.bottom());
- }
-
- for (int x = GRID_SEP*GRID_N; x < rect.right(); x += GRID_SEP*GRID_N) {
- qreal xf = (qreal)x;
- painter->drawLine(xf, rect.top(), xf, rect.bottom());
- }
-
- for (int y = -GRID_SEP*GRID_N; y > rect.top(); y -= GRID_SEP*GRID_N) {
- qreal yf = (qreal)y;
- painter->drawLine(rect.left(), yf, rect.right(), yf);
- }
-
- for (int y = GRID_SEP*GRID_N; y < rect.bottom(); y += GRID_SEP*GRID_N) {
- qreal yf = (qreal)y;
- painter->drawLine(rect.left(), yf, rect.right(), yf);
- }
-
- painter->setPen(pen3);
- painter->drawLine(rect.left(), 0, rect.right(), 0);
- painter->drawLine(0, rect.top(), 0, rect.bottom());
-}
-
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzview.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QScrollBar>
+
+TikzView::TikzView(QWidget *parent) : QGraphicsView(parent)
+{
+ setRenderHint(QPainter::Antialiasing);
+ //setDragMode(QGraphicsView::RubberBandDrag);
+
+ _scale = 1.0f;
+}
+
+void TikzView::zoomIn()
+{
+ _scale *= 1.6f;
+ scale(1.6,1.6);
+}
+
+void TikzView::zoomOut()
+{
+ _scale *= 0.625f;
+ scale(0.625,0.625);
+}
+
+void TikzView::setScene(QGraphicsScene *scene)
+{
+ QGraphicsView::setScene(scene);
+ centerOn(QPointF(0.0f,-230.0f));
+}
+
+void TikzView::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ // draw a gray background if disabled
+ TikzScene *sc = static_cast<TikzScene*>(scene());
+ if (!sc->enabled()) painter->fillRect(rect, QBrush(QColor(240,240,240)));
+
+ // draw the grid
+
+ QPen pen1;
+ //pen1.setWidthF(0.5);
+ pen1.setCosmetic(true);
+ pen1.setColor(QColor(250,250,255));
+
+ QPen pen2 = pen1;
+ pen2.setColor(QColor(240,240,250));
+
+ QPen pen3 = pen1;
+ pen3.setColor(QColor(220,220,240));
+
+ painter->setPen(pen1);
+
+ if (_scale > 0.2f) {
+ for (int x = -GRID_SEP; x > rect.left(); x -= GRID_SEP) {
+ if (x % (GRID_SEP * GRID_N) != 0) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+ }
+
+ for (int x = GRID_SEP; x < rect.right(); x += GRID_SEP) {
+ if (x % (GRID_SEP * GRID_N) != 0) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+ }
+
+ for (int y = -GRID_SEP; y > rect.top(); y -= GRID_SEP) {
+ if (y % (GRID_SEP * GRID_N) != 0) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+ }
+
+ for (int y = GRID_SEP; y < rect.bottom(); y += GRID_SEP) {
+ if (y % (GRID_SEP * GRID_N) != 0) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+ }
+ }
+
+ painter->setPen(pen2);
+
+ for (int x = -GRID_SEP*GRID_N; x > rect.left(); x -= GRID_SEP*GRID_N) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+
+ for (int x = GRID_SEP*GRID_N; x < rect.right(); x += GRID_SEP*GRID_N) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+
+ for (int y = -GRID_SEP*GRID_N; y > rect.top(); y -= GRID_SEP*GRID_N) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+
+ for (int y = GRID_SEP*GRID_N; y < rect.bottom(); y += GRID_SEP*GRID_N) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+
+ painter->setPen(pen3);
+ painter->drawLine(rect.left(), 0, rect.right(), 0);
+ painter->drawLine(0, rect.top(), 0, rect.bottom());
+}
+
diff --git a/src/gui/tikzview.h b/src/gui/tikzview.h
index 4ec9f3d..bfa7ace 100644
--- a/src/gui/tikzview.h
+++ b/src/gui/tikzview.h
@@ -1,52 +1,52 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * Display a Graph, and manage any user input that purely changes the view (e.g. Zoom). This
- * serves as the view in the MVC (TikzDocument, TikzView, TikzScene).
- */
-
-#ifndef TIKZVIEW_H
-#define TIKZVIEW_H
-
-#include <QObject>
-#include <QWidget>
-#include <QGraphicsView>
-#include <QPainter>
-#include <QGraphicsItem>
-#include <QStyleOptionGraphicsItem>
-#include <QRectF>
-#include <QMouseEvent>
-
-class TikzView : public QGraphicsView
-{
- Q_OBJECT
-public:
- explicit TikzView(QWidget *parent = 0);
-
-public slots:
- void zoomIn();
- void zoomOut();
- void setScene(QGraphicsScene *scene);
-protected:
- void drawBackground(QPainter *painter, const QRectF &rect);
-private:
- float _scale;
-};
-
-#endif // TIKZVIEW_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Display a Graph, and manage any user input that purely changes the view (e.g. Zoom). This
+ * serves as the view in the MVC (TikzDocument, TikzView, TikzScene).
+ */
+
+#ifndef TIKZVIEW_H
+#define TIKZVIEW_H
+
+#include <QObject>
+#include <QWidget>
+#include <QGraphicsView>
+#include <QPainter>
+#include <QGraphicsItem>
+#include <QStyleOptionGraphicsItem>
+#include <QRectF>
+#include <QMouseEvent>
+
+class TikzView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ explicit TikzView(QWidget *parent = 0);
+
+public slots:
+ void zoomIn();
+ void zoomOut();
+ void setScene(QGraphicsScene *scene);
+protected:
+ void drawBackground(QPainter *painter, const QRectF &rect);
+private:
+ float _scale;
+};
+
+#endif // TIKZVIEW_H
diff --git a/src/gui/toolpalette.cpp b/src/gui/toolpalette.cpp
index 43a4a49..2931f82 100644
--- a/src/gui/toolpalette.cpp
+++ b/src/gui/toolpalette.cpp
@@ -1,86 +1,86 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "toolpalette.h"
-
-#include <QVector>
-#include <QLayout>
-#include <QVBoxLayout>
-#include <QDebug>
-
-ToolPalette::ToolPalette(QWidget *parent) :
- QToolBar(parent)
-{
- setWindowFlags(Qt::Window
- | Qt::CustomizeWindowHint
- | Qt::WindowDoesNotAcceptFocus);
- setOrientation(Qt::Vertical);
- setFocusPolicy(Qt::NoFocus);
- //setGeometry(100,200,30,195);
-
- tools = new QActionGroup(this);
-
- select = new QAction(QIcon(":/images/Inkscape_icons_edit_select_all.svg"), "Select");
- vertex = new QAction(QIcon(":/images/Inkscape_icons_draw_ellipse.svg"), "Add Vertex");
- edge = new QAction(QIcon(":/images/Inkscape_icons_draw_path.svg"), "Add Edge");
- crop = new QAction(QIcon(":/images/crop.svg"), "Bounding Box");
-
- tools->addAction(select);
- tools->addAction(vertex);
- tools->addAction(edge);
- tools->addAction(crop);
-
- select->setCheckable(true);
- vertex->setCheckable(true);
- edge->setCheckable(true);
- crop->setCheckable(true);
- select->setChecked(true);
-
- addAction(select);
- addAction(vertex);
- addAction(edge);
- addAction(crop);
-}
-
-ToolPalette::Tool ToolPalette::currentTool() const
-{
- QAction *a = tools->checkedAction();
- if (a == vertex) return VERTEX;
- else if (a == edge) return EDGE;
- else if (a == crop) return CROP;
- else return SELECT;
-}
-
-void ToolPalette::setCurrentTool(ToolPalette::Tool tool)
-{
- switch(tool) {
- case SELECT:
- select->setChecked(true);
- break;
- case VERTEX:
- vertex->setChecked(true);
- break;
- case EDGE:
- edge->setChecked(true);
- break;
- case CROP:
- crop->setChecked(true);
- break;
- }
-}
-
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "toolpalette.h"
+
+#include <QVector>
+#include <QLayout>
+#include <QVBoxLayout>
+#include <QDebug>
+
+ToolPalette::ToolPalette(QWidget *parent) :
+ QToolBar(parent)
+{
+ setWindowFlags(Qt::Window
+ | Qt::CustomizeWindowHint
+ | Qt::WindowDoesNotAcceptFocus);
+ setOrientation(Qt::Vertical);
+ setFocusPolicy(Qt::NoFocus);
+ //setGeometry(100,200,30,195);
+
+ tools = new QActionGroup(this);
+
+ select = new QAction(QIcon(":/images/Inkscape_icons_edit_select_all.svg"), "Select");
+ vertex = new QAction(QIcon(":/images/Inkscape_icons_draw_ellipse.svg"), "Add Vertex");
+ edge = new QAction(QIcon(":/images/Inkscape_icons_draw_path.svg"), "Add Edge");
+ crop = new QAction(QIcon(":/images/crop.svg"), "Bounding Box");
+
+ tools->addAction(select);
+ tools->addAction(vertex);
+ tools->addAction(edge);
+ tools->addAction(crop);
+
+ select->setCheckable(true);
+ vertex->setCheckable(true);
+ edge->setCheckable(true);
+ crop->setCheckable(true);
+ select->setChecked(true);
+
+ addAction(select);
+ addAction(vertex);
+ addAction(edge);
+ addAction(crop);
+}
+
+ToolPalette::Tool ToolPalette::currentTool() const
+{
+ QAction *a = tools->checkedAction();
+ if (a == vertex) return VERTEX;
+ else if (a == edge) return EDGE;
+ else if (a == crop) return CROP;
+ else return SELECT;
+}
+
+void ToolPalette::setCurrentTool(ToolPalette::Tool tool)
+{
+ switch(tool) {
+ case SELECT:
+ select->setChecked(true);
+ break;
+ case VERTEX:
+ vertex->setChecked(true);
+ break;
+ case EDGE:
+ edge->setChecked(true);
+ break;
+ case CROP:
+ crop->setChecked(true);
+ break;
+ }
+}
+
diff --git a/src/gui/toolpalette.h b/src/gui/toolpalette.h
index a001055..d095d93 100644
--- a/src/gui/toolpalette.h
+++ b/src/gui/toolpalette.h
@@ -1,53 +1,53 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * A small window that lets the user select the current editing tool.
- */
-
-#ifndef TOOLPALETTE_H
-#define TOOLPALETTE_H
-
-#include <QObject>
-#include <QToolBar>
-#include <QAction>
-#include <QActionGroup>
-
-class ToolPalette : public QToolBar
-{
- Q_OBJECT
-public:
- ToolPalette(QWidget *parent = 0);
- enum Tool {
- SELECT,
- VERTEX,
- EDGE,
- CROP
- };
-
- Tool currentTool() const;
- void setCurrentTool(Tool tool);
-private:
- QActionGroup *tools;
- QAction *select;
- QAction *vertex;
- QAction *edge;
- QAction *crop;
-};
-
-#endif // TOOLPALETTE_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A small window that lets the user select the current editing tool.
+ */
+
+#ifndef TOOLPALETTE_H
+#define TOOLPALETTE_H
+
+#include <QObject>
+#include <QToolBar>
+#include <QAction>
+#include <QActionGroup>
+
+class ToolPalette : public QToolBar
+{
+ Q_OBJECT
+public:
+ ToolPalette(QWidget *parent = 0);
+ enum Tool {
+ SELECT,
+ VERTEX,
+ EDGE,
+ CROP
+ };
+
+ Tool currentTool() const;
+ void setCurrentTool(Tool tool);
+private:
+ QActionGroup *tools;
+ QAction *select;
+ QAction *vertex;
+ QAction *edge;
+ QAction *crop;
+};
+
+#endif // TOOLPALETTE_H
diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp
index 5525cb7..dc7a797 100644
--- a/src/gui/undocommands.cpp
+++ b/src/gui/undocommands.cpp
@@ -1,428 +1,428 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "undocommands.h"
-#include "nodeitem.h"
-#include "edgeitem.h"
-
-#include <QGraphicsView>
-
-GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent), _scene(scene)
-{
-}
-
-void GraphUpdateCommand::undo()
-{
- _scene->tikzDocument()->refreshTikz();
- //refreshSceneBounds does nothing
- //_scene->refreshSceneBounds();
- _scene->invalidate();
-}
-
-void GraphUpdateCommand::redo()
-{
- _scene->tikzDocument()->refreshTikz();
- //refreshSceneBounds does nothing
- //_scene->refreshSceneBounds();
- _scene->invalidate();
-}
-
-
-MoveCommand::MoveCommand(TikzScene *scene,
- QMap<Node*, QPointF> oldNodePositions,
- QMap<Node*, QPointF> newNodePositions,
- QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent),
- _oldNodePositions(oldNodePositions),
- _newNodePositions(newNodePositions)
-{}
-
-
-void MoveCommand::undo()
-{
- foreach (NodeItem *ni, _scene->nodeItems()) {
- if (_oldNodePositions.contains(ni->node())) {
- ni->node()->setPoint(_oldNodePositions.value(ni->node()));
- ni->readPos();
- }
- }
-
- _scene->refreshAdjacentEdges(_oldNodePositions.keys());
- GraphUpdateCommand::undo();
-}
-
-void MoveCommand::redo()
-{
- foreach (NodeItem *ni, _scene->nodeItems()) {
- if (_newNodePositions.contains(ni->node())) {
- ni->node()->setPoint(_newNodePositions.value(ni->node()));
- ni->readPos();
- }
- }
-
- _scene->refreshAdjacentEdges(_newNodePositions.keys());
- GraphUpdateCommand::redo();
-}
-
-EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge,
- float oldWeight, int oldBend,
- int oldInAngle, int oldOutAngle, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent),
- _edge(edge),
- _oldWeight(oldWeight), _oldBend(oldBend),
- _oldInAngle(oldInAngle), _oldOutAngle(oldOutAngle)
-{
- _newWeight = edge->weight();
- _newBend = edge->bend();
- _newInAngle = edge->inAngle();
- _newOutAngle = edge->outAngle();
-}
-
-void EdgeBendCommand::undo()
-{
- _edge->setWeight(_oldWeight);
- _edge->setBend(_oldBend);
- _edge->setInAngle(_oldInAngle);
- _edge->setOutAngle(_oldOutAngle);
-
- foreach(EdgeItem *ei, _scene->edgeItems()) {
- if (ei->edge() == _edge) {
- ei->readPos();
- break;
- }
- }
- GraphUpdateCommand::undo();
-}
-
-void EdgeBendCommand::redo()
-{
- _edge->setWeight(_newWeight);
- _edge->setBend(_newBend);
- _edge->setInAngle(_newInAngle);
- _edge->setOutAngle(_newOutAngle);
-
- foreach(EdgeItem *ei, _scene->edgeItems()) {
- if (ei->edge() == _edge) {
- ei->readPos();
- break;
- }
- }
-
- GraphUpdateCommand::redo();
-}
-
-DeleteCommand::DeleteCommand(TikzScene *scene,
- QMap<int, Node *> deleteNodes,
- QMap<int, Edge *> deleteEdges,
- QSet<Edge *> selEdges, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent),
- _deleteNodes(deleteNodes), _deleteEdges(deleteEdges), _selEdges(selEdges)
-{}
-
-void DeleteCommand::undo()
-{
- for (auto it = _deleteNodes.begin(); it != _deleteNodes.end(); ++it) {
- Node *n = it.value();
- n->attachStyle(); // in case styles have changed
- _scene->graph()->addNode(n, it.key());
- NodeItem *ni = new NodeItem(n);
- _scene->nodeItems().insert(n, ni);
- _scene->addItem(ni);
- ni->setSelected(true);
- }
-
- for (auto it = _deleteEdges.begin(); it != _deleteEdges.end(); ++it) {
- Edge *e = it.value();
- e->attachStyle();
- _scene->graph()->addEdge(e, it.key());
- EdgeItem *ei = new EdgeItem(e);
- _scene->edgeItems().insert(e, ei);
- _scene->addItem(ei);
-
- if (_selEdges.contains(e)) ei->setSelected(true);
- }
-
- GraphUpdateCommand::undo();
-}
-
-void DeleteCommand::redo()
-{
- foreach (Edge *e, _deleteEdges.values()) {
- EdgeItem *ei = _scene->edgeItems()[e];
- _scene->edgeItems().remove(e);
- _scene->removeItem(ei);
- delete ei;
-
- _scene->graph()->removeEdge(e);
- }
-
- foreach (Node *n, _deleteNodes.values()) {
- NodeItem *ni = _scene->nodeItems()[n];
- _scene->nodeItems().remove(n);
- _scene->removeItem(ni);
- delete ni;
-
- _scene->graph()->removeNode(n);
- }
-
- GraphUpdateCommand::redo();
-}
-
-AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds)
-{
-}
-
-void AddNodeCommand::undo()
-{
- NodeItem *ni = _scene->nodeItems()[_node];
- _scene->removeItem(ni);
- _scene->nodeItems().remove(_node);
- delete ni;
-
- _scene->graph()->removeNode(_node);
-
- //_scene->setBounds(_oldBounds);
-
- GraphUpdateCommand::undo();
-}
-
-void AddNodeCommand::redo()
-{
- _node->attachStyle(); // do for every redo, in case styles have changed
- _scene->graph()->addNode(_node);
- NodeItem *ni = new NodeItem(_node);
- _scene->nodeItems().insert(_node, ni);
- _scene->addItem(ni);
-
- //_scene->setBounds(_newBounds);
-
- GraphUpdateCommand::redo();
-}
-
-AddEdgeCommand::AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _edge(edge)
-{
-}
-
-void AddEdgeCommand::undo()
-{
- EdgeItem *ei = _scene->edgeItems()[_edge];
- _scene->removeItem(ei);
- _scene->edgeItems().remove(_edge);
- delete ei;
-
- _scene->graph()->removeEdge(_edge);
- GraphUpdateCommand::undo();
-}
-
-void AddEdgeCommand::redo()
-{
- _edge->attachStyle(); // do for every redo, in case styles have changed
- _scene->graph()->addEdge(_edge);
- EdgeItem *ei = new EdgeItem(_edge);
- _scene->edgeItems().insert(_edge, ei);
- _scene->addItem(ei);
-
- // TODO: deal consistently with stacking order
- // edges should always be stacked below nodes
- if (!_scene->graph()->nodes().isEmpty()) {
- ei->stackBefore(_scene->nodeItems()[_scene->graph()->nodes().first()]);
- }
-
- GraphUpdateCommand::redo();
-}
-
-ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _edge(edge)
-{
-}
-
-void ChangeEdgeModeCommand::undo()
-{
- // FIXME: this act strangely sometimes
- _edge->setBasicBendMode(!_edge->basicBendMode());
- _scene->edgeItems()[_edge]->readPos();
- GraphUpdateCommand::undo();
-}
-
-void ChangeEdgeModeCommand::redo()
-{
- _edge->setBasicBendMode(!_edge->basicBendMode());
- _scene->edgeItems()[_edge]->readPos();
- GraphUpdateCommand::redo();
-}
-
-ApplyStyleToNodesCommand::ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
-{
- foreach (QGraphicsItem *it, scene->selectedItems()) {
- if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
- _oldStyles.insert(ni->node(), ni->node()->styleName());
- }
- }
-}
-
-void ApplyStyleToNodesCommand::undo()
-{
- foreach (Node *n, _oldStyles.keys()) {
- n->setStyleName(_oldStyles[n]);
- n->attachStyle();
- }
-
- GraphUpdateCommand::undo();
-}
-
-void ApplyStyleToNodesCommand::redo()
-{
- foreach (Node *n, _oldStyles.keys()) {
- n->setStyleName(_style);
- n->attachStyle();
- }
- GraphUpdateCommand::redo();
-}
-
-ApplyStyleToEdgesCommand::ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
-{
- foreach(QGraphicsItem *it, scene->selectedItems()) {
- if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
- _oldStyles.insert(ei->edge(), ei->edge()->styleName());
- }
- }
-}
-
-void ApplyStyleToEdgesCommand::undo()
-{
- foreach(Edge *e, _oldStyles.keys()) {
- e->setStyleName(_oldStyles[e]);
- e->attachStyle();
- }
-
- GraphUpdateCommand::undo();
-}
-
-void ApplyStyleToEdgesCommand::redo()
-{
- foreach(Edge *e, _oldStyles.keys()) {
- e->setStyleName(_style);
- e->attachStyle();
- }
- GraphUpdateCommand::redo();
-}
-
-PasteCommand::PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _graph(graph)
-{
- scene->getSelection(_oldSelectedNodes, _oldSelectedEdges);
-}
-
-void PasteCommand::undo()
-{
- _scene->clearSelection();
-
- foreach (Edge *e, _graph->edges()) {
- EdgeItem *ei = _scene->edgeItems()[e];
- _scene->edgeItems().remove(e);
- _scene->removeItem(ei);
- delete ei;
-
- _scene->graph()->removeEdge(e);
- }
-
- foreach (Node *n, _graph->nodes()) {
- NodeItem *ni = _scene->nodeItems()[n];
- _scene->nodeItems().remove(n);
- _scene->removeItem(ni);
- delete ni;
-
- _scene->graph()->removeNode(n);
- }
-
- foreach(Node *n, _oldSelectedNodes) _scene->nodeItems()[n]->setSelected(true);
- foreach(Edge *e, _oldSelectedEdges) _scene->edgeItems()[e]->setSelected(true);
-
- GraphUpdateCommand::undo();
-}
-
-void PasteCommand::redo()
-{
- _scene->clearSelection();
- _scene->graph()->insertGraph(_graph);
-
- foreach (Edge *e, _graph->edges()) {
- e->attachStyle(); // in case styles have changed
- EdgeItem *ei = new EdgeItem(e);
- _scene->edgeItems().insert(e, ei);
- _scene->addItem(ei);
- }
-
- foreach (Node *n, _graph->nodes()) {
- n->attachStyle(); // in case styles have changed
- NodeItem *ni = new NodeItem(n);
- _scene->nodeItems().insert(n, ni);
- _scene->addItem(ni);
- ni->setSelected(true);
- }
-
- GraphUpdateCommand::redo();
-}
-
-ChangeLabelCommand::ChangeLabelCommand(TikzScene *scene, Graph *graph, QMap<Node *, QString> oldLabels, QString newLabel, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _oldLabels(oldLabels), _newLabel(newLabel)
-{
-}
-
-void ChangeLabelCommand::undo()
-{
- foreach (Node *n, _oldLabels.keys()) {
- n->setLabel(_oldLabels[n]);
- NodeItem *ni = _scene->nodeItems()[n];
- if (ni != 0) ni->updateBounds();
- }
-
- GraphUpdateCommand::undo();
-}
-
-void ChangeLabelCommand::redo()
-{
- foreach (Node *n, _oldLabels.keys()) {
- n->setLabel(_newLabel);
- NodeItem *ni = _scene->nodeItems()[n];
- if (ni != 0) ni->updateBounds();
- }
-
- GraphUpdateCommand::redo();
-}
-
-ReplaceGraphCommand::ReplaceGraphCommand(TikzScene *scene, Graph *oldGraph, Graph *newGraph, QUndoCommand *parent) :
- GraphUpdateCommand(scene, parent), _oldGraph(oldGraph), _newGraph(newGraph)
-{
-}
-
-void ReplaceGraphCommand::undo()
-{
- _scene->tikzDocument()->setGraph(_oldGraph);
- _scene->graphReplaced();
-}
-
-void ReplaceGraphCommand::redo()
-{
- _scene->tikzDocument()->setGraph(_newGraph);
- _scene->graphReplaced();
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "undocommands.h"
+#include "nodeitem.h"
+#include "edgeitem.h"
+
+#include <QGraphicsView>
+
+GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent), _scene(scene)
+{
+}
+
+void GraphUpdateCommand::undo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ //refreshSceneBounds does nothing
+ //_scene->refreshSceneBounds();
+ _scene->invalidate();
+}
+
+void GraphUpdateCommand::redo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ //refreshSceneBounds does nothing
+ //_scene->refreshSceneBounds();
+ _scene->invalidate();
+}
+
+
+MoveCommand::MoveCommand(TikzScene *scene,
+ QMap<Node*, QPointF> oldNodePositions,
+ QMap<Node*, QPointF> newNodePositions,
+ QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _oldNodePositions(oldNodePositions),
+ _newNodePositions(newNodePositions)
+{}
+
+
+void MoveCommand::undo()
+{
+ foreach (NodeItem *ni, _scene->nodeItems()) {
+ if (_oldNodePositions.contains(ni->node())) {
+ ni->node()->setPoint(_oldNodePositions.value(ni->node()));
+ ni->readPos();
+ }
+ }
+
+ _scene->refreshAdjacentEdges(_oldNodePositions.keys());
+ GraphUpdateCommand::undo();
+}
+
+void MoveCommand::redo()
+{
+ foreach (NodeItem *ni, _scene->nodeItems()) {
+ if (_newNodePositions.contains(ni->node())) {
+ ni->node()->setPoint(_newNodePositions.value(ni->node()));
+ ni->readPos();
+ }
+ }
+
+ _scene->refreshAdjacentEdges(_newNodePositions.keys());
+ GraphUpdateCommand::redo();
+}
+
+EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge,
+ float oldWeight, int oldBend,
+ int oldInAngle, int oldOutAngle, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _edge(edge),
+ _oldWeight(oldWeight), _oldBend(oldBend),
+ _oldInAngle(oldInAngle), _oldOutAngle(oldOutAngle)
+{
+ _newWeight = edge->weight();
+ _newBend = edge->bend();
+ _newInAngle = edge->inAngle();
+ _newOutAngle = edge->outAngle();
+}
+
+void EdgeBendCommand::undo()
+{
+ _edge->setWeight(_oldWeight);
+ _edge->setBend(_oldBend);
+ _edge->setInAngle(_oldInAngle);
+ _edge->setOutAngle(_oldOutAngle);
+
+ foreach(EdgeItem *ei, _scene->edgeItems()) {
+ if (ei->edge() == _edge) {
+ ei->readPos();
+ break;
+ }
+ }
+ GraphUpdateCommand::undo();
+}
+
+void EdgeBendCommand::redo()
+{
+ _edge->setWeight(_newWeight);
+ _edge->setBend(_newBend);
+ _edge->setInAngle(_newInAngle);
+ _edge->setOutAngle(_newOutAngle);
+
+ foreach(EdgeItem *ei, _scene->edgeItems()) {
+ if (ei->edge() == _edge) {
+ ei->readPos();
+ break;
+ }
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+DeleteCommand::DeleteCommand(TikzScene *scene,
+ QMap<int, Node *> deleteNodes,
+ QMap<int, Edge *> deleteEdges,
+ QSet<Edge *> selEdges, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _deleteNodes(deleteNodes), _deleteEdges(deleteEdges), _selEdges(selEdges)
+{}
+
+void DeleteCommand::undo()
+{
+ for (auto it = _deleteNodes.begin(); it != _deleteNodes.end(); ++it) {
+ Node *n = it.value();
+ n->attachStyle(); // in case styles have changed
+ _scene->graph()->addNode(n, it.key());
+ NodeItem *ni = new NodeItem(n);
+ _scene->nodeItems().insert(n, ni);
+ _scene->addItem(ni);
+ ni->setSelected(true);
+ }
+
+ for (auto it = _deleteEdges.begin(); it != _deleteEdges.end(); ++it) {
+ Edge *e = it.value();
+ e->attachStyle();
+ _scene->graph()->addEdge(e, it.key());
+ EdgeItem *ei = new EdgeItem(e);
+ _scene->edgeItems().insert(e, ei);
+ _scene->addItem(ei);
+
+ if (_selEdges.contains(e)) ei->setSelected(true);
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void DeleteCommand::redo()
+{
+ foreach (Edge *e, _deleteEdges.values()) {
+ EdgeItem *ei = _scene->edgeItems()[e];
+ _scene->edgeItems().remove(e);
+ _scene->removeItem(ei);
+ delete ei;
+
+ _scene->graph()->removeEdge(e);
+ }
+
+ foreach (Node *n, _deleteNodes.values()) {
+ NodeItem *ni = _scene->nodeItems()[n];
+ _scene->nodeItems().remove(n);
+ _scene->removeItem(ni);
+ delete ni;
+
+ _scene->graph()->removeNode(n);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds)
+{
+}
+
+void AddNodeCommand::undo()
+{
+ NodeItem *ni = _scene->nodeItems()[_node];
+ _scene->removeItem(ni);
+ _scene->nodeItems().remove(_node);
+ delete ni;
+
+ _scene->graph()->removeNode(_node);
+
+ //_scene->setBounds(_oldBounds);
+
+ GraphUpdateCommand::undo();
+}
+
+void AddNodeCommand::redo()
+{
+ _node->attachStyle(); // do for every redo, in case styles have changed
+ _scene->graph()->addNode(_node);
+ NodeItem *ni = new NodeItem(_node);
+ _scene->nodeItems().insert(_node, ni);
+ _scene->addItem(ni);
+
+ //_scene->setBounds(_newBounds);
+
+ GraphUpdateCommand::redo();
+}
+
+AddEdgeCommand::AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
+{
+}
+
+void AddEdgeCommand::undo()
+{
+ EdgeItem *ei = _scene->edgeItems()[_edge];
+ _scene->removeItem(ei);
+ _scene->edgeItems().remove(_edge);
+ delete ei;
+
+ _scene->graph()->removeEdge(_edge);
+ GraphUpdateCommand::undo();
+}
+
+void AddEdgeCommand::redo()
+{
+ _edge->attachStyle(); // do for every redo, in case styles have changed
+ _scene->graph()->addEdge(_edge);
+ EdgeItem *ei = new EdgeItem(_edge);
+ _scene->edgeItems().insert(_edge, ei);
+ _scene->addItem(ei);
+
+ // TODO: deal consistently with stacking order
+ // edges should always be stacked below nodes
+ if (!_scene->graph()->nodes().isEmpty()) {
+ ei->stackBefore(_scene->nodeItems()[_scene->graph()->nodes().first()]);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
+{
+}
+
+void ChangeEdgeModeCommand::undo()
+{
+ // FIXME: this act strangely sometimes
+ _edge->setBasicBendMode(!_edge->basicBendMode());
+ _scene->edgeItems()[_edge]->readPos();
+ GraphUpdateCommand::undo();
+}
+
+void ChangeEdgeModeCommand::redo()
+{
+ _edge->setBasicBendMode(!_edge->basicBendMode());
+ _scene->edgeItems()[_edge]->readPos();
+ GraphUpdateCommand::redo();
+}
+
+ApplyStyleToNodesCommand::ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
+{
+ foreach (QGraphicsItem *it, scene->selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
+ _oldStyles.insert(ni->node(), ni->node()->styleName());
+ }
+ }
+}
+
+void ApplyStyleToNodesCommand::undo()
+{
+ foreach (Node *n, _oldStyles.keys()) {
+ n->setStyleName(_oldStyles[n]);
+ n->attachStyle();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ApplyStyleToNodesCommand::redo()
+{
+ foreach (Node *n, _oldStyles.keys()) {
+ n->setStyleName(_style);
+ n->attachStyle();
+ }
+ GraphUpdateCommand::redo();
+}
+
+ApplyStyleToEdgesCommand::ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
+{
+ foreach(QGraphicsItem *it, scene->selectedItems()) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
+ _oldStyles.insert(ei->edge(), ei->edge()->styleName());
+ }
+ }
+}
+
+void ApplyStyleToEdgesCommand::undo()
+{
+ foreach(Edge *e, _oldStyles.keys()) {
+ e->setStyleName(_oldStyles[e]);
+ e->attachStyle();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ApplyStyleToEdgesCommand::redo()
+{
+ foreach(Edge *e, _oldStyles.keys()) {
+ e->setStyleName(_style);
+ e->attachStyle();
+ }
+ GraphUpdateCommand::redo();
+}
+
+PasteCommand::PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _graph(graph)
+{
+ scene->getSelection(_oldSelectedNodes, _oldSelectedEdges);
+}
+
+void PasteCommand::undo()
+{
+ _scene->clearSelection();
+
+ foreach (Edge *e, _graph->edges()) {
+ EdgeItem *ei = _scene->edgeItems()[e];
+ _scene->edgeItems().remove(e);
+ _scene->removeItem(ei);
+ delete ei;
+
+ _scene->graph()->removeEdge(e);
+ }
+
+ foreach (Node *n, _graph->nodes()) {
+ NodeItem *ni = _scene->nodeItems()[n];
+ _scene->nodeItems().remove(n);
+ _scene->removeItem(ni);
+ delete ni;
+
+ _scene->graph()->removeNode(n);
+ }
+
+ foreach(Node *n, _oldSelectedNodes) _scene->nodeItems()[n]->setSelected(true);
+ foreach(Edge *e, _oldSelectedEdges) _scene->edgeItems()[e]->setSelected(true);
+
+ GraphUpdateCommand::undo();
+}
+
+void PasteCommand::redo()
+{
+ _scene->clearSelection();
+ _scene->graph()->insertGraph(_graph);
+
+ foreach (Edge *e, _graph->edges()) {
+ e->attachStyle(); // in case styles have changed
+ EdgeItem *ei = new EdgeItem(e);
+ _scene->edgeItems().insert(e, ei);
+ _scene->addItem(ei);
+ }
+
+ foreach (Node *n, _graph->nodes()) {
+ n->attachStyle(); // in case styles have changed
+ NodeItem *ni = new NodeItem(n);
+ _scene->nodeItems().insert(n, ni);
+ _scene->addItem(ni);
+ ni->setSelected(true);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ChangeLabelCommand::ChangeLabelCommand(TikzScene *scene, Graph *graph, QMap<Node *, QString> oldLabels, QString newLabel, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _oldLabels(oldLabels), _newLabel(newLabel)
+{
+}
+
+void ChangeLabelCommand::undo()
+{
+ foreach (Node *n, _oldLabels.keys()) {
+ n->setLabel(_oldLabels[n]);
+ NodeItem *ni = _scene->nodeItems()[n];
+ if (ni != 0) ni->updateBounds();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ChangeLabelCommand::redo()
+{
+ foreach (Node *n, _oldLabels.keys()) {
+ n->setLabel(_newLabel);
+ NodeItem *ni = _scene->nodeItems()[n];
+ if (ni != 0) ni->updateBounds();
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ReplaceGraphCommand::ReplaceGraphCommand(TikzScene *scene, Graph *oldGraph, Graph *newGraph, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _oldGraph(oldGraph), _newGraph(newGraph)
+{
+}
+
+void ReplaceGraphCommand::undo()
+{
+ _scene->tikzDocument()->setGraph(_oldGraph);
+ _scene->graphReplaced();
+}
+
+void ReplaceGraphCommand::redo()
+{
+ _scene->tikzDocument()->setGraph(_newGraph);
+ _scene->graphReplaced();
+}
diff --git a/src/gui/undocommands.h b/src/gui/undocommands.h
index 292632e..9164f01 100644
--- a/src/gui/undocommands.h
+++ b/src/gui/undocommands.h
@@ -1,194 +1,194 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * \file undocommands.h
- *
- * All changes to a TikzDocument are done via subclasses of QUndoCommand. When a controller
- * (e.g. TikzScene) gets input from the user to change the document, it will push one of
- * these commands onto the TikzDocument's undo stack, which automatically calls the redo()
- * method of the command.
- */
-
-#ifndef UNDOCOMMANDS_H
-#define UNDOCOMMANDS_H
-
-#include "tikzscene.h"
-
-#include <QUndoCommand>
-#include <QSet>
-
-class GraphUpdateCommand : public QUndoCommand {
-public:
- explicit GraphUpdateCommand(TikzScene *scene,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-protected:
- TikzScene *_scene;
-};
-
-class MoveCommand : public GraphUpdateCommand
-{
-public:
- explicit MoveCommand(TikzScene *scene,
- QMap<Node*,QPointF> oldNodePositions,
- QMap<Node*,QPointF> newNodePositions,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- QMap<Node*,QPointF> _oldNodePositions;
- QMap<Node*,QPointF> _newNodePositions;
-};
-
-class EdgeBendCommand : public GraphUpdateCommand
-{
-public:
- explicit EdgeBendCommand(TikzScene *scene, Edge *edge,
- float oldWeight, int oldBend,
- int oldInAngle, int oldOutAngle,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Edge *_edge;
- float _oldWeight;
- int _oldBend;
- int _oldInAngle;
- int _oldOutAngle;
- float _newWeight;
- int _newBend;
- int _newInAngle;
- int _newOutAngle;
-};
-
-class DeleteCommand : public GraphUpdateCommand
-{
-public:
- explicit DeleteCommand(TikzScene *scene,
- QMap<int,Node*> deleteNodes,
- QMap<int,Edge*> deleteEdges,
- QSet<Edge*> selEdges,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- QMap<int,Node*> _deleteNodes;
- QMap<int,Edge*> _deleteEdges;
- QSet<Edge*> _selEdges;
-};
-
-class AddNodeCommand : public GraphUpdateCommand
-{
-public:
- explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Node *_node;
- QRectF _oldBounds;
- QRectF _newBounds;
-};
-
-class AddEdgeCommand : public GraphUpdateCommand
-{
-public:
- explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Edge *_edge;
-};
-
-class ChangeEdgeModeCommand : public GraphUpdateCommand
-{
-public:
- explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Edge *_edge;
-};
-
-class ApplyStyleToNodesCommand : public GraphUpdateCommand
-{
-public:
- explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- QString _style;
- QMap<Node*,QString> _oldStyles;
-};
-
-class ApplyStyleToEdgesCommand : public GraphUpdateCommand
-{
-public:
- explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- QString _style;
- QMap<Edge*, QString> _oldStyles;
-};
-
-class PasteCommand : public GraphUpdateCommand
-{
-public:
- explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Graph *_graph;
- QSet<Node*> _oldSelectedNodes;
- QSet<Edge*> _oldSelectedEdges;
-};
-
-class ChangeLabelCommand : public GraphUpdateCommand
-{
-public:
- explicit ChangeLabelCommand(TikzScene *scene,
- Graph *graph,
- QMap<Node*,QString> oldLabels,
- QString newLabel,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Graph *_graph;
- QMap<Node*,QString> _oldLabels;
- QString _newLabel;
-};
-
-class ReplaceGraphCommand : public GraphUpdateCommand
-{
-public:
- explicit ReplaceGraphCommand(TikzScene *scene,
- Graph *oldGraph,
- Graph *newGraph,
- QUndoCommand *parent = 0);
- void undo() override;
- void redo() override;
-private:
- Graph *_oldGraph;
- Graph *_newGraph;
-};
-
-#endif // UNDOCOMMANDS_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * \file undocommands.h
+ *
+ * All changes to a TikzDocument are done via subclasses of QUndoCommand. When a controller
+ * (e.g. TikzScene) gets input from the user to change the document, it will push one of
+ * these commands onto the TikzDocument's undo stack, which automatically calls the redo()
+ * method of the command.
+ */
+
+#ifndef UNDOCOMMANDS_H
+#define UNDOCOMMANDS_H
+
+#include "tikzscene.h"
+
+#include <QUndoCommand>
+#include <QSet>
+
+class GraphUpdateCommand : public QUndoCommand {
+public:
+ explicit GraphUpdateCommand(TikzScene *scene,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+protected:
+ TikzScene *_scene;
+};
+
+class MoveCommand : public GraphUpdateCommand
+{
+public:
+ explicit MoveCommand(TikzScene *scene,
+ QMap<Node*,QPointF> oldNodePositions,
+ QMap<Node*,QPointF> newNodePositions,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QMap<Node*,QPointF> _oldNodePositions;
+ QMap<Node*,QPointF> _newNodePositions;
+};
+
+class EdgeBendCommand : public GraphUpdateCommand
+{
+public:
+ explicit EdgeBendCommand(TikzScene *scene, Edge *edge,
+ float oldWeight, int oldBend,
+ int oldInAngle, int oldOutAngle,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+ float _oldWeight;
+ int _oldBend;
+ int _oldInAngle;
+ int _oldOutAngle;
+ float _newWeight;
+ int _newBend;
+ int _newInAngle;
+ int _newOutAngle;
+};
+
+class DeleteCommand : public GraphUpdateCommand
+{
+public:
+ explicit DeleteCommand(TikzScene *scene,
+ QMap<int,Node*> deleteNodes,
+ QMap<int,Edge*> deleteEdges,
+ QSet<Edge*> selEdges,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QMap<int,Node*> _deleteNodes;
+ QMap<int,Edge*> _deleteEdges;
+ QSet<Edge*> _selEdges;
+};
+
+class AddNodeCommand : public GraphUpdateCommand
+{
+public:
+ explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Node *_node;
+ QRectF _oldBounds;
+ QRectF _newBounds;
+};
+
+class AddEdgeCommand : public GraphUpdateCommand
+{
+public:
+ explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+};
+
+class ChangeEdgeModeCommand : public GraphUpdateCommand
+{
+public:
+ explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+};
+
+class ApplyStyleToNodesCommand : public GraphUpdateCommand
+{
+public:
+ explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QString _style;
+ QMap<Node*,QString> _oldStyles;
+};
+
+class ApplyStyleToEdgesCommand : public GraphUpdateCommand
+{
+public:
+ explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QString _style;
+ QMap<Edge*, QString> _oldStyles;
+};
+
+class PasteCommand : public GraphUpdateCommand
+{
+public:
+ explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_graph;
+ QSet<Node*> _oldSelectedNodes;
+ QSet<Edge*> _oldSelectedEdges;
+};
+
+class ChangeLabelCommand : public GraphUpdateCommand
+{
+public:
+ explicit ChangeLabelCommand(TikzScene *scene,
+ Graph *graph,
+ QMap<Node*,QString> oldLabels,
+ QString newLabel,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_graph;
+ QMap<Node*,QString> _oldLabels;
+ QString _newLabel;
+};
+
+class ReplaceGraphCommand : public GraphUpdateCommand
+{
+public:
+ explicit ReplaceGraphCommand(TikzScene *scene,
+ Graph *oldGraph,
+ Graph *newGraph,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_oldGraph;
+ Graph *_newGraph;
+};
+
+#endif // UNDOCOMMANDS_H
diff --git a/src/main.cpp b/src/main.cpp
index 4d6f9a7..f36cad3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,48 +1,48 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-
-/*!
- * \file main.cpp
- *
- * The main entry point for the TikZiT executable.
- */
-
-#include "tikzit.h"
-
-#include <QApplication>
-#include <QMenuBar>
-
-
-
-int main(int argc, char *argv[])
-{
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- //QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
- QApplication a(argc, argv);
- a.setQuitOnLastWindowClosed(false);
- tikzit = new Tikzit();
- tikzit->init(&a);
-
- if (a.arguments().length() > 1) {
- tikzit->open(a.arguments()[1]);
- }
-
- return a.exec();
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+
+/*!
+ * \file main.cpp
+ *
+ * The main entry point for the TikZiT executable.
+ */
+
+#include "tikzit.h"
+
+#include <QApplication>
+#include <QMenuBar>
+
+
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ //QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+ QApplication a(argc, argv);
+ a.setQuitOnLastWindowClosed(false);
+ tikzit = new Tikzit();
+ tikzit->init(&a);
+
+ if (a.arguments().length() > 1) {
+ tikzit->open(a.arguments()[1]);
+ }
+
+ return a.exec();
+}
diff --git a/src/test/testmain.cpp b/src/test/testmain.cpp
index 56491ed..30e5f6d 100644
--- a/src/test/testmain.cpp
+++ b/src/test/testmain.cpp
@@ -1,22 +1,22 @@
-#include "testtest.h"
-#include "testparser.h"
-#include "testtikzoutput.h"
-
-#include <QTest>
-#include <QDebug>
-#include <iostream>
-
-int main(int argc, char *argv[])
-{
- TestTest test;
- TestParser parser;
- TestTikzOutput tikzOutput;
- int r = QTest::qExec(&test, argc, argv) |
- QTest::qExec(&parser, argc, argv) |
- QTest::qExec(&tikzOutput, argc, argv);
-
- if (r == 0) std::cout << "***************** All tests passed! *****************\n";
- else std::cout << "***************** Some tests failed. *****************\n";
-
- return r;
-}
+#include "testtest.h"
+#include "testparser.h"
+#include "testtikzoutput.h"
+
+#include <QTest>
+#include <QDebug>
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ TestTest test;
+ TestParser parser;
+ TestTikzOutput tikzOutput;
+ int r = QTest::qExec(&test, argc, argv) |
+ QTest::qExec(&parser, argc, argv) |
+ QTest::qExec(&tikzOutput, argc, argv);
+
+ if (r == 0) std::cout << "***************** All tests passed! *****************\n";
+ else std::cout << "***************** Some tests failed. *****************\n";
+
+ return r;
+}
diff --git a/src/test/testparser.cpp b/src/test/testparser.cpp
index 284930e..85afe95 100644
--- a/src/test/testparser.cpp
+++ b/src/test/testparser.cpp
@@ -1,163 +1,163 @@
-#include "testparser.h"
-#include "graph.h"
-#include "tikzassembler.h"
-
-#include <QTest>
-#include <QVector>
-
-//void TestParser::initTestCase()
-//{
-
-//}
-
-//void TestParser::cleanupTestCase()
-//{
-
-//}
-
-void TestParser::parseEmptyGraph()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse("\\begin{tikzpicture}\n\\end{tikzpicture}");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 0);
- QVERIFY(g->edges().size() == 0);
- delete g;
-}
-
-void TestParser::parseNodeGraph()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse(
- "\\begin{tikzpicture}\n"
- " \\node (node0) at (1.1, -2.2) {};\n"
- " \\node (node1) at (3, 4) {test};\n"
- "\\end{tikzpicture}");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 2);
- QVERIFY(g->edges().size() == 0);
- QVERIFY(g->nodes()[0]->name() == "node0");
- QVERIFY(g->nodes()[0]->label() == "");
- QVERIFY(g->nodes()[0]->point() == QPointF(1.1,-2.2));
- QVERIFY(g->nodes()[1]->name() == "node1");
- QVERIFY(g->nodes()[1]->label() == "test");
- QVERIFY(g->nodes()[1]->point() == QPointF(3,4));
- delete g;
-}
-
-void TestParser::parseEdgeGraph()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse(
- "\\begin{tikzpicture}\n"
- " \\begin{pgfonlayer}{nodelayer}\n"
- " \\node [style=x, {foo++}] (0) at (-1, -1) {};\n"
- " \\node [style=y] (1) at (0, 1) {};\n"
- " \\node [style=z] (2) at (1, -1) {};\n"
- " \\end{pgfonlayer}\n"
- " \\begin{pgfonlayer}{edgelayer}\n"
- " \\draw [style=a] (1.center) to (2);\n"
- " \\draw [style=b, foo] (2) to (0.west);\n"
- " \\draw [style=c] (0) to (1);\n"
- " \\end{pgfonlayer}\n"
- "\\end{tikzpicture}\n");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 3);
- QVERIFY(g->edges().size() == 3);
- QVERIFY(g->nodes()[0]->data()->atom("foo++"));
- QVERIFY(g->edges()[0]->data()->property("style") == "a");
- QVERIFY(!g->edges()[0]->data()->atom("foo"));
- QVERIFY(g->edges()[1]->data()->property("style") == "b");
- QVERIFY(g->edges()[1]->data()->atom("foo"));
- QVERIFY(g->edges()[2]->data()->property("style") == "c");
- Node *en = g->edges()[0]->edgeNode();
- QVERIFY(en == 0);
- delete g;
-}
-
-void TestParser::parseEdgeNode()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse(
- "\\begin{tikzpicture}\n"
- " \\begin{pgfonlayer}{nodelayer}\n"
- " \\node [style=none] (0) at (-1, 0) {};\n"
- " \\node [style=none] (1) at (1, 0) {};\n"
- " \\end{pgfonlayer}\n"
- " \\begin{pgfonlayer}{edgelayer}\n"
- " \\draw [style=diredge] (0.center) to node[foo, bar=baz baz]{test} (1.center);\n"
- " \\end{pgfonlayer}\n"
- "\\end{tikzpicture}\n");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 2);
- QVERIFY(g->edges().size() == 1);
- Node *en = g->edges()[0]->edgeNode();
- QVERIFY(en != 0);
- QVERIFY(en->label() == "test");
- QVERIFY(en->data()->atom("foo"));
- QVERIFY(en->data()->property("bar") == "baz baz");
- delete g;
-}
-
-void TestParser::parseEdgeBends()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse(
- "\\begin{tikzpicture}\n"
- " \\begin{pgfonlayer}{nodelayer}\n"
- " \\node [style=white] (0) at (-1, 0) {};\n"
- " \\node [style=black] (1) at (1, 0) {};\n"
- " \\end{pgfonlayer}\n"
- " \\begin{pgfonlayer}{edgelayer}\n"
- " \\draw [style=diredge,bend left] (0) to (1);\n"
- " \\draw [style=diredge,bend right] (0) to (1);\n"
- " \\draw [style=diredge,bend left=20] (0) to (1);\n"
- " \\draw [style=diredge,bend right=80] (0) to (1);\n"
- " \\draw [style=diredge,in=10,out=150,looseness=2] (0) to (1);\n"
- " \\end{pgfonlayer}\n"
- "\\end{tikzpicture}\n");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 2);
- QVERIFY(g->edges().size() == 5);
- QVERIFY(g->edges()[0]->bend() == -30);
- QVERIFY(g->edges()[1]->bend() == 30);
- QVERIFY(g->edges()[2]->bend() == -20);
- QVERIFY(g->edges()[3]->bend() == 80);
- QVERIFY(g->edges()[4]->inAngle() == 10);
- QVERIFY(g->edges()[4]->outAngle() == 150);
- QVERIFY(g->edges()[4]->weight() == 2.0f/2.5f);
-}
-
-void TestParser::parseBbox()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
- bool res = ga.parse(
- "\\begin{tikzpicture}\n"
- " \\path [use as bounding box] (-1.5,-1.5) rectangle (1.5,1.5);\n"
- " \\begin{pgfonlayer}{nodelayer}\n"
- " \\node [style=white dot] (0) at (-1, -1) {};\n"
- " \\node [style=white dot] (1) at (0, 1) {};\n"
- " \\node [style=white dot] (2) at (1, -1) {};\n"
- " \\end{pgfonlayer}\n"
- " \\begin{pgfonlayer}{edgelayer}\n"
- " \\draw [style=diredge] (1) to (2);\n"
- " \\draw [style=diredge] (2) to (0);\n"
- " \\draw [style=diredge] (0) to (1);\n"
- " \\end{pgfonlayer}\n"
- "\\end{tikzpicture}\n");
- QVERIFY(res);
- QVERIFY(g->nodes().size() == 3);
- QVERIFY(g->edges().size() == 3);
- QVERIFY(g->hasBbox());
- QVERIFY(g->bbox() == QRectF(QPointF(-1.5,-1.5), QPointF(1.5,1.5)));
-
- delete g;
-}
-
-
+#include "testparser.h"
+#include "graph.h"
+#include "tikzassembler.h"
+
+#include <QTest>
+#include <QVector>
+
+//void TestParser::initTestCase()
+//{
+
+//}
+
+//void TestParser::cleanupTestCase()
+//{
+
+//}
+
+void TestParser::parseEmptyGraph()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse("\\begin{tikzpicture}\n\\end{tikzpicture}");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 0);
+ QVERIFY(g->edges().size() == 0);
+ delete g;
+}
+
+void TestParser::parseNodeGraph()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\node (node0) at (1.1, -2.2) {};\n"
+ " \\node (node1) at (3, 4) {test};\n"
+ "\\end{tikzpicture}");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 2);
+ QVERIFY(g->edges().size() == 0);
+ QVERIFY(g->nodes()[0]->name() == "node0");
+ QVERIFY(g->nodes()[0]->label() == "");
+ QVERIFY(g->nodes()[0]->point() == QPointF(1.1,-2.2));
+ QVERIFY(g->nodes()[1]->name() == "node1");
+ QVERIFY(g->nodes()[1]->label() == "test");
+ QVERIFY(g->nodes()[1]->point() == QPointF(3,4));
+ delete g;
+}
+
+void TestParser::parseEdgeGraph()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=x, {foo++}] (0) at (-1, -1) {};\n"
+ " \\node [style=y] (1) at (0, 1) {};\n"
+ " \\node [style=z] (2) at (1, -1) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=a] (1.center) to (2);\n"
+ " \\draw [style=b, foo] (2) to (0.west);\n"
+ " \\draw [style=c] (0) to (1);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 3);
+ QVERIFY(g->edges().size() == 3);
+ QVERIFY(g->nodes()[0]->data()->atom("foo++"));
+ QVERIFY(g->edges()[0]->data()->property("style") == "a");
+ QVERIFY(!g->edges()[0]->data()->atom("foo"));
+ QVERIFY(g->edges()[1]->data()->property("style") == "b");
+ QVERIFY(g->edges()[1]->data()->atom("foo"));
+ QVERIFY(g->edges()[2]->data()->property("style") == "c");
+ Node *en = g->edges()[0]->edgeNode();
+ QVERIFY(en == 0);
+ delete g;
+}
+
+void TestParser::parseEdgeNode()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=none] (0) at (-1, 0) {};\n"
+ " \\node [style=none] (1) at (1, 0) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=diredge] (0.center) to node[foo, bar=baz baz]{test} (1.center);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 2);
+ QVERIFY(g->edges().size() == 1);
+ Node *en = g->edges()[0]->edgeNode();
+ QVERIFY(en != 0);
+ QVERIFY(en->label() == "test");
+ QVERIFY(en->data()->atom("foo"));
+ QVERIFY(en->data()->property("bar") == "baz baz");
+ delete g;
+}
+
+void TestParser::parseEdgeBends()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=white] (0) at (-1, 0) {};\n"
+ " \\node [style=black] (1) at (1, 0) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=diredge,bend left] (0) to (1);\n"
+ " \\draw [style=diredge,bend right] (0) to (1);\n"
+ " \\draw [style=diredge,bend left=20] (0) to (1);\n"
+ " \\draw [style=diredge,bend right=80] (0) to (1);\n"
+ " \\draw [style=diredge,in=10,out=150,looseness=2] (0) to (1);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 2);
+ QVERIFY(g->edges().size() == 5);
+ QVERIFY(g->edges()[0]->bend() == -30);
+ QVERIFY(g->edges()[1]->bend() == 30);
+ QVERIFY(g->edges()[2]->bend() == -20);
+ QVERIFY(g->edges()[3]->bend() == 80);
+ QVERIFY(g->edges()[4]->inAngle() == 10);
+ QVERIFY(g->edges()[4]->outAngle() == 150);
+ QVERIFY(g->edges()[4]->weight() == 2.0f/2.5f);
+}
+
+void TestParser::parseBbox()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\path [use as bounding box] (-1.5,-1.5) rectangle (1.5,1.5);\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=white dot] (0) at (-1, -1) {};\n"
+ " \\node [style=white dot] (1) at (0, 1) {};\n"
+ " \\node [style=white dot] (2) at (1, -1) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=diredge] (1) to (2);\n"
+ " \\draw [style=diredge] (2) to (0);\n"
+ " \\draw [style=diredge] (0) to (1);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 3);
+ QVERIFY(g->edges().size() == 3);
+ QVERIFY(g->hasBbox());
+ QVERIFY(g->bbox() == QRectF(QPointF(-1.5,-1.5), QPointF(1.5,1.5)));
+
+ delete g;
+}
+
+
diff --git a/src/test/testparser.h b/src/test/testparser.h
index a40a58f..a59647d 100644
--- a/src/test/testparser.h
+++ b/src/test/testparser.h
@@ -1,18 +1,18 @@
-#ifndef TESTPARSER_H
-#define TESTPARSER_H
-
-#include <QObject>
-
-class TestParser : public QObject
-{
- Q_OBJECT
-private slots:
- void parseEmptyGraph();
- void parseNodeGraph();
- void parseEdgeGraph();
- void parseEdgeNode();
- void parseEdgeBends();
- void parseBbox();
-};
-
-#endif // TESTPARSER_H
+#ifndef TESTPARSER_H
+#define TESTPARSER_H
+
+#include <QObject>
+
+class TestParser : public QObject
+{
+ Q_OBJECT
+private slots:
+ void parseEmptyGraph();
+ void parseNodeGraph();
+ void parseEdgeGraph();
+ void parseEdgeNode();
+ void parseEdgeBends();
+ void parseBbox();
+};
+
+#endif // TESTPARSER_H
diff --git a/src/test/testtest.cpp b/src/test/testtest.cpp
index 59173c0..7f8d8cb 100644
--- a/src/test/testtest.cpp
+++ b/src/test/testtest.cpp
@@ -1,10 +1,10 @@
-#include "testtest.h"
-
-#include <QObject>
-#include <QTest>
-
-void TestTest::initTestCase() { qDebug("initialising test"); }
-void TestTest::myFirstTest() { QVERIFY(1 == 1); }
-void TestTest::mySecondTest() { QVERIFY(1 != 2); }
-void TestTest::cleanupTestCase() { qDebug("cleaning up test"); }
-
+#include "testtest.h"
+
+#include <QObject>
+#include <QTest>
+
+void TestTest::initTestCase() { qDebug("initialising test"); }
+void TestTest::myFirstTest() { QVERIFY(1 == 1); }
+void TestTest::mySecondTest() { QVERIFY(1 != 2); }
+void TestTest::cleanupTestCase() { qDebug("cleaning up test"); }
+
diff --git a/src/test/testtest.h b/src/test/testtest.h
index 69a0bc8..a94dd41 100644
--- a/src/test/testtest.h
+++ b/src/test/testtest.h
@@ -1,17 +1,17 @@
-#ifndef TESTTEST_H
-#define TESTTEST_H
-
-#include <QObject>
-#include <QTest>
-
-class TestTest: public QObject
-{
- Q_OBJECT
-private slots:
- void initTestCase();
- void myFirstTest();
- void mySecondTest();
- void cleanupTestCase();
-};
-
-#endif // TESTTEST_H
+#ifndef TESTTEST_H
+#define TESTTEST_H
+
+#include <QObject>
+#include <QTest>
+
+class TestTest: public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void myFirstTest();
+ void mySecondTest();
+ void cleanupTestCase();
+};
+
+#endif // TESTTEST_H
diff --git a/src/test/testtikzoutput.cpp b/src/test/testtikzoutput.cpp
index 1c25439..d7ec32a 100644
--- a/src/test/testtikzoutput.cpp
+++ b/src/test/testtikzoutput.cpp
@@ -1,97 +1,97 @@
-#include "testtikzoutput.h"
-#include "graphelementproperty.h"
-#include "graphelementdata.h"
-#include "graph.h"
-#include "tikzassembler.h"
-
-#include <QTest>
-#include <QRectF>
-#include <QPointF>
-
-void TestTikzOutput::escape()
-{
- QVERIFY(GraphElementProperty::tikzEscape("foo") == "foo");
- QVERIFY(GraphElementProperty::tikzEscape("foo'") == "foo'");
- QVERIFY(GraphElementProperty::tikzEscape("foo bar") == "foo bar");
- QVERIFY(GraphElementProperty::tikzEscape("foo.bar") == "foo.bar");
- QVERIFY(GraphElementProperty::tikzEscape("foo-bar") == "foo-bar");
- QVERIFY(GraphElementProperty::tikzEscape("foo >") == "foo >");
- QVERIFY(GraphElementProperty::tikzEscape("foo <") == "foo <");
- QVERIFY(GraphElementProperty::tikzEscape("foo+") == "{foo+}");
- QVERIFY(GraphElementProperty::tikzEscape("foo{bar}") == "{foo{bar}}");
-}
-
-void TestTikzOutput::data()
-{
- GraphElementData d;
- QVERIFY(d.tikz() == "");
- d.setAtom("foo");
- QVERIFY(d.tikz() == "[foo]");
- d.setAtom("bar");
- QVERIFY(d.tikz() == "[foo, bar]");
- d.setProperty("foo","bar");
- QVERIFY(d.tikz() == "[foo, bar, foo=bar]");
- d.setAtom("foo+");
- QVERIFY(d.tikz() == "[foo, bar, foo=bar, {foo+}]");
- d.unsetAtom("foo");
- QVERIFY(d.tikz() == "[bar, foo=bar, {foo+}]");
- d.unsetProperty("foo");
- QVERIFY(d.tikz() == "[bar, {foo+}]");
- d.unsetAtom("foo+");
- QVERIFY(d.tikz() == "[bar]");
- d.unsetAtom("bar");
- QVERIFY(d.tikz() == "");
-}
-
-void TestTikzOutput::graphEmpty()
-{
- Graph *g = new Graph();
-
- QString tikz =
- "\\begin{tikzpicture}\n"
- "\\end{tikzpicture}\n";
- QVERIFY(g->tikz() == tikz);
-
- delete g;
-}
-
-void TestTikzOutput::graphFromTikz()
-{
- Graph *g = new Graph();
- TikzAssembler ga(g);
-
- QString tikz =
- "\\begin{tikzpicture}\n"
- "\t\\path [use as bounding box] (-1.5,-1.5) rectangle (1.5,1.5);\n"
- "\t\\begin{pgfonlayer}{nodelayer}\n"
- "\t\t\\node [style=white dot] (0) at (-1, -1) {};\n"
- "\t\t\\node [style=white dot] (1) at (0, 1) {};\n"
- "\t\t\\node [style=white dot] (2) at (1, -1) {};\n"
- "\t\\end{pgfonlayer}\n"
- "\t\\begin{pgfonlayer}{edgelayer}\n"
- "\t\t\\draw [style=diredge] (1) to (2);\n"
- "\t\t\\draw [style=diredge] (2.center) to (0);\n"
- "\t\t\\draw [style=diredge] (0) to ();\n"
- "\t\\end{pgfonlayer}\n"
- "\\end{tikzpicture}\n";
- bool res = ga.parse(tikz);
- QVERIFY2(res, "parsed successfully");
- QVERIFY2(g->tikz() == tikz, "produced matching tikz");
-
- delete g;
-}
-
-void TestTikzOutput::graphBbox()
-{
- Graph *g = new Graph();
- g->setBbox(QRectF(QPointF(-0.75, -0.5), QPointF(0.25, 1)));
-
- QString tikz =
- "\\begin{tikzpicture}\n"
- "\t\\path [use as bounding box] (-0.75,-0.5) rectangle (0.25,1);\n"
- "\\end{tikzpicture}\n";
- QVERIFY(g->tikz() == tikz);
-
-
- delete g;
-}
+#include "testtikzoutput.h"
+#include "graphelementproperty.h"
+#include "graphelementdata.h"
+#include "graph.h"
+#include "tikzassembler.h"
+
+#include <QTest>
+#include <QRectF>
+#include <QPointF>
+
+void TestTikzOutput::escape()
+{
+ QVERIFY(GraphElementProperty::tikzEscape("foo") == "foo");
+ QVERIFY(GraphElementProperty::tikzEscape("foo'") == "foo'");
+ QVERIFY(GraphElementProperty::tikzEscape("foo bar") == "foo bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo.bar") == "foo.bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo-bar") == "foo-bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo >") == "foo >");
+ QVERIFY(GraphElementProperty::tikzEscape("foo <") == "foo <");
+ QVERIFY(GraphElementProperty::tikzEscape("foo+") == "{foo+}");
+ QVERIFY(GraphElementProperty::tikzEscape("foo{bar}") == "{foo{bar}}");
+}
+
+void TestTikzOutput::data()
+{
+ GraphElementData d;
+ QVERIFY(d.tikz() == "");
+ d.setAtom("foo");
+ QVERIFY(d.tikz() == "[foo]");
+ d.setAtom("bar");
+ QVERIFY(d.tikz() == "[foo, bar]");
+ d.setProperty("foo","bar");
+ QVERIFY(d.tikz() == "[foo, bar, foo=bar]");
+ d.setAtom("foo+");
+ QVERIFY(d.tikz() == "[foo, bar, foo=bar, {foo+}]");
+ d.unsetAtom("foo");
+ QVERIFY(d.tikz() == "[bar, foo=bar, {foo+}]");
+ d.unsetProperty("foo");
+ QVERIFY(d.tikz() == "[bar, {foo+}]");
+ d.unsetAtom("foo+");
+ QVERIFY(d.tikz() == "[bar]");
+ d.unsetAtom("bar");
+ QVERIFY(d.tikz() == "");
+}
+
+void TestTikzOutput::graphEmpty()
+{
+ Graph *g = new Graph();
+
+ QString tikz =
+ "\\begin{tikzpicture}\n"
+ "\\end{tikzpicture}\n";
+ QVERIFY(g->tikz() == tikz);
+
+ delete g;
+}
+
+void TestTikzOutput::graphFromTikz()
+{
+ Graph *g = new Graph();
+ TikzAssembler ga(g);
+
+ QString tikz =
+ "\\begin{tikzpicture}\n"
+ "\t\\path [use as bounding box] (-1.5,-1.5) rectangle (1.5,1.5);\n"
+ "\t\\begin{pgfonlayer}{nodelayer}\n"
+ "\t\t\\node [style=white dot] (0) at (-1, -1) {};\n"
+ "\t\t\\node [style=white dot] (1) at (0, 1) {};\n"
+ "\t\t\\node [style=white dot] (2) at (1, -1) {};\n"
+ "\t\\end{pgfonlayer}\n"
+ "\t\\begin{pgfonlayer}{edgelayer}\n"
+ "\t\t\\draw [style=diredge] (1) to (2);\n"
+ "\t\t\\draw [style=diredge] (2.center) to (0);\n"
+ "\t\t\\draw [style=diredge] (0) to ();\n"
+ "\t\\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n";
+ bool res = ga.parse(tikz);
+ QVERIFY2(res, "parsed successfully");
+ QVERIFY2(g->tikz() == tikz, "produced matching tikz");
+
+ delete g;
+}
+
+void TestTikzOutput::graphBbox()
+{
+ Graph *g = new Graph();
+ g->setBbox(QRectF(QPointF(-0.75, -0.5), QPointF(0.25, 1)));
+
+ QString tikz =
+ "\\begin{tikzpicture}\n"
+ "\t\\path [use as bounding box] (-0.75,-0.5) rectangle (0.25,1);\n"
+ "\\end{tikzpicture}\n";
+ QVERIFY(g->tikz() == tikz);
+
+
+ delete g;
+}
diff --git a/src/test/testtikzoutput.h b/src/test/testtikzoutput.h
index dff1db1..f4949f5 100644
--- a/src/test/testtikzoutput.h
+++ b/src/test/testtikzoutput.h
@@ -1,17 +1,17 @@
-#ifndef TESTTIKZOUTPUT_H
-#define TESTTIKZOUTPUT_H
-
-#include <QObject>
-
-class TestTikzOutput : public QObject
-{
- Q_OBJECT
-private slots:
- void escape();
- void data();
- void graphBbox();
- void graphEmpty();
- void graphFromTikz();
-};
-
-#endif // TESTTIKZOUTPUT_H
+#ifndef TESTTIKZOUTPUT_H
+#define TESTTIKZOUTPUT_H
+
+#include <QObject>
+
+class TestTikzOutput : public QObject
+{
+ Q_OBJECT
+private slots:
+ void escape();
+ void data();
+ void graphBbox();
+ void graphEmpty();
+ void graphFromTikz();
+};
+
+#endif // TESTTIKZOUTPUT_H
diff --git a/src/tikzit.cpp b/src/tikzit.cpp
index 9a4e166..e4b3b95 100644
--- a/src/tikzit.cpp
+++ b/src/tikzit.cpp
@@ -1,211 +1,211 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "tikzit.h"
-#include "tikzassembler.h"
-#include "tikzstyles.h"
-
-#include <QFile>
-#include <QFileDialog>
-#include <QSettings>
-#include <QDebug>
-#include <QMessageBox>
-
-// application-level instance of Tikzit
-Tikzit *tikzit;
-
-// font to use for node labels
-QFont Tikzit::LABEL_FONT("Courrier", 9);
-
-Tikzit::Tikzit() : _styleFile("[default]"), _activeWindow(0)
-{
-}
-
-void Tikzit::init(QApplication *app)
-{
- QSettings settings("tikzit", "tikzit");
- _mainMenu = new MainMenu();
- QMainWindow *dummy = new QMainWindow();
-
- _toolPalette = new ToolPalette(dummy);
- _propertyPalette = new PropertyPalette(dummy);
- //_stylePalette = new StylePalette(dummy);
- _styles = new TikzStyles(this);
-
- //_stylePalette->show();
- _windows << new MainWindow();
- _windows[0]->show();
-
- QString styleFile = settings.value("previous-tikzstyles-file").toString();
- if (!styleFile.isEmpty()) loadStyles(styleFile);
-
- //connect(app, &QApplication::focusChanged, this, &focusChanged);
-}
-
-//QMenuBar *Tikzit::mainMenu() const
-//{
-// return _mainMenu;
-//}
-
-ToolPalette *Tikzit::toolPalette() const
-{
- return _toolPalette;
-}
-
-PropertyPalette *Tikzit::propertyPalette() const
-{
- return _propertyPalette;
-}
-
-void Tikzit::newDoc()
-{
- MainWindow *w = new MainWindow();
- w->show();
- _windows << w;
-}
-
-MainWindow *Tikzit::activeWindow() const
-{
- return _activeWindow;
-}
-
-void Tikzit::setActiveWindow(MainWindow *activeWindow)
-{
- _activeWindow = activeWindow;
-}
-
-void Tikzit::removeWindow(MainWindow *w)
-{
- _windows.removeAll(w);
- if (_activeWindow == w) {
- if (_windows.isEmpty()) {
- _activeWindow = 0;
- // TODO: check if we should quit when last window closed
- quit();
- } else _activeWindow = _windows[0];
- }
-}
-
-void Tikzit::open()
-{
- QSettings settings("tikzit", "tikzit");
- QString fileName = QFileDialog::getOpenFileName(0,
- tr("Open File"),
- settings.value("previous-file-path").toString(),
- tr("TiKZ Files (*.tikz)"));
-
- open(fileName);
-}
-
-void Tikzit::open(QString fileName)
-{
- if (!fileName.isEmpty()) {
- if (_windows.size() == 1 &&
- _windows[0]->tikzDocument()->isClean() &&
- _windows[0]->tikzDocument()->shortName().isEmpty())
- {
- _windows[0]->open(fileName);
- _windows[0]->show();
- }
- else {
- MainWindow *w = new MainWindow();
- w->show();
- w->open(fileName);
- _windows << w;
- }
- }
-}
-
-void Tikzit::openTikzStyles() {
- QSettings settings("tikzit", "tikzit");
- QString fileName = QFileDialog::getOpenFileName(0,
- tr("Open File"),
- settings.value("previous-tikzstyles-path").toString(),
- tr("TiKZ Style Files (*.tikzstyles)"));
-
- if (!fileName.isEmpty()) {
- loadStyles(fileName);
- }
-}
-
-void Tikzit::loadStyles(QString fileName)
-{
- QSettings settings("tikzit", "tikzit");
- QFile file(fileName);
- if (file.open(QIODevice::ReadOnly)) {
- QFileInfo fi(file);
- settings.setValue("previous-tikzstyles-path", fi.absolutePath());
- settings.setValue("previous-tikzstyles-file", fileName);
- _styleFile = fi.fileName();
- QTextStream in(&file);
- QString styleTikz = in.readAll();
- file.close();
-
- _styles->clear();
- TikzAssembler ass(_styles);
- bool parseSuccess = ass.parse(styleTikz);
- if (parseSuccess) {
- qDebug() << "parse successful";
- } else {
- qDebug() << "parse failed";
- }
- //_stylePalette->reloadStyles();
-
- foreach (MainWindow *w, _windows) {
- w->tikzScene()->reloadStyles();
- }
-
- } else {
- settings.setValue("previous-tikzstyles-file", "");
- QMessageBox::warning(0, "Style file not found.", "Could not open style file: '" + fileName + "', reverting to default.");
- }
-}
-
-QString Tikzit::styleFile() const
-{
- return _styleFile;
-}
-
-void Tikzit::focusChanged(QWidget *old, QWidget *nw)
-{
-// foreach (MainWindow *w, _windows) {
-// if (w->isActiveWindow()) {
-// _stylePalette->raise();
-// break;
-// }
-// }
-}
-
-//StylePalette *Tikzit::stylePalette() const
-//{
-// return _stylePalette;
-//}
-
-
-TikzStyles *Tikzit::styles() const
-{
- return _styles;
-}
-
-void Tikzit::quit()
-{
- //_stylePalette->close();
- QApplication::quit();
-}
-
-
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "tikzassembler.h"
+#include "tikzstyles.h"
+
+#include <QFile>
+#include <QFileDialog>
+#include <QSettings>
+#include <QDebug>
+#include <QMessageBox>
+
+// application-level instance of Tikzit
+Tikzit *tikzit;
+
+// font to use for node labels
+QFont Tikzit::LABEL_FONT("Courrier", 9);
+
+Tikzit::Tikzit() : _styleFile("[default]"), _activeWindow(0)
+{
+}
+
+void Tikzit::init(QApplication *app)
+{
+ QSettings settings("tikzit", "tikzit");
+ _mainMenu = new MainMenu();
+ QMainWindow *dummy = new QMainWindow();
+
+ _toolPalette = new ToolPalette(dummy);
+ _propertyPalette = new PropertyPalette(dummy);
+ //_stylePalette = new StylePalette(dummy);
+ _styles = new TikzStyles(this);
+
+ //_stylePalette->show();
+ _windows << new MainWindow();
+ _windows[0]->show();
+
+ QString styleFile = settings.value("previous-tikzstyles-file").toString();
+ if (!styleFile.isEmpty()) loadStyles(styleFile);
+
+ //connect(app, &QApplication::focusChanged, this, &focusChanged);
+}
+
+//QMenuBar *Tikzit::mainMenu() const
+//{
+// return _mainMenu;
+//}
+
+ToolPalette *Tikzit::toolPalette() const
+{
+ return _toolPalette;
+}
+
+PropertyPalette *Tikzit::propertyPalette() const
+{
+ return _propertyPalette;
+}
+
+void Tikzit::newDoc()
+{
+ MainWindow *w = new MainWindow();
+ w->show();
+ _windows << w;
+}
+
+MainWindow *Tikzit::activeWindow() const
+{
+ return _activeWindow;
+}
+
+void Tikzit::setActiveWindow(MainWindow *activeWindow)
+{
+ _activeWindow = activeWindow;
+}
+
+void Tikzit::removeWindow(MainWindow *w)
+{
+ _windows.removeAll(w);
+ if (_activeWindow == w) {
+ if (_windows.isEmpty()) {
+ _activeWindow = 0;
+ // TODO: check if we should quit when last window closed
+ quit();
+ } else _activeWindow = _windows[0];
+ }
+}
+
+void Tikzit::open()
+{
+ QSettings settings("tikzit", "tikzit");
+ QString fileName = QFileDialog::getOpenFileName(0,
+ tr("Open File"),
+ settings.value("previous-file-path").toString(),
+ tr("TiKZ Files (*.tikz)"));
+
+ open(fileName);
+}
+
+void Tikzit::open(QString fileName)
+{
+ if (!fileName.isEmpty()) {
+ if (_windows.size() == 1 &&
+ _windows[0]->tikzDocument()->isClean() &&
+ _windows[0]->tikzDocument()->shortName().isEmpty())
+ {
+ _windows[0]->open(fileName);
+ _windows[0]->show();
+ }
+ else {
+ MainWindow *w = new MainWindow();
+ w->show();
+ w->open(fileName);
+ _windows << w;
+ }
+ }
+}
+
+void Tikzit::openTikzStyles() {
+ QSettings settings("tikzit", "tikzit");
+ QString fileName = QFileDialog::getOpenFileName(0,
+ tr("Open File"),
+ settings.value("previous-tikzstyles-path").toString(),
+ tr("TiKZ Style Files (*.tikzstyles)"));
+
+ if (!fileName.isEmpty()) {
+ loadStyles(fileName);
+ }
+}
+
+void Tikzit::loadStyles(QString fileName)
+{
+ QSettings settings("tikzit", "tikzit");
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ QFileInfo fi(file);
+ settings.setValue("previous-tikzstyles-path", fi.absolutePath());
+ settings.setValue("previous-tikzstyles-file", fileName);
+ _styleFile = fi.fileName();
+ QTextStream in(&file);
+ QString styleTikz = in.readAll();
+ file.close();
+
+ _styles->clear();
+ TikzAssembler ass(_styles);
+ bool parseSuccess = ass.parse(styleTikz);
+ if (parseSuccess) {
+ qDebug() << "parse successful";
+ } else {
+ qDebug() << "parse failed";
+ }
+ //_stylePalette->reloadStyles();
+
+ foreach (MainWindow *w, _windows) {
+ w->tikzScene()->reloadStyles();
+ }
+
+ } else {
+ settings.setValue("previous-tikzstyles-file", "");
+ QMessageBox::warning(0, "Style file not found.", "Could not open style file: '" + fileName + "', reverting to default.");
+ }
+}
+
+QString Tikzit::styleFile() const
+{
+ return _styleFile;
+}
+
+void Tikzit::focusChanged(QWidget *old, QWidget *nw)
+{
+// foreach (MainWindow *w, _windows) {
+// if (w->isActiveWindow()) {
+// _stylePalette->raise();
+// break;
+// }
+// }
+}
+
+//StylePalette *Tikzit::stylePalette() const
+//{
+// return _stylePalette;
+//}
+
+
+TikzStyles *Tikzit::styles() const
+{
+ return _styles;
+}
+
+void Tikzit::quit()
+{
+ //_stylePalette->close();
+ QApplication::quit();
+}
+
+
diff --git a/src/tikzit.h b/src/tikzit.h
index 232a4aa..b450d3f 100644
--- a/src/tikzit.h
+++ b/src/tikzit.h
@@ -1,141 +1,141 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-
-/*!
- *
- * \mainpage TikZiT Documentation
- *
- * This is the source code documentation for TikZiT. The global entry point
- * for the TikZiT executable is in main.cpp, whereas the class Tikzit maintains
- * the global application state.
- *
- * The TikZ parser is implemented in flex/bison in the files tikzlexer.l and tikzparser.y.
- *
- * Most of the interesting code for handling user input is in the class TikzScene. Anything
- * that makes a change to the tikz file should be implemented as a QUndoCommand. Currently,
- * these are all in undocommands.h.
- *
- * I've basically been adding documentation as I go. Other bits and pieces can be accessed
- * by searching, or via the class list/class hierarchy links in the menu above.
- *
- */
-
-/*!
- *
- * \class Tikzit
- *
- * Tikzit is the top-level class which maintains the global application state. For convenience,
- * it also holds an instance of the main menu for macOS (or Ubuntu unity) style GUIs which only
- * have one, application-level menu.
- *
- */
-
-#ifndef TIKZIT_H
-#define TIKZIT_H
-
-#include "mainwindow.h"
-#include "mainmenu.h"
-#include "ui_mainmenu.h"
-
-#include "toolpalette.h"
-#include "propertypalette.h"
-#include "stylepalette.h"
-#include "nodestyle.h"
-#include "tikzstyles.h"
-
-#include <QObject>
-#include <QVector>
-#include <QPointF>
-#include <QMenuBar>
-#include <QMainWindow>
-#include <QFont>
-
-// Number of pixels between (0,0) and (1,0) at 100% zoom level. This should be
-// divisible by 8 to avoid rounding errors with e.g. grid-snapping.
-#define GLOBAL_SCALE 40
-#define GLOBAL_SCALEF 40.0f
-#define GLOBAL_SCALEF_INV 0.025f
-#define GRID_N 4
-#define GRID_SEP 10
-#define GRID_SEPF 10.0f
-
-inline QPointF toScreen(QPointF src)
-{ src.setY(-src.y()); src *= GLOBAL_SCALEF; return src; }
-
-inline QPointF fromScreen(QPointF src)
-{ src.setY(-src.y()); src *= GLOBAL_SCALEF_INV; return src; }
-
-inline QRectF rectToScreen(QRectF src)
-{ return QRectF(src.x() * GLOBAL_SCALEF,
- -(src.y()+src.height()) * GLOBAL_SCALEF,
- src.width() * GLOBAL_SCALEF,
- src.height() * GLOBAL_SCALEF); }
-
-inline QRectF rectFromScreen(QRectF src)
-{ return QRectF(src.x() * GLOBAL_SCALEF_INV,
- -(src.y()+src.height()) * GLOBAL_SCALEF_INV,
- src.width() * GLOBAL_SCALEF_INV,
- src.height() * GLOBAL_SCALEF_INV); }
-
-class Tikzit : public QObject {
- Q_OBJECT
-public:
- Tikzit();
- ToolPalette *toolPalette() const;
- PropertyPalette *propertyPalette() const;
-
- MainWindow *activeWindow() const;
- void setActiveWindow(MainWindow *activeWindow);
- void removeWindow(MainWindow *w);
-
- static QFont LABEL_FONT;
-// Ui::MainMenu *_mainMenuUi;
-// QMenuBar *_mainMenu;
-
- void newDoc();
- void open();
- void open(QString fileName);
- void quit();
- void init(QApplication *app);
-
- void openTikzStyles();
- void loadStyles(QString fileName);
- TikzStyles *styles() const;
- QString styleFile() const;
- //StylePalette *stylePalette() const;
-
-public slots:
- void focusChanged(QWidget *old, QWidget *nw);
-private:
- // void createMenu();
-
- MainMenu *_mainMenu;
- ToolPalette *_toolPalette;
- PropertyPalette *_propertyPalette;
- //StylePalette *_stylePalette;
- QVector<MainWindow*> _windows;
- MainWindow *_activeWindow;
- TikzStyles *_styles;
- QString _styleFile;
-
-};
-
-extern Tikzit *tikzit;
-
-#endif // TIKZIT_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 <https://www.gnu.org/licenses/>.
+*/
+
+
+/*!
+ *
+ * \mainpage TikZiT Documentation
+ *
+ * This is the source code documentation for TikZiT. The global entry point
+ * for the TikZiT executable is in main.cpp, whereas the class Tikzit maintains
+ * the global application state.
+ *
+ * The TikZ parser is implemented in flex/bison in the files tikzlexer.l and tikzparser.y.
+ *
+ * Most of the interesting code for handling user input is in the class TikzScene. Anything
+ * that makes a change to the tikz file should be implemented as a QUndoCommand. Currently,
+ * these are all in undocommands.h.
+ *
+ * I've basically been adding documentation as I go. Other bits and pieces can be accessed
+ * by searching, or via the class list/class hierarchy links in the menu above.
+ *
+ */
+
+/*!
+ *
+ * \class Tikzit
+ *
+ * Tikzit is the top-level class which maintains the global application state. For convenience,
+ * it also holds an instance of the main menu for macOS (or Ubuntu unity) style GUIs which only
+ * have one, application-level menu.
+ *
+ */
+
+#ifndef TIKZIT_H
+#define TIKZIT_H
+
+#include "mainwindow.h"
+#include "mainmenu.h"
+#include "ui_mainmenu.h"
+
+#include "toolpalette.h"
+#include "propertypalette.h"
+#include "stylepalette.h"
+#include "nodestyle.h"
+#include "tikzstyles.h"
+
+#include <QObject>
+#include <QVector>
+#include <QPointF>
+#include <QMenuBar>
+#include <QMainWindow>
+#include <QFont>
+
+// Number of pixels between (0,0) and (1,0) at 100% zoom level. This should be
+// divisible by 8 to avoid rounding errors with e.g. grid-snapping.
+#define GLOBAL_SCALE 40
+#define GLOBAL_SCALEF 40.0f
+#define GLOBAL_SCALEF_INV 0.025f
+#define GRID_N 4
+#define GRID_SEP 10
+#define GRID_SEPF 10.0f
+
+inline QPointF toScreen(QPointF src)
+{ src.setY(-src.y()); src *= GLOBAL_SCALEF; return src; }
+
+inline QPointF fromScreen(QPointF src)
+{ src.setY(-src.y()); src *= GLOBAL_SCALEF_INV; return src; }
+
+inline QRectF rectToScreen(QRectF src)
+{ return QRectF(src.x() * GLOBAL_SCALEF,
+ -(src.y()+src.height()) * GLOBAL_SCALEF,
+ src.width() * GLOBAL_SCALEF,
+ src.height() * GLOBAL_SCALEF); }
+
+inline QRectF rectFromScreen(QRectF src)
+{ return QRectF(src.x() * GLOBAL_SCALEF_INV,
+ -(src.y()+src.height()) * GLOBAL_SCALEF_INV,
+ src.width() * GLOBAL_SCALEF_INV,
+ src.height() * GLOBAL_SCALEF_INV); }
+
+class Tikzit : public QObject {
+ Q_OBJECT
+public:
+ Tikzit();
+ ToolPalette *toolPalette() const;
+ PropertyPalette *propertyPalette() const;
+
+ MainWindow *activeWindow() const;
+ void setActiveWindow(MainWindow *activeWindow);
+ void removeWindow(MainWindow *w);
+
+ static QFont LABEL_FONT;
+// Ui::MainMenu *_mainMenuUi;
+// QMenuBar *_mainMenu;
+
+ void newDoc();
+ void open();
+ void open(QString fileName);
+ void quit();
+ void init(QApplication *app);
+
+ void openTikzStyles();
+ void loadStyles(QString fileName);
+ TikzStyles *styles() const;
+ QString styleFile() const;
+ //StylePalette *stylePalette() const;
+
+public slots:
+ void focusChanged(QWidget *old, QWidget *nw);
+private:
+ // void createMenu();
+
+ MainMenu *_mainMenu;
+ ToolPalette *_toolPalette;
+ PropertyPalette *_propertyPalette;
+ //StylePalette *_stylePalette;
+ QVector<MainWindow*> _windows;
+ MainWindow *_activeWindow;
+ TikzStyles *_styles;
+ QString _styleFile;
+
+};
+
+extern Tikzit *tikzit;
+
+#endif // TIKZIT_H
diff --git a/src/util.cpp b/src/util.cpp
index 9c699f5..6d75bee 100644
--- a/src/util.cpp
+++ b/src/util.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 <https://www.gnu.org/licenses/>.
-*/
-
-#include "util.h"
-
-float bezierInterpolate(float dist, float c0, float c1, float c2, float c3) {
- float distp = 1 - dist;
- return (distp*distp*distp) * c0 +
- 3 * (distp*distp) * dist * c1 +
- 3 * (dist*dist) * distp * c2 +
- (dist*dist*dist) * c3;
-}
-
-QPointF bezierInterpolateFull (float dist, QPointF c0, QPointF c1, QPointF c2, QPointF c3) {
- return QPointF(bezierInterpolate (dist, c0.x(), c1.x(), c2.x(), c3.x()),
- bezierInterpolate (dist, c0.y(), c1.y(), c2.y(), c3.y()));
-}
-
-
-float roundToNearest(float stepSize, float val) {
- if (stepSize==0.0f) return val;
- else return round(val/stepSize)*stepSize;
-}
-
-float radiansToDegrees (float radians) {
- return (radians * 180.0f) / M_PI;
-}
-
-float degreesToRadians(float degrees) {
- return (degrees * M_PI) / 180.0f;
-}
-
-int normaliseAngleDeg (int degrees) {
- while (degrees > 180) {
- degrees -= 360;
- }
- while (degrees <= -180) {
- degrees += 360;
- }
- return degrees;
-}
-
-float normaliseAngleRad (float rads) {
- while (rads > M_PI) {
- rads -= 2 * M_PI;
- }
- while (rads <= -M_PI) {
- rads += 2 * M_PI;
- }
- return rads;
-}
-
-// convert float to string, squashing very small floats to zero
-QString floatToString(float f) {
- if (f >= -0.000001 && f <= 0.000001) return "0";
- else return QString::number(f);
-}
+/*
+ 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "util.h"
+
+float bezierInterpolate(float dist, float c0, float c1, float c2, float c3) {
+ float distp = 1 - dist;
+ return (distp*distp*distp) * c0 +
+ 3 * (distp*distp) * dist * c1 +
+ 3 * (dist*dist) * distp * c2 +
+ (dist*dist*dist) * c3;
+}
+
+QPointF bezierInterpolateFull (float dist, QPointF c0, QPointF c1, QPointF c2, QPointF c3) {
+ return QPointF(bezierInterpolate (dist, c0.x(), c1.x(), c2.x(), c3.x()),
+ bezierInterpolate (dist, c0.y(), c1.y(), c2.y(), c3.y()));
+}
+
+
+float roundToNearest(float stepSize, float val) {
+ if (stepSize==0.0f) return val;
+ else return round(val/stepSize)*stepSize;
+}
+
+float radiansToDegrees (float radians) {
+ return (radians * 180.0f) / M_PI;
+}
+
+float degreesToRadians(float degrees) {
+ return (degrees * M_PI) / 180.0f;
+}
+
+int normaliseAngleDeg (int degrees) {
+ while (degrees > 180) {
+ degrees -= 360;
+ }
+ while (degrees <= -180) {
+ degrees += 360;
+ }
+ return degrees;
+}
+
+float normaliseAngleRad (float rads) {
+ while (rads > M_PI) {
+ rads -= 2 * M_PI;
+ }
+ while (rads <= -M_PI) {
+ rads += 2 * M_PI;
+ }
+ return rads;
+}
+
+// convert float to string, squashing very small floats to zero
+QString floatToString(float f) {
+ if (f >= -0.000001 && f <= 0.000001) return "0";
+ else return QString::number(f);
+}
diff --git a/src/util.h b/src/util.h
index aff0587..a0388d7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,48 +1,48 @@
-/*
- 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 <https://www.gnu.org/licenses/>.
-*/
-
-/*!
- * Various utility functions, mostly for mathematical calculation.
- */
-
-#ifndef UTIL_H
-#define UTIL_H
-
-#include <QPoint>
-#include <QString>
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338327950288
-#endif
-
-// interpolate on a cubic bezier curve
-float bezierInterpolate(float dist, float c0, float c1, float c2, float c3);
-QPointF bezierInterpolateFull (float dist, QPointF c0, QPointF c1, QPointF c2, QPointF c3);
-
-// rounding
-float roundToNearest(float stepSize, float val);
-float radiansToDegrees (float radians);
-QString floatToString(float f);
-
-// angles
-float degreesToRadians(float degrees);
-int normaliseAngleDeg (int degrees);
-float normaliseAngleRad (float rads);
-
-#endif // UTIL_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 <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Various utility functions, mostly for mathematical calculation.
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <QPoint>
+#include <QString>
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327950288
+#endif
+
+// interpolate on a cubic bezier curve
+float bezierInterpolate(float dist, float c0, float c1, float c2, float c3);
+QPointF bezierInterpolateFull (float dist, QPointF c0, QPointF c1, QPointF c2, QPointF c3);
+
+// rounding
+float roundToNearest(float stepSize, float val);
+float radiansToDegrees (float radians);
+QString floatToString(float f);
+
+// angles
+float degreesToRadians(float degrees);
+int normaliseAngleDeg (int degrees);
+float normaliseAngleRad (float rads);
+
+#endif // UTIL_H