diff options
author | Aleks Kissinger <aleks0@gmail.com> | 2018-07-20 11:13:42 +0200 |
---|---|---|
committer | Aleks Kissinger <aleks0@gmail.com> | 2018-07-20 11:13:42 +0200 |
commit | c7f79b3a9878dafc4088f170964264dff839f502 (patch) | |
tree | 1ef286f50d758ab739b7747418d76c1377176964 | |
parent | 329da8795d9a9183830d0c4e0e22ea08d546a4f7 (diff) |
...
-rw-r--r-- | src/gui/commands.h | 8 | ||||
-rw-r--r-- | src/gui/edgeitem.cpp | 442 | ||||
-rw-r--r-- | src/gui/edgeitem.h | 124 | ||||
-rw-r--r-- | src/gui/mainmenu.cpp | 302 | ||||
-rw-r--r-- | src/gui/mainmenu.h | 128 | ||||
-rw-r--r-- | src/gui/mainmenu.ui | 418 | ||||
-rw-r--r-- | src/gui/mainwindow.cpp | 320 | ||||
-rw-r--r-- | src/gui/mainwindow.h | 120 | ||||
-rw-r--r-- | src/gui/mainwindow.ui | 410 | ||||
-rw-r--r-- | src/gui/nodeitem.cpp | 318 | ||||
-rw-r--r-- | src/gui/nodeitem.h | 102 | ||||
-rw-r--r-- | src/gui/propertypalette.cpp | 122 | ||||
-rw-r--r-- | src/gui/propertypalette.h | 92 | ||||
-rw-r--r-- | src/gui/propertypalette.ui | 66 | ||||
-rw-r--r-- | src/gui/stylepalette.cpp | 358 | ||||
-rw-r--r-- | src/gui/stylepalette.h | 122 | ||||
-rw-r--r-- | src/gui/stylepalette.ui | 240 | ||||
-rw-r--r-- | src/gui/tikzscene.cpp | 1560 | ||||
-rw-r--r-- | src/gui/tikzscene.h | 214 | ||||
-rw-r--r-- | src/gui/tikzview.cpp | 256 | ||||
-rw-r--r-- | src/gui/tikzview.h | 104 | ||||
-rw-r--r-- | src/gui/toolpalette.cpp | 172 | ||||
-rw-r--r-- | src/gui/toolpalette.h | 106 | ||||
-rw-r--r-- | src/gui/undocommands.cpp | 856 | ||||
-rw-r--r-- | src/gui/undocommands.h | 388 |
25 files changed, 3674 insertions, 3674 deletions
diff --git a/src/gui/commands.h b/src/gui/commands.h index 9942ba8..73bfaa7 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 9cf14c8..f469506 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 060de13..3d4758a 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 69159d2..3625338 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 8cb7a3a..aa5c727 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 ce7d41d..6a2511e 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 953889e..15b6943 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 3ab641c..1e05239 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 3df579f..137d6cf 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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;">
-<p style="-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;"><br /></p></body></html></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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Courier New'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-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;"><br /></p></body></html></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 d308dd2..b452848 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 efd32f1..678a7e8 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 e2b8b8d..c27b8b2 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 1241123..29fb0af 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 f5ccebd..a8ba5d2 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 42d440e..e3fea0b 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 01daa90..45dc8da 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 be8263e..4f5b58d 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 6f2994b..47464fe 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 8aafe28..4ac56c7 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 f0084fb..6cdb17c 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 bfa7ace..4ec9f3d 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 2931f82..43a4a49 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 d095d93..a001055 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 dc7a797..5525cb7 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 9164f01..292632e 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 |