diff options
Diffstat (limited to 'src/gui')
-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 73bfaa7..9942ba8 100644 --- a/src/gui/commands.h +++ b/src/gui/commands.h @@ -1,4 +1,4 @@ -#ifndef COMMANDS_H -#define COMMANDS_H - -#endif // COMMANDS_H +#ifndef COMMANDS_H
+#define COMMANDS_H
+
+#endif // COMMANDS_H
diff --git a/src/gui/edgeitem.cpp b/src/gui/edgeitem.cpp index f469506..9cf14c8 100644 --- a/src/gui/edgeitem.cpp +++ b/src/gui/edgeitem.cpp @@ -1,221 +1,221 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "tikzit.h" -#include "edgeitem.h" - -#include <QPainterPath> -#include <QPen> - -EdgeItem::EdgeItem(Edge *edge) -{ - _edge = edge; - setFlag(QGraphicsItem::ItemIsSelectable); - - _cp1Item = new QGraphicsEllipseItem(this); - _cp1Item->setParentItem(this); - _cp1Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1), - GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2); - _cp1Item->setVisible(false); - - _cp2Item = new QGraphicsEllipseItem(this); - _cp2Item->setParentItem(this); - _cp2Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1), - GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2); - _cp2Item->setVisible(false); - - readPos(); -} - -void EdgeItem::readPos() -{ - //_edge->setAttributesFromData(); - _edge->updateControls(); - QPainterPath path; - - path.moveTo (toScreen(_edge->tail())); - - if (_edge->bend() != 0 || !_edge->basicBendMode()) { - path.cubicTo(toScreen(_edge->cp1()), - toScreen(_edge->cp2()), - toScreen(_edge->head())); - } - else { - path.lineTo(toScreen(_edge->head())); - } - - setPath(path); - - _cp1Item->setPos(toScreen(_edge->cp1())); - _cp2Item->setPos(toScreen(_edge->cp2())); -} - -void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - //QGraphicsPathItem::paint(painter, option, widget); - QPen pen = _edge->style()->pen(); - painter->setPen(pen); - painter->setBrush(Qt::NoBrush); - painter->drawPath(path()); - - QPointF ht = _edge->headTangent(); - QPointF hLeft(-ht.y(), ht.x()); - QPointF hRight(ht.y(), -ht.x()); - QPointF tt = _edge->tailTangent(); - QPointF tLeft(-ht.y(), ht.x()); - QPointF tRight(ht.y(), -ht.x()); - - pen.setStyle(Qt::SolidLine); - painter->setPen(pen); - - - - switch (_edge->style()->arrowHead()) { - case EdgeStyle::Flat: - { - painter->drawLine( - toScreen(_edge->head() + hLeft), - toScreen(_edge->head() + hRight)); - break; - } - case EdgeStyle::Pointer: - { - QPainterPath pth; - pth.moveTo(toScreen(_edge->head() + ht + hLeft)); - pth.lineTo(toScreen(_edge->head())); - pth.lineTo(toScreen(_edge->head() + ht + hRight)); - painter->drawPath(pth); - break; - } - } - - switch (_edge->style()->arrowTail()) { - case EdgeStyle::Flat: - { - painter->drawLine( - toScreen(_edge->tail() + tLeft), - toScreen(_edge->tail() + tRight)); - break; - } - case EdgeStyle::Pointer: - { - QPainterPath pth; - pth.moveTo(toScreen(_edge->tail() + tt + tLeft)); - pth.lineTo(toScreen(_edge->tail())); - pth.lineTo(toScreen(_edge->tail() + tt + tRight)); - painter->drawPath(pth); - break; - } - } - - if (isSelected()) { - QColor draw; - QColor draw1; - QColor fill; - - if (_edge->basicBendMode()) { - draw = Qt::blue; - draw1 = QColor(100,100,255,100); - fill = QColor(200,200,255,50); - } else { - draw = Qt::darkGreen; - draw1 = QColor(0, 150, 0, 50); - fill = QColor(200,255,200,150); - } - - painter->setPen(QPen(draw1)); - - float r = GLOBAL_SCALEF * _edge->cpDist(); - painter->drawEllipse(toScreen(_edge->source()->point()), r, r); - painter->drawEllipse(toScreen(_edge->target()->point()), r, r); - - painter->setPen(QPen(draw)); - painter->setBrush(QBrush(fill)); - - painter->drawLine(toScreen(_edge->tail()), toScreen(_edge->cp1())); - painter->drawLine(toScreen(_edge->head()), toScreen(_edge->cp2())); - - //painter->drawEllipse(toScreen(_edge->cp1()), r, r); - //painter->drawEllipse(toScreen(_edge->cp2()), r, r); - - _cp1Item->setPen(QPen(draw)); - _cp1Item->setBrush(QBrush(fill)); - _cp1Item->setVisible(true); - - _cp2Item->setPen(QPen(draw)); - _cp2Item->setBrush(QBrush(fill)); - _cp2Item->setVisible(true); - - r = GLOBAL_SCALEF * 0.05; - painter->setPen(QPen(Qt::black)); - painter->setBrush(QBrush(QColor(255,255,255,200))); - painter->drawEllipse(toScreen(_edge->mid()), r, r); - } else { - _cp1Item->setVisible(false); - _cp2Item->setVisible(false); - } -} - -QRectF EdgeItem::boundingRect() const -{ - return _boundingRect; -} - -QPainterPath EdgeItem::shape() const -{ - return _expPath; -} - -Edge *EdgeItem::edge() const -{ - return _edge; -} - -QGraphicsEllipseItem *EdgeItem::cp1Item() const -{ - return _cp1Item; -} - -QGraphicsEllipseItem *EdgeItem::cp2Item() const -{ - return _cp2Item; -} - -QPainterPath EdgeItem::path() const -{ - return _path; -} - -void EdgeItem::setPath(const QPainterPath &path) -{ - prepareGeometryChange(); - - _path = path; - - // get the shape of the edge, and expand a bit to make selection easier - QPainterPathStroker stroker; - stroker.setWidth(5); - stroker.setJoinStyle(Qt::MiterJoin); - _expPath = (stroker.createStroke(_path) + _path).simplified(); - - float r = GLOBAL_SCALEF * (_edge->cpDist() + 0.2); - _boundingRect = _path.boundingRect().adjusted(-r,-r,r,r); - - update(); -} - +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "edgeitem.h"
+
+#include <QPainterPath>
+#include <QPen>
+
+EdgeItem::EdgeItem(Edge *edge)
+{
+ _edge = edge;
+ setFlag(QGraphicsItem::ItemIsSelectable);
+
+ _cp1Item = new QGraphicsEllipseItem(this);
+ _cp1Item->setParentItem(this);
+ _cp1Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
+ GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ _cp1Item->setVisible(false);
+
+ _cp2Item = new QGraphicsEllipseItem(this);
+ _cp2Item->setParentItem(this);
+ _cp2Item->setRect(GLOBAL_SCALEF * (-0.1), GLOBAL_SCALEF * (-0.1),
+ GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ _cp2Item->setVisible(false);
+
+ readPos();
+}
+
+void EdgeItem::readPos()
+{
+ //_edge->setAttributesFromData();
+ _edge->updateControls();
+ QPainterPath path;
+
+ path.moveTo (toScreen(_edge->tail()));
+
+ if (_edge->bend() != 0 || !_edge->basicBendMode()) {
+ path.cubicTo(toScreen(_edge->cp1()),
+ toScreen(_edge->cp2()),
+ toScreen(_edge->head()));
+ }
+ else {
+ path.lineTo(toScreen(_edge->head()));
+ }
+
+ setPath(path);
+
+ _cp1Item->setPos(toScreen(_edge->cp1()));
+ _cp2Item->setPos(toScreen(_edge->cp2()));
+}
+
+void EdgeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ //QGraphicsPathItem::paint(painter, option, widget);
+ QPen pen = _edge->style()->pen();
+ painter->setPen(pen);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(path());
+
+ QPointF ht = _edge->headTangent();
+ QPointF hLeft(-ht.y(), ht.x());
+ QPointF hRight(ht.y(), -ht.x());
+ QPointF tt = _edge->tailTangent();
+ QPointF tLeft(-ht.y(), ht.x());
+ QPointF tRight(ht.y(), -ht.x());
+
+ pen.setStyle(Qt::SolidLine);
+ painter->setPen(pen);
+
+
+
+ switch (_edge->style()->arrowHead()) {
+ case EdgeStyle::Flat:
+ {
+ painter->drawLine(
+ toScreen(_edge->head() + hLeft),
+ toScreen(_edge->head() + hRight));
+ break;
+ }
+ case EdgeStyle::Pointer:
+ {
+ QPainterPath pth;
+ pth.moveTo(toScreen(_edge->head() + ht + hLeft));
+ pth.lineTo(toScreen(_edge->head()));
+ pth.lineTo(toScreen(_edge->head() + ht + hRight));
+ painter->drawPath(pth);
+ break;
+ }
+ }
+
+ switch (_edge->style()->arrowTail()) {
+ case EdgeStyle::Flat:
+ {
+ painter->drawLine(
+ toScreen(_edge->tail() + tLeft),
+ toScreen(_edge->tail() + tRight));
+ break;
+ }
+ case EdgeStyle::Pointer:
+ {
+ QPainterPath pth;
+ pth.moveTo(toScreen(_edge->tail() + tt + tLeft));
+ pth.lineTo(toScreen(_edge->tail()));
+ pth.lineTo(toScreen(_edge->tail() + tt + tRight));
+ painter->drawPath(pth);
+ break;
+ }
+ }
+
+ if (isSelected()) {
+ QColor draw;
+ QColor draw1;
+ QColor fill;
+
+ if (_edge->basicBendMode()) {
+ draw = Qt::blue;
+ draw1 = QColor(100,100,255,100);
+ fill = QColor(200,200,255,50);
+ } else {
+ draw = Qt::darkGreen;
+ draw1 = QColor(0, 150, 0, 50);
+ fill = QColor(200,255,200,150);
+ }
+
+ painter->setPen(QPen(draw1));
+
+ float r = GLOBAL_SCALEF * _edge->cpDist();
+ painter->drawEllipse(toScreen(_edge->source()->point()), r, r);
+ painter->drawEllipse(toScreen(_edge->target()->point()), r, r);
+
+ painter->setPen(QPen(draw));
+ painter->setBrush(QBrush(fill));
+
+ painter->drawLine(toScreen(_edge->tail()), toScreen(_edge->cp1()));
+ painter->drawLine(toScreen(_edge->head()), toScreen(_edge->cp2()));
+
+ //painter->drawEllipse(toScreen(_edge->cp1()), r, r);
+ //painter->drawEllipse(toScreen(_edge->cp2()), r, r);
+
+ _cp1Item->setPen(QPen(draw));
+ _cp1Item->setBrush(QBrush(fill));
+ _cp1Item->setVisible(true);
+
+ _cp2Item->setPen(QPen(draw));
+ _cp2Item->setBrush(QBrush(fill));
+ _cp2Item->setVisible(true);
+
+ r = GLOBAL_SCALEF * 0.05;
+ painter->setPen(QPen(Qt::black));
+ painter->setBrush(QBrush(QColor(255,255,255,200)));
+ painter->drawEllipse(toScreen(_edge->mid()), r, r);
+ } else {
+ _cp1Item->setVisible(false);
+ _cp2Item->setVisible(false);
+ }
+}
+
+QRectF EdgeItem::boundingRect() const
+{
+ return _boundingRect;
+}
+
+QPainterPath EdgeItem::shape() const
+{
+ return _expPath;
+}
+
+Edge *EdgeItem::edge() const
+{
+ return _edge;
+}
+
+QGraphicsEllipseItem *EdgeItem::cp1Item() const
+{
+ return _cp1Item;
+}
+
+QGraphicsEllipseItem *EdgeItem::cp2Item() const
+{
+ return _cp2Item;
+}
+
+QPainterPath EdgeItem::path() const
+{
+ return _path;
+}
+
+void EdgeItem::setPath(const QPainterPath &path)
+{
+ prepareGeometryChange();
+
+ _path = path;
+
+ // get the shape of the edge, and expand a bit to make selection easier
+ QPainterPathStroker stroker;
+ stroker.setWidth(5);
+ stroker.setJoinStyle(Qt::MiterJoin);
+ _expPath = (stroker.createStroke(_path) + _path).simplified();
+
+ float r = GLOBAL_SCALEF * (_edge->cpDist() + 0.2);
+ _boundingRect = _path.boundingRect().adjusted(-r,-r,r,r);
+
+ update();
+}
+
diff --git a/src/gui/edgeitem.h b/src/gui/edgeitem.h index 3d4758a..060de13 100644 --- a/src/gui/edgeitem.h +++ b/src/gui/edgeitem.h @@ -1,62 +1,62 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * A QGraphicsItem that handles drawing a single edge. - */ - -#ifndef EDGEITEM_H -#define EDGEITEM_H - -#include "edge.h" - -#include <QObject> -#include <QGraphicsPathItem> -#include <QPainter> -#include <QStyleOptionGraphicsItem> -#include <QWidget> -#include <QGraphicsEllipseItem> -#include <QString> - -class EdgeItem : public QGraphicsItem -{ -public: - EdgeItem(Edge *edge); - void readPos(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - QRectF boundingRect() const; - QPainterPath shape() const; - Edge *edge() const; - QGraphicsEllipseItem *cp1Item() const; - QGraphicsEllipseItem *cp2Item() const; - - - QPainterPath path() const; - void setPath(const QPainterPath &path); - - -private: - Edge *_edge; - QPainterPath _path; - QPainterPath _expPath; - QRectF _boundingRect; - QGraphicsEllipseItem *_cp1Item; - QGraphicsEllipseItem *_cp2Item; -}; - -#endif // EDGEITEM_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A QGraphicsItem that handles drawing a single edge.
+ */
+
+#ifndef EDGEITEM_H
+#define EDGEITEM_H
+
+#include "edge.h"
+
+#include <QObject>
+#include <QGraphicsPathItem>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QWidget>
+#include <QGraphicsEllipseItem>
+#include <QString>
+
+class EdgeItem : public QGraphicsItem
+{
+public:
+ EdgeItem(Edge *edge);
+ void readPos();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ Edge *edge() const;
+ QGraphicsEllipseItem *cp1Item() const;
+ QGraphicsEllipseItem *cp2Item() const;
+
+
+ QPainterPath path() const;
+ void setPath(const QPainterPath &path);
+
+
+private:
+ Edge *_edge;
+ QPainterPath _path;
+ QPainterPath _expPath;
+ QRectF _boundingRect;
+ QGraphicsEllipseItem *_cp1Item;
+ QGraphicsEllipseItem *_cp2Item;
+};
+
+#endif // EDGEITEM_H
diff --git a/src/gui/mainmenu.cpp b/src/gui/mainmenu.cpp index 3625338..69159d2 100644 --- a/src/gui/mainmenu.cpp +++ b/src/gui/mainmenu.cpp @@ -1,151 +1,151 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "mainmenu.h" -#include "tikzit.h" - -#include <QDebug> - -MainMenu::MainMenu() -{ - ui.setupUi(this); -} - -// File -void MainMenu::on_actionNew_triggered() -{ - tikzit->newDoc(); -} - -void MainMenu::on_actionOpen_triggered() -{ - tikzit->open(); -} - -void MainMenu::on_actionClose_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->close(); -} - -void MainMenu::on_actionSave_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzDocument()->save(); -} - -void MainMenu::on_actionSave_As_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzDocument()->saveAs(); -} - -void MainMenu::on_actionExit_triggered() -{ - tikzit->quit(); -} - - -// Edit -void MainMenu::on_actionUndo_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzDocument()->undoStack()->undo(); -} - -void MainMenu::on_actionRedo_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzDocument()->undoStack()->redo(); -} - -void MainMenu::on_actionCut_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->cutToClipboard(); -} - -void MainMenu::on_actionCopy_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->copyToClipboard(); -} - -void MainMenu::on_actionPaste_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->pasteFromClipboard(); -} - -void MainMenu::on_actionDelete_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->deleteSelectedItems(); -} - -void MainMenu::on_actionSelect_All_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->selectAllNodes(); -} - -void MainMenu::on_actionDeselect_All_triggered() -{ - if (tikzit->activeWindow() != 0) - tikzit->activeWindow()->tikzScene()->deselectAll(); -} - - -// Tikz -void MainMenu::on_actionParse_triggered() -{ - MainWindow *win = tikzit->activeWindow(); - if (win != 0) { - win->tikzScene()->parseTikz(win->tikzSource()); - } -} - -void MainMenu::on_actionRevert_triggered() -{ - MainWindow *win = tikzit->activeWindow(); - if (win != 0) { - win->tikzDocument()->refreshTikz(); - win->tikzScene()->setEnabled(true); - } -} - -void MainMenu::on_actionJump_to_Selection_triggered() -{ - MainWindow *win = tikzit->activeWindow(); - if (win != 0) { - qDebug() << "jump to selection on line:" << win->tikzScene()->lineNumberForSelection(); - win->setSourceLine(win->tikzScene()->lineNumberForSelection()); - } -} - - -// View -void MainMenu::on_actionZoom_In_triggered() -{ - if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomIn(); -} - -void MainMenu::on_actionZoom_Out_triggered() -{ - if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomOut(); -} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "mainmenu.h"
+#include "tikzit.h"
+
+#include <QDebug>
+
+MainMenu::MainMenu()
+{
+ ui.setupUi(this);
+}
+
+// File
+void MainMenu::on_actionNew_triggered()
+{
+ tikzit->newDoc();
+}
+
+void MainMenu::on_actionOpen_triggered()
+{
+ tikzit->open();
+}
+
+void MainMenu::on_actionClose_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->close();
+}
+
+void MainMenu::on_actionSave_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->save();
+}
+
+void MainMenu::on_actionSave_As_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->saveAs();
+}
+
+void MainMenu::on_actionExit_triggered()
+{
+ tikzit->quit();
+}
+
+
+// Edit
+void MainMenu::on_actionUndo_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->undoStack()->undo();
+}
+
+void MainMenu::on_actionRedo_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->undoStack()->redo();
+}
+
+void MainMenu::on_actionCut_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->cutToClipboard();
+}
+
+void MainMenu::on_actionCopy_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->copyToClipboard();
+}
+
+void MainMenu::on_actionPaste_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->pasteFromClipboard();
+}
+
+void MainMenu::on_actionDelete_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->deleteSelectedItems();
+}
+
+void MainMenu::on_actionSelect_All_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->selectAllNodes();
+}
+
+void MainMenu::on_actionDeselect_All_triggered()
+{
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->deselectAll();
+}
+
+
+// Tikz
+void MainMenu::on_actionParse_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ win->tikzScene()->parseTikz(win->tikzSource());
+ }
+}
+
+void MainMenu::on_actionRevert_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ win->tikzDocument()->refreshTikz();
+ win->tikzScene()->setEnabled(true);
+ }
+}
+
+void MainMenu::on_actionJump_to_Selection_triggered()
+{
+ MainWindow *win = tikzit->activeWindow();
+ if (win != 0) {
+ qDebug() << "jump to selection on line:" << win->tikzScene()->lineNumberForSelection();
+ win->setSourceLine(win->tikzScene()->lineNumberForSelection());
+ }
+}
+
+
+// View
+void MainMenu::on_actionZoom_In_triggered()
+{
+ if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomIn();
+}
+
+void MainMenu::on_actionZoom_Out_triggered()
+{
+ if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzView()->zoomOut();
+}
diff --git a/src/gui/mainmenu.h b/src/gui/mainmenu.h index aa5c727..8cb7a3a 100644 --- a/src/gui/mainmenu.h +++ b/src/gui/mainmenu.h @@ -1,64 +1,64 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#ifndef MAINMENU_H -#define MAINMENU_H - -#include "ui_mainmenu.h" - -#include <QMenuBar> - -class MainMenu : public QMenuBar -{ - Q_OBJECT -public: - MainMenu(); - -private: - Ui::MainMenu ui; - -public slots: - // File - void on_actionNew_triggered(); - void on_actionOpen_triggered(); - void on_actionClose_triggered(); - void on_actionSave_triggered(); - void on_actionSave_As_triggered(); - void on_actionExit_triggered(); - - // Edit - void on_actionUndo_triggered(); - void on_actionRedo_triggered(); - void on_actionCut_triggered(); - void on_actionCopy_triggered(); - void on_actionPaste_triggered(); - void on_actionDelete_triggered(); - void on_actionSelect_All_triggered(); - void on_actionDeselect_All_triggered(); - - // Tikz - void on_actionParse_triggered(); - void on_actionRevert_triggered(); - void on_actionJump_to_Selection_triggered(); - - // View - void on_actionZoom_In_triggered(); - void on_actionZoom_Out_triggered(); -}; - -#endif // MAINMENU_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef MAINMENU_H
+#define MAINMENU_H
+
+#include "ui_mainmenu.h"
+
+#include <QMenuBar>
+
+class MainMenu : public QMenuBar
+{
+ Q_OBJECT
+public:
+ MainMenu();
+
+private:
+ Ui::MainMenu ui;
+
+public slots:
+ // File
+ void on_actionNew_triggered();
+ void on_actionOpen_triggered();
+ void on_actionClose_triggered();
+ void on_actionSave_triggered();
+ void on_actionSave_As_triggered();
+ void on_actionExit_triggered();
+
+ // Edit
+ void on_actionUndo_triggered();
+ void on_actionRedo_triggered();
+ void on_actionCut_triggered();
+ void on_actionCopy_triggered();
+ void on_actionPaste_triggered();
+ void on_actionDelete_triggered();
+ void on_actionSelect_All_triggered();
+ void on_actionDeselect_All_triggered();
+
+ // Tikz
+ void on_actionParse_triggered();
+ void on_actionRevert_triggered();
+ void on_actionJump_to_Selection_triggered();
+
+ // View
+ void on_actionZoom_In_triggered();
+ void on_actionZoom_Out_triggered();
+};
+
+#endif // MAINMENU_H
diff --git a/src/gui/mainmenu.ui b/src/gui/mainmenu.ui index 6a2511e..ce7d41d 100644 --- a/src/gui/mainmenu.ui +++ b/src/gui/mainmenu.ui @@ -1,209 +1,209 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainMenu</class> - <widget class="QMenuBar" name="MainMenu"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>476</width> - <height>22</height> - </rect> - </property> - <widget class="QMenu" name="menuFile"> - <property name="title"> - <string>File</string> - </property> - <addaction name="actionNew"/> - <addaction name="actionOpen"/> - <addaction name="separator"/> - <addaction name="actionClose"/> - <addaction name="actionSave"/> - <addaction name="actionSave_As"/> - <addaction name="separator"/> - <addaction name="actionExit"/> - </widget> - <widget class="QMenu" name="menuEdit"> - <property name="title"> - <string>Edit</string> - </property> - <addaction name="actionUndo"/> - <addaction name="actionRedo"/> - <addaction name="separator"/> - <addaction name="actionCut"/> - <addaction name="actionCopy"/> - <addaction name="actionPaste"/> - <addaction name="actionDelete"/> - <addaction name="separator"/> - <addaction name="actionSelect_All"/> - <addaction name="actionDeselect_All"/> - </widget> - <widget class="QMenu" name="menuTikz"> - <property name="title"> - <string>Tikz</string> - </property> - <addaction name="actionParse"/> - <addaction name="actionRevert"/> - <addaction name="actionJump_to_Selection"/> - </widget> - <widget class="QMenu" name="menuView"> - <property name="title"> - <string>View</string> - </property> - <addaction name="actionZoom_In"/> - <addaction name="actionZoom_Out"/> - </widget> - <action name="actionNew"> - <property name="text"> - <string>New...</string> - </property> - <property name="shortcut"> - <string>Ctrl+N</string> - </property> - </action> - <action name="actionOpen"> - <property name="text"> - <string>Open...</string> - </property> - <property name="shortcut"> - <string>Ctrl+O</string> - </property> - </action> - <action name="actionClose"> - <property name="text"> - <string>Close</string> - </property> - <property name="shortcut"> - <string>Ctrl+W</string> - </property> - </action> - <action name="actionSave"> - <property name="text"> - <string>Save</string> - </property> - <property name="shortcut"> - <string>Ctrl+S</string> - </property> - </action> - <action name="actionSave_As"> - <property name="text"> - <string>Save As...</string> - </property> - <property name="shortcut"> - <string>Ctrl+Shift+S</string> - </property> - </action> - <action name="actionUndo"> - <property name="text"> - <string>Undo</string> - </property> - <property name="shortcut"> - <string>Ctrl+Z</string> - </property> - </action> - <action name="actionRedo"> - <property name="text"> - <string>Redo</string> - </property> - <property name="shortcut"> - <string>Ctrl+Shift+Z</string> - </property> - </action> - <action name="actionCut"> - <property name="text"> - <string>Cut</string> - </property> - <property name="shortcut"> - <string>Ctrl+X</string> - </property> - </action> - <action name="actionCopy"> - <property name="text"> - <string>Copy</string> - </property> - <property name="shortcut"> - <string>Ctrl+C</string> - </property> - </action> - <action name="actionPaste"> - <property name="text"> - <string>Paste</string> - </property> - <property name="shortcut"> - <string>Ctrl+V</string> - </property> - </action> - <action name="actionDelete"> - <property name="text"> - <string>Delete</string> - </property> - <property name="shortcut"> - <string>Backspace</string> - </property> - </action> - <action name="actionSelect_All"> - <property name="text"> - <string>Select All</string> - </property> - <property name="shortcut"> - <string>Ctrl+A</string> - </property> - </action> - <action name="actionDeselect_All"> - <property name="text"> - <string>Deselect All</string> - </property> - <property name="shortcut"> - <string>Ctrl+D</string> - </property> - </action> - <action name="actionParse"> - <property name="text"> - <string>Parse Tikz</string> - </property> - <property name="shortcut"> - <string>Ctrl+T</string> - </property> - </action> - <action name="actionZoom_In"> - <property name="text"> - <string>Zoom In</string> - </property> - <property name="shortcut"> - <string>Ctrl+=</string> - </property> - </action> - <action name="actionZoom_Out"> - <property name="text"> - <string>Zoom Out</string> - </property> - <property name="shortcut"> - <string>Ctrl+-</string> - </property> - </action> - <action name="actionExit"> - <property name="text"> - <string>Exit</string> - </property> - </action> - <action name="actionRevert"> - <property name="text"> - <string>Revert Tikz</string> - </property> - </action> - <action name="actionJump_to_Selection"> - <property name="text"> - <string>Jump to Selection</string> - </property> - <property name="shortcut"> - <string>Ctrl+J</string> - </property> - </action> - <addaction name="menuFile"/> - <addaction name="menuEdit"/> - <addaction name="menuView"/> - <addaction name="menuTikz"/> - </widget> - <resources/> - <connections/> -</ui> +<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainMenu</class>
+ <widget class="QMenuBar" name="MainMenu">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>476</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="actionNew"/>
+ <addaction name="actionOpen"/>
+ <addaction name="separator"/>
+ <addaction name="actionClose"/>
+ <addaction name="actionSave"/>
+ <addaction name="actionSave_As"/>
+ <addaction name="separator"/>
+ <addaction name="actionExit"/>
+ </widget>
+ <widget class="QMenu" name="menuEdit">
+ <property name="title">
+ <string>Edit</string>
+ </property>
+ <addaction name="actionUndo"/>
+ <addaction name="actionRedo"/>
+ <addaction name="separator"/>
+ <addaction name="actionCut"/>
+ <addaction name="actionCopy"/>
+ <addaction name="actionPaste"/>
+ <addaction name="actionDelete"/>
+ <addaction name="separator"/>
+ <addaction name="actionSelect_All"/>
+ <addaction name="actionDeselect_All"/>
+ </widget>
+ <widget class="QMenu" name="menuTikz">
+ <property name="title">
+ <string>Tikz</string>
+ </property>
+ <addaction name="actionParse"/>
+ <addaction name="actionRevert"/>
+ <addaction name="actionJump_to_Selection"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>View</string>
+ </property>
+ <addaction name="actionZoom_In"/>
+ <addaction name="actionZoom_Out"/>
+ </widget>
+ <action name="actionNew">
+ <property name="text">
+ <string>New...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ </action>
+ <action name="actionOpen">
+ <property name="text">
+ <string>Open...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+W</string>
+ </property>
+ </action>
+ <action name="actionSave">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ <action name="actionSave_As">
+ <property name="text">
+ <string>Save As...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+S</string>
+ </property>
+ </action>
+ <action name="actionUndo">
+ <property name="text">
+ <string>Undo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Z</string>
+ </property>
+ </action>
+ <action name="actionRedo">
+ <property name="text">
+ <string>Redo</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+Z</string>
+ </property>
+ </action>
+ <action name="actionCut">
+ <property name="text">
+ <string>Cut</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+X</string>
+ </property>
+ </action>
+ <action name="actionCopy">
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionPaste">
+ <property name="text">
+ <string>Paste</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+V</string>
+ </property>
+ </action>
+ <action name="actionDelete">
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Backspace</string>
+ </property>
+ </action>
+ <action name="actionSelect_All">
+ <property name="text">
+ <string>Select All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+A</string>
+ </property>
+ </action>
+ <action name="actionDeselect_All">
+ <property name="text">
+ <string>Deselect All</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+D</string>
+ </property>
+ </action>
+ <action name="actionParse">
+ <property name="text">
+ <string>Parse Tikz</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ <action name="actionZoom_In">
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+=</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out">
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+-</string>
+ </property>
+ </action>
+ <action name="actionExit">
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </action>
+ <action name="actionRevert">
+ <property name="text">
+ <string>Revert Tikz</string>
+ </property>
+ </action>
+ <action name="actionJump_to_Selection">
+ <property name="text">
+ <string>Jump to Selection</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+J</string>
+ </property>
+ </action>
+ <addaction name="menuFile"/>
+ <addaction name="menuEdit"/>
+ <addaction name="menuView"/>
+ <addaction name="menuTikz"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 15b6943..953889e 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -1,160 +1,160 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" - -#include "mainmenu.h" -#include "tikzassembler.h" -#include "toolpalette.h" -#include "tikzit.h" - -#include <QDebug> -#include <QFile> -#include <QList> -#include <QSettings> -#include <QMessageBox> -#include <QFileDialog> -#include <QTextEdit> -#include <QTextBlock> - -int MainWindow::_numWindows = 0; - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) -{ - _windowId = _numWindows; - _numWindows++; - ui->setupUi(this); - setAttribute(Qt::WA_DeleteOnClose, true); - _tikzDocument = new TikzDocument(this); - - _toolPalette = new ToolPalette(this); - addToolBar(_toolPalette); - - _stylePalette = new StylePalette(this); - addDockWidget(Qt::RightDockWidgetArea, _stylePalette); - - _tikzScene = new TikzScene(_tikzDocument, _toolPalette, _stylePalette, this); - ui->tikzView->setScene(_tikzScene); - - // TODO: check if each window should have a menu - _menu = new MainMenu(); - _menu->setParent(this); - - setMenuBar(_menu); - - // initially, the source view should be collapsed - QList<int> sz = ui->splitter->sizes(); - sz[0] = sz[0] + sz[1]; - sz[1] = 0; - ui->splitter->setSizes(sz); - - _tikzDocument->refreshTikz(); - - connect(_tikzDocument->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateFileName())); -} - -MainWindow::~MainWindow() -{ - tikzit->removeWindow(this); - delete ui; -} - -void MainWindow::open(QString fileName) -{ - _tikzDocument->open(fileName); - - //ui->tikzSource->setText(_tikzDocument->tikz()); - - - if (_tikzDocument->parseSuccess()) { - statusBar()->showMessage("TiKZ parsed successfully", 2000); - //setWindowTitle("TiKZiT - " + _tikzDocument->shortName()); - _tikzScene->setTikzDocument(_tikzDocument); - updateFileName(); - } else { - statusBar()->showMessage("Cannot read TiKZ source"); - } - -} - -void MainWindow::closeEvent(QCloseEvent *event) -{ - qDebug() << "got close event"; - QMainWindow::closeEvent(event); -} - -void MainWindow::changeEvent(QEvent *event) -{ - if (event->type() == QEvent::ActivationChange && isActiveWindow()) { - tikzit->setActiveWindow(this); - //tikzit->stylePalette()->raise(); - } - QMainWindow::changeEvent(event); -} - -StylePalette *MainWindow::stylePalette() const -{ - return _stylePalette; -} - -QString MainWindow::tikzSource() -{ - return ui->tikzSource->toPlainText(); -} - -void MainWindow::setSourceLine(int line) -{ - QTextCursor cursor(ui->tikzSource->document()->findBlockByLineNumber(line)); - cursor.movePosition(QTextCursor::EndOfLine); - //ui->tikzSource->moveCursor(QTextCursor::End); - ui->tikzSource->setTextCursor(cursor); - ui->tikzSource->setFocus(); -} - -void MainWindow::updateFileName() -{ - QString nm = _tikzDocument->shortName(); - if (nm.isEmpty()) nm = "untitled"; - if (!_tikzDocument->isClean()) nm += "*"; - setWindowTitle("TiKZiT - " + nm); -} - -void MainWindow::refreshTikz() -{ - // don't emit textChanged() when we update the tikz - ui->tikzSource->blockSignals(true); - ui->tikzSource->setText(_tikzDocument->tikz()); - ui->tikzSource->blockSignals(false); -} - -ToolPalette *MainWindow::toolPalette() const -{ - return _toolPalette; -} - -TikzDocument *MainWindow::tikzDocument() const -{ - return _tikzDocument; -} - -TikzScene *MainWindow::tikzScene() const -{ - return _tikzScene; -} - -int MainWindow::windowId() const -{ - return _windowId; -} - -TikzView *MainWindow::tikzView() const -{ - return ui->tikzView; -} - -void MainWindow::on_tikzSource_textChanged() -{ - if (_tikzScene->enabled()) _tikzScene->setEnabled(false); -} - - +#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include "mainmenu.h"
+#include "tikzassembler.h"
+#include "toolpalette.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QFile>
+#include <QList>
+#include <QSettings>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QTextEdit>
+#include <QTextBlock>
+
+int MainWindow::_numWindows = 0;
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ _windowId = _numWindows;
+ _numWindows++;
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ _tikzDocument = new TikzDocument(this);
+
+ _toolPalette = new ToolPalette(this);
+ addToolBar(_toolPalette);
+
+ _stylePalette = new StylePalette(this);
+ addDockWidget(Qt::RightDockWidgetArea, _stylePalette);
+
+ _tikzScene = new TikzScene(_tikzDocument, _toolPalette, _stylePalette, this);
+ ui->tikzView->setScene(_tikzScene);
+
+ // TODO: check if each window should have a menu
+ _menu = new MainMenu();
+ _menu->setParent(this);
+
+ setMenuBar(_menu);
+
+ // initially, the source view should be collapsed
+ QList<int> sz = ui->splitter->sizes();
+ sz[0] = sz[0] + sz[1];
+ sz[1] = 0;
+ ui->splitter->setSizes(sz);
+
+ _tikzDocument->refreshTikz();
+
+ connect(_tikzDocument->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateFileName()));
+}
+
+MainWindow::~MainWindow()
+{
+ tikzit->removeWindow(this);
+ delete ui;
+}
+
+void MainWindow::open(QString fileName)
+{
+ _tikzDocument->open(fileName);
+
+ //ui->tikzSource->setText(_tikzDocument->tikz());
+
+
+ if (_tikzDocument->parseSuccess()) {
+ statusBar()->showMessage("TiKZ parsed successfully", 2000);
+ //setWindowTitle("TiKZiT - " + _tikzDocument->shortName());
+ _tikzScene->setTikzDocument(_tikzDocument);
+ updateFileName();
+ } else {
+ statusBar()->showMessage("Cannot read TiKZ source");
+ }
+
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ qDebug() << "got close event";
+ QMainWindow::closeEvent(event);
+}
+
+void MainWindow::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::ActivationChange && isActiveWindow()) {
+ tikzit->setActiveWindow(this);
+ //tikzit->stylePalette()->raise();
+ }
+ QMainWindow::changeEvent(event);
+}
+
+StylePalette *MainWindow::stylePalette() const
+{
+ return _stylePalette;
+}
+
+QString MainWindow::tikzSource()
+{
+ return ui->tikzSource->toPlainText();
+}
+
+void MainWindow::setSourceLine(int line)
+{
+ QTextCursor cursor(ui->tikzSource->document()->findBlockByLineNumber(line));
+ cursor.movePosition(QTextCursor::EndOfLine);
+ //ui->tikzSource->moveCursor(QTextCursor::End);
+ ui->tikzSource->setTextCursor(cursor);
+ ui->tikzSource->setFocus();
+}
+
+void MainWindow::updateFileName()
+{
+ QString nm = _tikzDocument->shortName();
+ if (nm.isEmpty()) nm = "untitled";
+ if (!_tikzDocument->isClean()) nm += "*";
+ setWindowTitle("TiKZiT - " + nm);
+}
+
+void MainWindow::refreshTikz()
+{
+ // don't emit textChanged() when we update the tikz
+ ui->tikzSource->blockSignals(true);
+ ui->tikzSource->setText(_tikzDocument->tikz());
+ ui->tikzSource->blockSignals(false);
+}
+
+ToolPalette *MainWindow::toolPalette() const
+{
+ return _toolPalette;
+}
+
+TikzDocument *MainWindow::tikzDocument() const
+{
+ return _tikzDocument;
+}
+
+TikzScene *MainWindow::tikzScene() const
+{
+ return _tikzScene;
+}
+
+int MainWindow::windowId() const
+{
+ return _windowId;
+}
+
+TikzView *MainWindow::tikzView() const
+{
+ return ui->tikzView;
+}
+
+void MainWindow::on_tikzSource_textChanged()
+{
+ if (_tikzScene->enabled()) _tikzScene->setEnabled(false);
+}
+
+
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index 1e05239..3ab641c 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -1,60 +1,60 @@ -/*! - * A top-level window, which contains a single TikzDocument. - */ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include "tikzscene.h" -#include "tikzview.h" -#include "graph.h" -#include "tikzdocument.h" -#include "mainmenu.h" -#include "toolpalette.h" -#include "stylepalette.h" - -#include <QMainWindow> -#include <QGraphicsView> - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - - void open(QString fileName); - int windowId() const; - TikzView *tikzView() const; - TikzScene *tikzScene() const; - TikzDocument *tikzDocument() const; - ToolPalette *toolPalette() const; - StylePalette *stylePalette() const; - QString tikzSource(); - void setSourceLine(int line); - -public slots: - void on_tikzSource_textChanged(); - void updateFileName(); - void refreshTikz(); -protected: - void closeEvent(QCloseEvent *event); - void changeEvent(QEvent *event); - -private: - TikzScene *_tikzScene; - TikzDocument *_tikzDocument; - MainMenu *_menu; - ToolPalette *_toolPalette; - StylePalette *_stylePalette; - Ui::MainWindow *ui; - int _windowId; - static int _numWindows; -}; - -#endif // MAINWINDOW_H +/*!
+ * A top-level window, which contains a single TikzDocument.
+ */
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "tikzscene.h"
+#include "tikzview.h"
+#include "graph.h"
+#include "tikzdocument.h"
+#include "mainmenu.h"
+#include "toolpalette.h"
+#include "stylepalette.h"
+
+#include <QMainWindow>
+#include <QGraphicsView>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ void open(QString fileName);
+ int windowId() const;
+ TikzView *tikzView() const;
+ TikzScene *tikzScene() const;
+ TikzDocument *tikzDocument() const;
+ ToolPalette *toolPalette() const;
+ StylePalette *stylePalette() const;
+ QString tikzSource();
+ void setSourceLine(int line);
+
+public slots:
+ void on_tikzSource_textChanged();
+ void updateFileName();
+ void refreshTikz();
+protected:
+ void closeEvent(QCloseEvent *event);
+ void changeEvent(QEvent *event);
+
+private:
+ TikzScene *_tikzScene;
+ TikzDocument *_tikzDocument;
+ MainMenu *_menu;
+ ToolPalette *_toolPalette;
+ StylePalette *_stylePalette;
+ Ui::MainWindow *ui;
+ int _windowId;
+ static int _numWindows;
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui index 137d6cf..3df579f 100644 --- a/src/gui/mainwindow.ui +++ b/src/gui/mainwindow.ui @@ -1,205 +1,205 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>640</width> - <height>580</height> - </rect> - </property> - <property name="windowTitle"> - <string>TikZiT - untitled</string> - </property> - <widget class="QWidget" name="centralWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <widget class="QSplitter" name="splitter"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <widget class="TikzView" name="tikzView"/> - <widget class="QTextEdit" name="tikzSource"> - <property name="font"> - <font> - <family>Courier New</family> - <pointsize>10</pointsize> - </font> - </property> - <property name="lineWrapMode"> - <enum>QTextEdit::NoWrap</enum> - </property> - <property name="html"> - <string><!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 b452848..d308dd2 100644 --- a/src/gui/nodeitem.cpp +++ b/src/gui/nodeitem.cpp @@ -1,159 +1,159 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "tikzit.h" -#include "nodeitem.h" -#include "tikzscene.h" -#include <cmath> - -#include <QPen> -#include <QApplication> -#include <QBrush> -#include <QDebug> -#include <QFont> -#include <QFontMetrics> -#include <QPainterPathStroker> - -NodeItem::NodeItem(Node *node) -{ - _node = node; - setFlag(QGraphicsItem::ItemIsSelectable); - //setFlag(QGraphicsItem::ItemIsMovable); - //setFlag(QGraphicsItem::ItemSendsGeometryChanges); - readPos(); - updateBounds(); -} - -void NodeItem::readPos() -{ - setPos(toScreen(_node->point())); -} - -void NodeItem::writePos() -{ - _node->setPoint(fromScreen(pos())); -} - -QRectF NodeItem::labelRect() const { - QString label = _node->label(); - //QFont f("Courier", 9); - QFontMetrics fm(Tikzit::LABEL_FONT); - - QRectF rect = fm.boundingRect(label); - //rect.adjust(-2,-2,2,2); - rect.moveCenter(QPointF(0,0)); - return rect; -} - -void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - if (_node->style()->isNone()) { - QColor c(180,180,200); - painter->setPen(QPen(c)); - painter->setBrush(QBrush(c)); - painter->drawEllipse(QPointF(0,0), 1,1); - - QPen pen(QColor(180,180,220)); - QVector<qreal> p; - p << 1.0 << 2.0; - pen.setDashPattern(p); - pen.setWidthF(2.0f); - painter->setPen(pen); - painter->setBrush(Qt::NoBrush); - painter->drawPath(shape()); - } else { - QPen pen(_node->style()->strokeColor()); - pen.setWidth(_node->style()->strokeThickness()); - painter->setPen(pen); - painter->setBrush(QBrush(_node->style()->fillColor())); - painter->drawPath(shape()); - } - - if (_node->label() != "") { - QRectF rect = labelRect(); - QPen pen(QColor(200,0,0,120)); - QVector<qreal> d; - d << 2.0 << 2.0; - pen.setDashPattern(d); - painter->setPen(pen); - painter->setBrush(QBrush(QColor(255,255,100,120))); - painter->drawRect(rect); - - painter->setPen(QPen(Qt::black)); - painter->setFont(Tikzit::LABEL_FONT); - painter->drawText(rect, Qt::AlignCenter, _node->label()); - } - - if (isSelected()) { - QPainterPath sh = shape(); - QPainterPathStroker stroker; - stroker.setWidth(4); - QPainterPath outline = (stroker.createStroke(sh) + sh).simplified(); - painter->setPen(Qt::NoPen); - painter->setBrush(QBrush(QColor(150,200,255,100))); - painter->drawPath(outline); - } - -} - -QPainterPath NodeItem::shape() const -{ - QPainterPath path; - path.addEllipse(QPointF(0,0), GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2); - return path; -} - -// TODO: nodeitem should sync boundingRect()-relevant stuff (label etc) explicitly, -// to allow prepareGeometryChange() -QRectF NodeItem::boundingRect() const -{ - return _boundingRect; -} - -void NodeItem::updateBounds() -{ - prepareGeometryChange(); - QString label = _node->label(); - if (label != "") { - QFontMetrics fm(Tikzit::LABEL_FONT); - QRectF labelRect = fm.boundingRect(label); - labelRect.moveCenter(QPointF(0, 0)); - _boundingRect = labelRect.united(shape().boundingRect()).adjusted(-4, -4, 4, 4); - } else { - _boundingRect = shape().boundingRect().adjusted(-4, -4, 4, 4); - } -} - -Node *NodeItem::node() const -{ - return _node; -} - -//QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value) -//{ -// if (change == ItemPositionChange) { -// QPointF newPos = value.toPointF(); -// int gridSize = GLOBAL_SCALE / 8; -// QPointF gridPos(round(newPos.x()/gridSize)*gridSize, round(newPos.y()/gridSize)*gridSize); -// _node->setPoint(fromScreen(gridPos)); -// -// return gridPos; -// } else { -// return QGraphicsItem::itemChange(change, value); -// } -//} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "nodeitem.h"
+#include "tikzscene.h"
+#include <cmath>
+
+#include <QPen>
+#include <QApplication>
+#include <QBrush>
+#include <QDebug>
+#include <QFont>
+#include <QFontMetrics>
+#include <QPainterPathStroker>
+
+NodeItem::NodeItem(Node *node)
+{
+ _node = node;
+ setFlag(QGraphicsItem::ItemIsSelectable);
+ //setFlag(QGraphicsItem::ItemIsMovable);
+ //setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ readPos();
+ updateBounds();
+}
+
+void NodeItem::readPos()
+{
+ setPos(toScreen(_node->point()));
+}
+
+void NodeItem::writePos()
+{
+ _node->setPoint(fromScreen(pos()));
+}
+
+QRectF NodeItem::labelRect() const {
+ QString label = _node->label();
+ //QFont f("Courier", 9);
+ QFontMetrics fm(Tikzit::LABEL_FONT);
+
+ QRectF rect = fm.boundingRect(label);
+ //rect.adjust(-2,-2,2,2);
+ rect.moveCenter(QPointF(0,0));
+ return rect;
+}
+
+void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ if (_node->style()->isNone()) {
+ QColor c(180,180,200);
+ painter->setPen(QPen(c));
+ painter->setBrush(QBrush(c));
+ painter->drawEllipse(QPointF(0,0), 1,1);
+
+ QPen pen(QColor(180,180,220));
+ QVector<qreal> p;
+ p << 1.0 << 2.0;
+ pen.setDashPattern(p);
+ pen.setWidthF(2.0f);
+ painter->setPen(pen);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(shape());
+ } else {
+ QPen pen(_node->style()->strokeColor());
+ pen.setWidth(_node->style()->strokeThickness());
+ painter->setPen(pen);
+ painter->setBrush(QBrush(_node->style()->fillColor()));
+ painter->drawPath(shape());
+ }
+
+ if (_node->label() != "") {
+ QRectF rect = labelRect();
+ QPen pen(QColor(200,0,0,120));
+ QVector<qreal> d;
+ d << 2.0 << 2.0;
+ pen.setDashPattern(d);
+ painter->setPen(pen);
+ painter->setBrush(QBrush(QColor(255,255,100,120)));
+ painter->drawRect(rect);
+
+ painter->setPen(QPen(Qt::black));
+ painter->setFont(Tikzit::LABEL_FONT);
+ painter->drawText(rect, Qt::AlignCenter, _node->label());
+ }
+
+ if (isSelected()) {
+ QPainterPath sh = shape();
+ QPainterPathStroker stroker;
+ stroker.setWidth(4);
+ QPainterPath outline = (stroker.createStroke(sh) + sh).simplified();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(QBrush(QColor(150,200,255,100)));
+ painter->drawPath(outline);
+ }
+
+}
+
+QPainterPath NodeItem::shape() const
+{
+ QPainterPath path;
+ path.addEllipse(QPointF(0,0), GLOBAL_SCALEF * 0.2, GLOBAL_SCALEF * 0.2);
+ return path;
+}
+
+// TODO: nodeitem should sync boundingRect()-relevant stuff (label etc) explicitly,
+// to allow prepareGeometryChange()
+QRectF NodeItem::boundingRect() const
+{
+ return _boundingRect;
+}
+
+void NodeItem::updateBounds()
+{
+ prepareGeometryChange();
+ QString label = _node->label();
+ if (label != "") {
+ QFontMetrics fm(Tikzit::LABEL_FONT);
+ QRectF labelRect = fm.boundingRect(label);
+ labelRect.moveCenter(QPointF(0, 0));
+ _boundingRect = labelRect.united(shape().boundingRect()).adjusted(-4, -4, 4, 4);
+ } else {
+ _boundingRect = shape().boundingRect().adjusted(-4, -4, 4, 4);
+ }
+}
+
+Node *NodeItem::node() const
+{
+ return _node;
+}
+
+//QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value)
+//{
+// if (change == ItemPositionChange) {
+// QPointF newPos = value.toPointF();
+// int gridSize = GLOBAL_SCALE / 8;
+// QPointF gridPos(round(newPos.x()/gridSize)*gridSize, round(newPos.y()/gridSize)*gridSize);
+// _node->setPoint(fromScreen(gridPos));
+//
+// return gridPos;
+// } else {
+// return QGraphicsItem::itemChange(change, value);
+// }
+//}
diff --git a/src/gui/nodeitem.h b/src/gui/nodeitem.h index 678a7e8..efd32f1 100644 --- a/src/gui/nodeitem.h +++ b/src/gui/nodeitem.h @@ -1,51 +1,51 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * A QGraphicsItem that handles drawing a single node. - */ - -#ifndef NODEITEM_H -#define NODEITEM_H - -#include "node.h" - -#include <QObject> -#include <QGraphicsItem> -#include <QPainterPath> -#include <QRectF> - -class NodeItem : public QGraphicsItem -{ -public: - NodeItem(Node *node); - void readPos(); - void writePos(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - QPainterPath shape() const override; - QRectF boundingRect() const override; - void updateBounds(); - Node *node() const; - -private: - Node *_node; - QRectF labelRect() const; - QRectF _boundingRect; -}; - -#endif // NODEITEM_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A QGraphicsItem that handles drawing a single node.
+ */
+
+#ifndef NODEITEM_H
+#define NODEITEM_H
+
+#include "node.h"
+
+#include <QObject>
+#include <QGraphicsItem>
+#include <QPainterPath>
+#include <QRectF>
+
+class NodeItem : public QGraphicsItem
+{
+public:
+ NodeItem(Node *node);
+ void readPos();
+ void writePos();
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
+ QPainterPath shape() const override;
+ QRectF boundingRect() const override;
+ void updateBounds();
+ Node *node() const;
+
+private:
+ Node *_node;
+ QRectF labelRect() const;
+ QRectF _boundingRect;
+};
+
+#endif // NODEITEM_H
diff --git a/src/gui/propertypalette.cpp b/src/gui/propertypalette.cpp index c27b8b2..e2b8b8d 100644 --- a/src/gui/propertypalette.cpp +++ b/src/gui/propertypalette.cpp @@ -1,61 +1,61 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "propertypalette.h" -#include "graphelementdata.h" -#include "ui_propertypalette.h" - -#include <QModelIndex> -#include <QDebug> -#include <QCloseEvent> -#include <QSettings> - -PropertyPalette::PropertyPalette(QWidget *parent) : - QDockWidget(parent), - ui(new Ui::PropertyPalette) -{ - setWindowFlags(Qt::Window - | Qt::CustomizeWindowHint - | Qt::WindowTitleHint); - //setFocusPolicy(Qt::NoFocus); - ui->setupUi(this); - GraphElementData *d = new GraphElementData(); - d->setProperty("key 1", "value 1"); - d->setAtom("atom 1"); - d->setProperty("key 2", "value 2"); - - //QModelIndex i = d->index(0,0); - //ui->treeView->setModel(d); - - QSettings settings("tikzit", "tikzit"); - QVariant geom = settings.value("property-palette-geometry"); - if (geom != QVariant()) { - restoreGeometry(geom.toByteArray()); - } -} - -PropertyPalette::~PropertyPalette() -{ - delete ui; -} - -void PropertyPalette::closeEvent(QCloseEvent *event) { - QSettings settings("tikzit", "tikzit"); - settings.setValue("property-palette-geometry", saveGeometry()); - QDockWidget::closeEvent(event); -} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "propertypalette.h"
+#include "graphelementdata.h"
+#include "ui_propertypalette.h"
+
+#include <QModelIndex>
+#include <QDebug>
+#include <QCloseEvent>
+#include <QSettings>
+
+PropertyPalette::PropertyPalette(QWidget *parent) :
+ QDockWidget(parent),
+ ui(new Ui::PropertyPalette)
+{
+ setWindowFlags(Qt::Window
+ | Qt::CustomizeWindowHint
+ | Qt::WindowTitleHint);
+ //setFocusPolicy(Qt::NoFocus);
+ ui->setupUi(this);
+ GraphElementData *d = new GraphElementData();
+ d->setProperty("key 1", "value 1");
+ d->setAtom("atom 1");
+ d->setProperty("key 2", "value 2");
+
+ //QModelIndex i = d->index(0,0);
+ //ui->treeView->setModel(d);
+
+ QSettings settings("tikzit", "tikzit");
+ QVariant geom = settings.value("property-palette-geometry");
+ if (geom != QVariant()) {
+ restoreGeometry(geom.toByteArray());
+ }
+}
+
+PropertyPalette::~PropertyPalette()
+{
+ delete ui;
+}
+
+void PropertyPalette::closeEvent(QCloseEvent *event) {
+ QSettings settings("tikzit", "tikzit");
+ settings.setValue("property-palette-geometry", saveGeometry());
+ QDockWidget::closeEvent(event);
+}
diff --git a/src/gui/propertypalette.h b/src/gui/propertypalette.h index 29fb0af..1241123 100644 --- a/src/gui/propertypalette.h +++ b/src/gui/propertypalette.h @@ -1,46 +1,46 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * Enables the user to edit properties of the graph, as well as the selected node/edge. - */ - -#ifndef PROPERTYPALETTE_H -#define PROPERTYPALETTE_H - -#include <QDockWidget> - -namespace Ui { -class PropertyPalette; -} - -class PropertyPalette : public QDockWidget -{ - Q_OBJECT - -public: - explicit PropertyPalette(QWidget *parent = 0); - ~PropertyPalette(); - -protected: - void closeEvent(QCloseEvent *event); -private: - Ui::PropertyPalette *ui; -}; - -#endif // PROPERTYPALETTE_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Enables the user to edit properties of the graph, as well as the selected node/edge.
+ */
+
+#ifndef PROPERTYPALETTE_H
+#define PROPERTYPALETTE_H
+
+#include <QDockWidget>
+
+namespace Ui {
+class PropertyPalette;
+}
+
+class PropertyPalette : public QDockWidget
+{
+ Q_OBJECT
+
+public:
+ explicit PropertyPalette(QWidget *parent = 0);
+ ~PropertyPalette();
+
+protected:
+ void closeEvent(QCloseEvent *event);
+private:
+ Ui::PropertyPalette *ui;
+};
+
+#endif // PROPERTYPALETTE_H
diff --git a/src/gui/propertypalette.ui b/src/gui/propertypalette.ui index a8ba5d2..f5ccebd 100644 --- a/src/gui/propertypalette.ui +++ b/src/gui/propertypalette.ui @@ -1,33 +1,33 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PropertyPalette</class> - <widget class="QDockWidget" name="PropertyPalette"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>194</width> - <height>341</height> - </rect> - </property> - <property name="floating"> - <bool>false</bool> - </property> - <property name="windowTitle"> - <string>Properties</string> - </property> - <widget class="QWidget" name="dockWidgetContents"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTreeView" name="treeView"> - <property name="indentation"> - <number>0</number> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - <resources/> - <connections/> -</ui> +<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PropertyPalette</class>
+ <widget class="QDockWidget" name="PropertyPalette">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>194</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property name="floating">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string>Properties</string>
+ </property>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/gui/stylepalette.cpp b/src/gui/stylepalette.cpp index e3fea0b..42d440e 100644 --- a/src/gui/stylepalette.cpp +++ b/src/gui/stylepalette.cpp @@ -1,179 +1,179 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "stylepalette.h" -#include "ui_stylepalette.h" -#include "tikzit.h" - -#include <QDebug> -#include <QIcon> -#include <QSize> -#include <QSettings> -#include <QPainter> -#include <QPixmap> -#include <QPainterPath> - -StylePalette::StylePalette(QWidget *parent) : - QDockWidget(parent), - ui(new Ui::StylePalette) -{ - ui->setupUi(this); - -// QSettings settings("tikzit", "tikzit"); -// QVariant geom = settings.value("style-palette-geometry"); -// if (geom != QVariant()) { -// restoreGeometry(geom.toByteArray()); -// } - - _nodeModel = new QStandardItemModel(this); - _edgeModel = new QStandardItemModel(this); - - ui->styleListView->setModel(_nodeModel); - ui->styleListView->setViewMode(QListView::IconMode); - ui->styleListView->setMovement(QListView::Static); - ui->styleListView->setGridSize(QSize(48,48)); - - - ui->edgeStyleListView->setModel(_edgeModel); - ui->edgeStyleListView->setViewMode(QListView::IconMode); - ui->edgeStyleListView->setMovement(QListView::Static); - ui->edgeStyleListView->setGridSize(QSize(48,48)); - - reloadStyles(); - - connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( nodeStyleDoubleClicked(const QModelIndex&)) ); -} - -StylePalette::~StylePalette() -{ - delete ui; -} - -void StylePalette::reloadStyles() -{ - _nodeModel->clear(); - _edgeModel->clear(); - QString f = tikzit->styleFile(); - ui->styleFile->setText(f); - - QStandardItem *it; - - it = new QStandardItem(noneStyle->icon(), noneStyle->name()); - it->setEditable(false); - it->setData(noneStyle->name()); - _nodeModel->appendRow(it); - - foreach(NodeStyle *ns, tikzit->styles()->nodeStyles()) { - it = new QStandardItem(ns->icon(), ns->name()); - it->setEditable(false); - it->setData(ns->name()); - _nodeModel->appendRow(it); - } - - it = new QStandardItem(noneEdgeStyle->icon(), noneEdgeStyle->name()); - it->setEditable(false); - it->setData(noneEdgeStyle->name()); - _edgeModel->appendRow(it); - - foreach(EdgeStyle *es, tikzit->styles()->edgeStyles()) { - it = new QStandardItem(es->icon(), es->name()); - it->setEditable(false); - it->setData(es->name()); - _edgeModel->appendRow(it); - } -} - -void StylePalette::changeNodeStyle(int increment) -{ - QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes(); - int row = 0; - if (!i.isEmpty()) { - int row = (i[0].row()+increment)%_nodeModel->rowCount(); - if (row < 0) row += _nodeModel->rowCount(); - } - - QModelIndex i1 = ui->styleListView->rootIndex().child(row, 0); - ui->styleListView->selectionModel()->select(i1, QItemSelectionModel::ClearAndSelect); - ui->styleListView->scrollTo(i1); -} - -void StylePalette::nextNodeStyle() -{ - changeNodeStyle(1); -} - -void StylePalette::previousNodeStyle() -{ - changeNodeStyle(-1); -} - -QString StylePalette::activeNodeStyleName() -{ - const QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes(); - - if (i.isEmpty()) { - return "none"; - } else { - return i[0].data().toString(); - } -} - -QString StylePalette::activeEdgeStyleName() -{ - const QModelIndexList i = ui->edgeStyleListView->selectionModel()->selectedIndexes(); - - if (i.isEmpty()) { - return "none"; - } else { - return i[0].data().toString(); - } -} - -void StylePalette::nodeStyleDoubleClicked(const QModelIndex &index) -{ - tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes(); -} - -void StylePalette::edgeStyleDoubleClicked(const QModelIndex &index) -{ - // TODO -} - -void StylePalette::on_buttonOpenTikzstyles_clicked() -{ - tikzit->openTikzStyles(); -} - -void StylePalette::on_buttonRefreshTikzstyles_clicked() -{ - QSettings settings("tikzit", "tikzit"); - QString path = settings.value("previous-tikzstyles-file").toString(); - if (!path.isEmpty()) tikzit->loadStyles(path); -} - -//void StylePalette::on_buttonApplyNodeStyle_clicked() -//{ -// if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes(); -//} - -void StylePalette::closeEvent(QCloseEvent *event) -{ - QSettings settings("tikzit", "tikzit"); - settings.setValue("style-palette-geometry", saveGeometry()); - QDockWidget::closeEvent(event); -} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "stylepalette.h"
+#include "ui_stylepalette.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QIcon>
+#include <QSize>
+#include <QSettings>
+#include <QPainter>
+#include <QPixmap>
+#include <QPainterPath>
+
+StylePalette::StylePalette(QWidget *parent) :
+ QDockWidget(parent),
+ ui(new Ui::StylePalette)
+{
+ ui->setupUi(this);
+
+// QSettings settings("tikzit", "tikzit");
+// QVariant geom = settings.value("style-palette-geometry");
+// if (geom != QVariant()) {
+// restoreGeometry(geom.toByteArray());
+// }
+
+ _nodeModel = new QStandardItemModel(this);
+ _edgeModel = new QStandardItemModel(this);
+
+ ui->styleListView->setModel(_nodeModel);
+ ui->styleListView->setViewMode(QListView::IconMode);
+ ui->styleListView->setMovement(QListView::Static);
+ ui->styleListView->setGridSize(QSize(48,48));
+
+
+ ui->edgeStyleListView->setModel(_edgeModel);
+ ui->edgeStyleListView->setViewMode(QListView::IconMode);
+ ui->edgeStyleListView->setMovement(QListView::Static);
+ ui->edgeStyleListView->setGridSize(QSize(48,48));
+
+ reloadStyles();
+
+ connect(ui->styleListView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT( nodeStyleDoubleClicked(const QModelIndex&)) );
+}
+
+StylePalette::~StylePalette()
+{
+ delete ui;
+}
+
+void StylePalette::reloadStyles()
+{
+ _nodeModel->clear();
+ _edgeModel->clear();
+ QString f = tikzit->styleFile();
+ ui->styleFile->setText(f);
+
+ QStandardItem *it;
+
+ it = new QStandardItem(noneStyle->icon(), noneStyle->name());
+ it->setEditable(false);
+ it->setData(noneStyle->name());
+ _nodeModel->appendRow(it);
+
+ foreach(NodeStyle *ns, tikzit->styles()->nodeStyles()) {
+ it = new QStandardItem(ns->icon(), ns->name());
+ it->setEditable(false);
+ it->setData(ns->name());
+ _nodeModel->appendRow(it);
+ }
+
+ it = new QStandardItem(noneEdgeStyle->icon(), noneEdgeStyle->name());
+ it->setEditable(false);
+ it->setData(noneEdgeStyle->name());
+ _edgeModel->appendRow(it);
+
+ foreach(EdgeStyle *es, tikzit->styles()->edgeStyles()) {
+ it = new QStandardItem(es->icon(), es->name());
+ it->setEditable(false);
+ it->setData(es->name());
+ _edgeModel->appendRow(it);
+ }
+}
+
+void StylePalette::changeNodeStyle(int increment)
+{
+ QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
+ int row = 0;
+ if (!i.isEmpty()) {
+ int row = (i[0].row()+increment)%_nodeModel->rowCount();
+ if (row < 0) row += _nodeModel->rowCount();
+ }
+
+ QModelIndex i1 = ui->styleListView->rootIndex().child(row, 0);
+ ui->styleListView->selectionModel()->select(i1, QItemSelectionModel::ClearAndSelect);
+ ui->styleListView->scrollTo(i1);
+}
+
+void StylePalette::nextNodeStyle()
+{
+ changeNodeStyle(1);
+}
+
+void StylePalette::previousNodeStyle()
+{
+ changeNodeStyle(-1);
+}
+
+QString StylePalette::activeNodeStyleName()
+{
+ const QModelIndexList i = ui->styleListView->selectionModel()->selectedIndexes();
+
+ if (i.isEmpty()) {
+ return "none";
+ } else {
+ return i[0].data().toString();
+ }
+}
+
+QString StylePalette::activeEdgeStyleName()
+{
+ const QModelIndexList i = ui->edgeStyleListView->selectionModel()->selectedIndexes();
+
+ if (i.isEmpty()) {
+ return "none";
+ } else {
+ return i[0].data().toString();
+ }
+}
+
+void StylePalette::nodeStyleDoubleClicked(const QModelIndex &index)
+{
+ tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
+}
+
+void StylePalette::edgeStyleDoubleClicked(const QModelIndex &index)
+{
+ // TODO
+}
+
+void StylePalette::on_buttonOpenTikzstyles_clicked()
+{
+ tikzit->openTikzStyles();
+}
+
+void StylePalette::on_buttonRefreshTikzstyles_clicked()
+{
+ QSettings settings("tikzit", "tikzit");
+ QString path = settings.value("previous-tikzstyles-file").toString();
+ if (!path.isEmpty()) tikzit->loadStyles(path);
+}
+
+//void StylePalette::on_buttonApplyNodeStyle_clicked()
+//{
+// if (tikzit->activeWindow() != 0) tikzit->activeWindow()->tikzScene()->applyActiveStyleToNodes();
+//}
+
+void StylePalette::closeEvent(QCloseEvent *event)
+{
+ QSettings settings("tikzit", "tikzit");
+ settings.setValue("style-palette-geometry", saveGeometry());
+ QDockWidget::closeEvent(event);
+}
diff --git a/src/gui/stylepalette.h b/src/gui/stylepalette.h index 45dc8da..01daa90 100644 --- a/src/gui/stylepalette.h +++ b/src/gui/stylepalette.h @@ -1,61 +1,61 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#ifndef STYLEPALETTE_H -#define STYLEPALETTE_H - -#include <QDockWidget> -#include <QStandardItemModel> - -namespace Ui { -class StylePalette; -} - -class StylePalette : public QDockWidget -{ - Q_OBJECT - -public: - explicit StylePalette(QWidget *parent = 0); - ~StylePalette(); - void reloadStyles(); - void nextNodeStyle(); - void previousNodeStyle(); - QString activeNodeStyleName(); - QString activeEdgeStyleName(); - - -public slots: - void nodeStyleDoubleClicked(const QModelIndex &index); - void edgeStyleDoubleClicked(const QModelIndex &index); - void on_buttonOpenTikzstyles_clicked(); - void on_buttonRefreshTikzstyles_clicked(); - //void on_buttonApplyNodeStyle_clicked(); - -private: - void changeNodeStyle(int increment); - - Ui::StylePalette *ui; - QStandardItemModel *_nodeModel; - QStandardItemModel *_edgeModel; - -protected: - void closeEvent(QCloseEvent *event) override; -}; - -#endif // STYLEPALETTE_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef STYLEPALETTE_H
+#define STYLEPALETTE_H
+
+#include <QDockWidget>
+#include <QStandardItemModel>
+
+namespace Ui {
+class StylePalette;
+}
+
+class StylePalette : public QDockWidget
+{
+ Q_OBJECT
+
+public:
+ explicit StylePalette(QWidget *parent = 0);
+ ~StylePalette();
+ void reloadStyles();
+ void nextNodeStyle();
+ void previousNodeStyle();
+ QString activeNodeStyleName();
+ QString activeEdgeStyleName();
+
+
+public slots:
+ void nodeStyleDoubleClicked(const QModelIndex &index);
+ void edgeStyleDoubleClicked(const QModelIndex &index);
+ void on_buttonOpenTikzstyles_clicked();
+ void on_buttonRefreshTikzstyles_clicked();
+ //void on_buttonApplyNodeStyle_clicked();
+
+private:
+ void changeNodeStyle(int increment);
+
+ Ui::StylePalette *ui;
+ QStandardItemModel *_nodeModel;
+ QStandardItemModel *_edgeModel;
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+};
+
+#endif // STYLEPALETTE_H
diff --git a/src/gui/stylepalette.ui b/src/gui/stylepalette.ui index 4f5b58d..be8263e 100644 --- a/src/gui/stylepalette.ui +++ b/src/gui/stylepalette.ui @@ -1,120 +1,120 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>StylePalette</class> - <widget class="QDockWidget" name="StylePalette"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>88</width> - <height>518</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>88</width> - <height>191</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>88</width> - <height>524287</height> - </size> - </property> - <property name="floating"> - <bool>false</bool> - </property> - <property name="windowTitle"> - <string/> - </property> - <widget class="QWidget" name="dockWidgetContents"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <property name="spacing"> - <number>2</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QToolButton" name="buttonOpenTikzstyles"> - <property name="toolTip"> - <string>New Project</string> - </property> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="../../tikzit.qrc"> - <normaloff>:/images/document-open.svg</normaloff>:/images/document-open.svg</iconset> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="buttonRefreshTikzstyles"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset resource="../../tikzit.qrc"> - <normaloff>:/images/refresh.svg</normaloff>:/images/refresh.svg</iconset> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="styleFile"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>[default]</string> - </property> - </widget> - </item> - <item> - <widget class="QListView" name="styleListView"> - <property name="font"> - <font> - <pointsize>8</pointsize> - <italic>true</italic> - </font> - </property> - </widget> - </item> - <item> - <widget class="QListView" name="edgeStyleListView"/> - </item> - </layout> - </widget> - </widget> - <resources> - <include location="../../tikzit.qrc"/> - </resources> - <connections/> -</ui> +<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>StylePalette</class>
+ <widget class="QDockWidget" name="StylePalette">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>88</width>
+ <height>518</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>88</width>
+ <height>191</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>88</width>
+ <height>524287</height>
+ </size>
+ </property>
+ <property name="floating">
+ <bool>false</bool>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+ <widget class="QWidget" name="dockWidgetContents">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonOpenTikzstyles">
+ <property name="toolTip">
+ <string>New Project</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../tikzit.qrc">
+ <normaloff>:/images/document-open.svg</normaloff>:/images/document-open.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonRefreshTikzstyles">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../tikzit.qrc">
+ <normaloff>:/images/refresh.svg</normaloff>:/images/refresh.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="styleFile">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>[default]</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="styleListView">
+ <property name="font">
+ <font>
+ <pointsize>8</pointsize>
+ <italic>true</italic>
+ </font>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListView" name="edgeStyleListView"/>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources>
+ <include location="../../tikzit.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp index 47464fe..6f2994b 100644 --- a/src/gui/tikzscene.cpp +++ b/src/gui/tikzscene.cpp @@ -1,780 +1,780 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "tikzit.h" -#include "util.h" -#include "tikzscene.h" -#include "undocommands.h" -#include "tikzassembler.h" - -#include <QPen> -#include <QBrush> -#include <QDebug> -#include <QClipboard> -#include <QInputDialog> -#include <cmath> - - -TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, - StylePalette *styles, QObject *parent) : - QGraphicsScene(parent), _tikzDocument(tikzDocument), _tools(tools), _styles(styles) -{ - _modifyEdgeItem = 0; - _edgeStartNodeItem = 0; - _drawEdgeItem = new QGraphicsLineItem(); - _rubberBandItem = new QGraphicsRectItem(); - _enabled = true; - //setSceneRect(-310,-230,620,450); - setSceneRect(-1000,-1000,2000,2000); - - QPen pen; - pen.setColor(QColor::fromRgbF(0.5f, 0.0f, 0.5f)); - //pen.setWidth(3.0f); - pen.setCosmetic(true); - _drawEdgeItem->setPen(pen); - _drawEdgeItem->setLine(0,0,0,0); - _drawEdgeItem->setVisible(false); - addItem(_drawEdgeItem); - - pen.setColor(QColor::fromRgbF(0.6f, 0.6f, 0.8f)); - //pen.setWidth(3.0f); - //QVector<qreal> dash; - //dash << 4.0 << 4.0; - pen.setStyle(Qt::DashLine); - //pen.setDashPattern(dash); - _rubberBandItem->setPen(pen); - - QBrush brush(QColor::fromRgbF(0.6,0.6,0.8,0.2)); - _rubberBandItem->setBrush(brush); - - _rubberBandItem->setVisible(false); - addItem(_rubberBandItem); -} - -TikzScene::~TikzScene() { -} - -Graph *TikzScene::graph() -{ - return _tikzDocument->graph(); -} - -void TikzScene::graphReplaced() -{ - - foreach (NodeItem *ni, _nodeItems) { - removeItem(ni); - delete ni; - } - _nodeItems.clear(); - - foreach (EdgeItem *ei, _edgeItems) { - removeItem(ei); - delete ei; - } - _edgeItems.clear(); - - foreach (Edge *e, graph()->edges()) { - e->attachStyle(); - EdgeItem *ei = new EdgeItem(e); - _edgeItems.insert(e, ei); - addItem(ei); - } - - foreach (Node *n, graph()->nodes()) { - n->attachStyle(); - NodeItem *ni = new NodeItem(n); - _nodeItems.insert(n, ni); - addItem(ni); - } -} - -void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if (!_enabled) return; - - // current mouse position, in scene coordinates - _mouseDownPos = event->scenePos(); - - _draggingNodes = false; - - // disable rubber band drag, which will clear the selection. Only re-enable it - // for the SELECT tool, and when no control point has been clicked. - //views()[0]->setDragMode(QGraphicsView::NoDrag); - - // radius of a control point for bezier edges, in scene coordinates - qreal cpR = GLOBAL_SCALEF * (0.1); - qreal cpR2 = cpR * cpR; - - switch (_tools->currentTool()) { - case ToolPalette::SELECT: - // check if we grabbed a control point of an edge - foreach (QGraphicsItem *gi, selectedItems()) { - if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) { - qreal dx, dy; - - dx = ei->cp1Item()->pos().x() - _mouseDownPos.x(); - dy = ei->cp1Item()->pos().y() - _mouseDownPos.y(); - - if (dx*dx + dy*dy <= cpR2) { - _modifyEdgeItem = ei; - _firstControlPoint = true; - break; - } - - dx = ei->cp2Item()->pos().x() - _mouseDownPos.x(); - dy = ei->cp2Item()->pos().y() - _mouseDownPos.y(); - - if (dx*dx + dy*dy <= cpR2) { - _modifyEdgeItem = ei; - _firstControlPoint = false; - break; - } - } - } - - if (_modifyEdgeItem != 0) { - // store for undo purposes - Edge *e = _modifyEdgeItem->edge(); - _oldBend = e->bend(); - _oldInAngle = e->inAngle(); - _oldOutAngle = e->outAngle(); - _oldWeight = e->weight(); - } else { - // since we are not dragging a control point, process the click normally - //views()[0]->setDragMode(QGraphicsView::RubberBandDrag); - QGraphicsScene::mousePressEvent(event); - - if (items(_mouseDownPos).isEmpty()) { - _rubberBandItem->setRect(QRectF(_mouseDownPos,_mouseDownPos)); - _rubberBandItem->setVisible(true); - qDebug() << "starting rubber band drag"; - } - -// foreach (QGraphicsItem *gi, items()) { -// if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) { -// //qDebug() << "got an edge item: " << ei; -// ei->setFlag(QGraphicsItem::ItemIsSelectable, false); -// //ei->setSelected(true); -// } -// } - - // save current node positions for undo support - _oldNodePositions.clear(); - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) { - _oldNodePositions.insert(ni->node(), ni->node()->point()); - } - } - - auto its = items(_mouseDownPos); - if (!its.isEmpty() && dynamic_cast<NodeItem*>(its[0])) - _draggingNodes = true; - } - - break; - case ToolPalette::VERTEX: - break; - case ToolPalette::EDGE: - foreach (QGraphicsItem *gi, items(_mouseDownPos)) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){ - _edgeStartNodeItem = ni; - _edgeEndNodeItem = ni; - QLineF line(toScreen(ni->node()->point()), _mouseDownPos); - _drawEdgeItem->setLine(line); - _drawEdgeItem->setVisible(true); - break; - } - } - break; - case ToolPalette::CROP: - break; - } -} - -void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - if (!_enabled) return; - - // current mouse position, in scene coordinates - QPointF mousePos = event->scenePos(); - //QRectF rb = views()[0]->rubberBandRect(); - //invalidate(-800,-800,1600,1600); - //invalidate(QRectF(), QGraphicsScene::BackgroundLayer); - - switch (_tools->currentTool()) { - case ToolPalette::SELECT: - if (_modifyEdgeItem != 0) { - Edge *e = _modifyEdgeItem->edge(); - - // dragging a control point - QPointF src = toScreen(e->source()->point()); - QPointF targ = toScreen(e->target()->point()); - float dx1 = targ.x() - src.x(); - float dy1 = targ.y() - src.y(); - float dx2, dy2; - if (_firstControlPoint) { - dx2 = mousePos.x() - src.x(); - dy2 = mousePos.y() - src.y(); - } else { - dx2 = mousePos.x() - targ.x(); - dy2 = mousePos.y() - targ.y(); - } - - float baseDist = sqrt(dx1*dx1 + dy1*dy1); - float handleDist = sqrt(dx2*dx2 + dy2*dy2); - float wcoarseness = 0.1f; - - if (!e->isSelfLoop()) { - if (baseDist != 0) { - e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist)); - } else { - e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF)); - } - } - - float control_angle = atan2(-dy2, dx2); - - int bcoarseness = 15; - - if(e->basicBendMode()) { - float bnd; - float base_angle = atan2(-dy1, dx1); - if (_firstControlPoint) { - bnd = base_angle - control_angle; - } else { - bnd = control_angle - base_angle + M_PI; - if (bnd > M_PI) bnd -= 2*M_PI; - } - - e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness); - - } else { - int bnd = round(control_angle * (180.0f / M_PI) * - (1.0f / (float)bcoarseness)) * - bcoarseness; - if (_firstControlPoint) { - // TODO: enable moving both control points -// if ([theEvent modifierFlags] & NSAlternateKeyMask) { -// if ([modifyEdge isSelfLoop]) { -// [modifyEdge setInAngle:[modifyEdge inAngle] + -// (bnd - [modifyEdge outAngle])]; -// } else { -// [modifyEdge setInAngle:[modifyEdge inAngle] - -// (bnd - [modifyEdge outAngle])]; -// } -// } - - e->setOutAngle(bnd); - } else { -// if (theEvent.modifierFlags & NSAlternateKeyMask) { -// if ([modifyEdge isSelfLoop]) { -// [modifyEdge setOutAngle:[modifyEdge outAngle] + -// (bnd - [modifyEdge inAngle])]; -// } else { -// [modifyEdge setOutAngle:[modifyEdge outAngle] - -// (bnd - [modifyEdge inAngle])]; -// } -// } - - e->setInAngle(bnd); - } - } - - _modifyEdgeItem->readPos(); - - } else if (_draggingNodes) { // nodes being dragged - QGraphicsScene::mouseMoveEvent(event); - - // apply the same offset to all nodes, otherwise we get odd rounding behaviour with - // multiple selection. - QPointF shift = mousePos - _mouseDownPos; - shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP); - - foreach (Node *n, _oldNodePositions.keys()) { - NodeItem *ni = _nodeItems[n]; - - // in (rare) cases, the graph can change while we are dragging - if (ni != 0) { - ni->setPos(toScreen(_oldNodePositions[n]) + shift); - ni->writePos(); - } - } - - refreshAdjacentEdges(_oldNodePositions.keys()); - } else { - // otherwise, process mouse move normally - QGraphicsScene::mouseMoveEvent(event); - - if (_rubberBandItem->isVisible()) { - qreal left = std::min(_mouseDownPos.x(), mousePos.x()); - qreal top = std::min(_mouseDownPos.y(), mousePos.y()); - qreal w = std::abs(_mouseDownPos.x() - mousePos.x()); - qreal h = std::abs(_mouseDownPos.y() - mousePos.y()); - - _rubberBandItem->setRect(QRectF(left, top, w, h)); - } - } - - break; - case ToolPalette::VERTEX: - break; - case ToolPalette::EDGE: - if (_drawEdgeItem->isVisible()) { - _edgeEndNodeItem = 0; - foreach (QGraphicsItem *gi, items(mousePos)) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){ - _edgeEndNodeItem = ni; - break; - } - } - QPointF p1 = _drawEdgeItem->line().p1(); - QPointF p2 = (_edgeEndNodeItem != 0) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos; - QLineF line(p1, p2); - - _drawEdgeItem->setLine(line); - } - break; - case ToolPalette::CROP: - break; - } -} - -void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - if (!_enabled) return; - - // current mouse position, in scene coordinates - QPointF mousePos = event->scenePos(); - - switch (_tools->currentTool()) { - case ToolPalette::SELECT: - if (_modifyEdgeItem != 0) { - // finished dragging a control point - Edge *e = _modifyEdgeItem->edge(); - - if (_oldWeight != e->weight() || - _oldBend != e->bend() || - _oldInAngle != e->inAngle() || - _oldOutAngle != e->outAngle()) - { - EdgeBendCommand *cmd = new EdgeBendCommand(this, e, _oldWeight, _oldBend, _oldInAngle, _oldOutAngle); - _tikzDocument->undoStack()->push(cmd); - } - - _modifyEdgeItem = 0; - } else { - // otherwise, process mouse move normally - QGraphicsScene::mouseReleaseEvent(event); - - if (_rubberBandItem->isVisible()) { - QPainterPath sel; - sel.addRect(_rubberBandItem->rect()); - foreach (QGraphicsItem *gi, items()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) { - if (sel.contains(toScreen(ni->node()->point()))) ni->setSelected(true); - } - } - //setSelectionArea(sel); - } - - _rubberBandItem->setVisible(false); - - if (!_oldNodePositions.empty()) { - QPointF shift = mousePos - _mouseDownPos; - shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP); - - if (shift.x() != 0 || shift.y() != 0) { - QMap<Node*,QPointF> newNodePositions; - - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) { - ni->writePos(); - newNodePositions.insert(ni->node(), ni->node()->point()); - } - } - - //qDebug() << _oldNodePositions; - //qDebug() << newNodePositions; - - _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions)); - } - - _oldNodePositions.clear(); - } - } - - break; - case ToolPalette::VERTEX: - { - QPointF gridPos(round(mousePos.x()/GRID_SEP)*GRID_SEP, round(mousePos.y()/GRID_SEP)*GRID_SEP); - Node *n = new Node(_tikzDocument); - n->setName(graph()->freshNodeName()); - n->setPoint(fromScreen(gridPos)); - n->setStyleName(_styles->activeNodeStyleName()); - - QRectF grow(gridPos.x() - GLOBAL_SCALEF, gridPos.y() - GLOBAL_SCALEF, 2 * GLOBAL_SCALEF, 2 * GLOBAL_SCALEF); - QRectF newBounds = sceneRect().united(grow); - //qDebug() << grow; - //qDebug() << newBounds; - - AddNodeCommand *cmd = new AddNodeCommand(this, n, newBounds); - _tikzDocument->undoStack()->push(cmd); - } - break; - case ToolPalette::EDGE: - if (_edgeStartNodeItem != 0 && _edgeEndNodeItem != 0) { - Edge *e = new Edge(_edgeStartNodeItem->node(), _edgeEndNodeItem->node(), _tikzDocument); - e->setStyleName(_styles->activeEdgeStyleName()); - AddEdgeCommand *cmd = new AddEdgeCommand(this, e); - _tikzDocument->undoStack()->push(cmd); - } - _edgeStartNodeItem = 0; - _edgeEndNodeItem = 0; - _drawEdgeItem->setVisible(false); - break; - case ToolPalette::CROP: - break; - } - - // clear artefacts from rubber band selection - invalidate(QRect(), QGraphicsScene::BackgroundLayer); -} - - - -void TikzScene::keyReleaseEvent(QKeyEvent *event) -{ - if (!_enabled) return; - - if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) { - deleteSelectedItems(); - } else if (event->modifiers() == Qt::NoModifier) { - switch(event->key()) { - case Qt::Key_S: - tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::SELECT); - break; - case Qt::Key_V: - case Qt::Key_N: - tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::VERTEX); - break; - case Qt::Key_E: - tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::EDGE); - break; - case Qt::Key_B: - tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::CROP); - break; - } - } -} - -void TikzScene::keyPressEvent(QKeyEvent *event) -{ - bool capture = false; - - if (event->key() == Qt::Key_QuoteLeft) { - capture = true; - _styles->nextNodeStyle(); - } - - if (event->modifiers() & Qt::ControlModifier) { - QPointF delta(0,0); - float shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0f : 10.0f; - switch(event->key()) { - case Qt::Key_Left: - delta.setX(-0.025f * shift); - break; - case Qt::Key_Right: - delta.setX(0.025f * shift); - break; - case Qt::Key_Up: - delta.setY(0.025f * shift); - break; - case Qt::Key_Down: - delta.setY(-0.025f * shift); - break; - } - - if (!delta.isNull()) { - capture = true; - QMap<Node*,QPointF> oldNodePositions; - QMap<Node*,QPointF> newNodePositions; - QPointF pos; - - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) { - pos = ni->node()->point(); - oldNodePositions.insert(ni->node(), pos); - newNodePositions.insert(ni->node(), pos + delta); - } - } - - MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions); - _tikzDocument->undoStack()->push(cmd); - } - } - - if (!capture) QGraphicsScene::keyPressEvent(event); -} - -void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) -{ - if (!_enabled) return; - - QPointF mousePos = event->scenePos(); - - foreach (QGraphicsItem *it, items(mousePos)) { - if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) { - ChangeEdgeModeCommand *cmd = new ChangeEdgeModeCommand(this, ei->edge()); - _tikzDocument->undoStack()->push(cmd); - break; - } else if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) { - bool ok; - QString newLabel = QInputDialog::getText(views()[0], tr("Node label"), - tr("Label:"), QLineEdit::Normal, - ni->node()->label(), &ok); - if (ok && !newLabel.isEmpty()) { - QMap<Node*,QString> oldLabels; - oldLabels.insert(ni->node(), ni->node()->label()); - ChangeLabelCommand *cmd = new ChangeLabelCommand(this, graph(), oldLabels, newLabel); - _tikzDocument->undoStack()->push(cmd); - } - break; - } - } -} - -bool TikzScene::enabled() const -{ - return _enabled; -} - -void TikzScene::setEnabled(bool enabled) -{ - _enabled = enabled; - update(); -} - -int TikzScene::lineNumberForSelection() -{ - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) return ni->node()->tikzLine(); - if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) return ei->edge()->tikzLine(); - } - return 0; -} - - -void TikzScene::applyActiveStyleToNodes() { - ApplyStyleToNodesCommand *cmd = new ApplyStyleToNodesCommand(this, _styles->activeNodeStyleName()); - _tikzDocument->undoStack()->push(cmd); -} - -void TikzScene::deleteSelectedItems() -{ - QSet<Node*> selNodes; - QSet<Edge*> selEdges; - getSelection(selNodes, selEdges); - - QMap<int,Node*> deleteNodes; - QMap<int,Edge*> deleteEdges; - - for (int i = 0; i < _tikzDocument->graph()->nodes().length(); ++i) { - Node *n = _tikzDocument->graph()->nodes()[i]; - if (selNodes.contains(n)) deleteNodes.insert(i, n); - } - - for (int i = 0; i < _tikzDocument->graph()->edges().length(); ++i) { - Edge *e = _tikzDocument->graph()->edges()[i]; - if (selEdges.contains(e) || - selNodes.contains(e->source()) || - selNodes.contains(e->target())) deleteEdges.insert(i, e); - } - - //qDebug() << "nodes:" << deleteNodes; - //qDebug() << "edges:" << deleteEdges; - DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges); - _tikzDocument->undoStack()->push(cmd); -} - -void TikzScene::copyToClipboard() -{ - Graph *g = graph()->copyOfSubgraphWithNodes(getSelectedNodes()); - QGuiApplication::clipboard()->setText(g->tikz()); - delete g; -} - -void TikzScene::cutToClipboard() -{ - copyToClipboard(); - deleteSelectedItems(); -} - - -void TikzScene::pasteFromClipboard() -{ - QString tikz = QGuiApplication::clipboard()->text(); - Graph *g = new Graph(); - TikzAssembler ass(g); - - // attempt to parse whatever's on the clipboard, if we get a - // non-empty tikz graph, insert it. - if (ass.parse(tikz) && !g->nodes().isEmpty()) { - // make sure names in the new subgraph are fresh - g->renameApart(graph()); - - QRectF srcRect = g->realBbox(); - QRectF tgtRect = graph()->realBbox(); - QPointF shift(tgtRect.right() - srcRect.left(), 0.0f); - - if (shift.x() > 0) { - foreach (Node *n, g->nodes()) { - n->setPoint(n->point() + shift); - } - } - - PasteCommand *cmd = new PasteCommand(this, g); - _tikzDocument->undoStack()->push(cmd); - } -} - -void TikzScene::selectAllNodes() -{ - foreach (NodeItem *ni, _nodeItems.values()) { - ni->setSelected(true); - } -} - -void TikzScene::deselectAll() -{ - selectedItems().clear(); -} - -void TikzScene::parseTikz(QString tikz) -{ - Graph *newGraph = new Graph(this); - TikzAssembler ass(newGraph); - if (ass.parse(tikz)) { - ReplaceGraphCommand *cmd = new ReplaceGraphCommand(this, graph(), newGraph); - tikzDocument()->undoStack()->push(cmd); - setEnabled(true); - } -} - -void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges) -{ - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node(); - if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) selEdges << ei->edge(); - } -} - -QSet<Node *> TikzScene::getSelectedNodes() -{ - QSet<Node*> selNodes; - foreach (QGraphicsItem *gi, selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node(); - } - return selNodes; -} - - -TikzDocument *TikzScene::tikzDocument() const -{ - return _tikzDocument; -} - -void TikzScene::setTikzDocument(TikzDocument *tikzDocument) -{ - _tikzDocument = tikzDocument; - graphReplaced(); -} - -void TikzScene::reloadStyles() -{ - _styles->reloadStyles(); - foreach(EdgeItem *ei, _edgeItems) { - ei->edge()->attachStyle(); - ei->readPos(); // trigger a repaint - } - - foreach (NodeItem *ni, _nodeItems) { - ni->node()->attachStyle(); - ni->readPos(); // trigger a repaint - } -} - -// void TikzScene::refreshSceneBounds() -// { -// // if (!views().empty()) { -// // QGraphicsView *v = views().first(); -// // QRectF viewB = v->mapToScene(v->viewport()->rect()).boundingRect(); -// // //QPointF tl = v->mapToScene(viewB.topLeft()); -// // //viewB.setTopLeft(tl); -// -// // QRectF bounds = viewB.united(rectToScreen(graph()->realBbox().adjusted(-1.0f, -1.0f, 1.0f, 1.0f))); -// // //qDebug() << viewB; -// -// // if (bounds != sceneRect()) { -// // QPointF c = viewB.center(); -// // setSceneRect(bounds); -// // v->centerOn(c); -// // } -// // } -// //setBounds(graphB); -// } - -void TikzScene::refreshAdjacentEdges(QList<Node*> nodes) -{ - if (nodes.empty()) return; - foreach (Edge *e, _edgeItems.keys()) { - EdgeItem *ei = _edgeItems[e]; - - // the list "nodes" can be out of date, e.g. if the graph changes while dragging - if (ei != 0) { - if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) { - ei->edge()->updateControls(); - ei->readPos(); - } - } - } -} - -//void TikzScene::setBounds(QRectF bounds) -//{ -// if (bounds != sceneRect()) { -// if (!views().empty()) { -// QGraphicsView *v = views().first(); -// QPointF c = v->mapToScene(v->viewport()->rect().center()); -// setSceneRect(bounds); -// v->centerOn(c); -// } else { -// setSceneRect(bounds); -// } -// } -//} - -QMap<Node*,NodeItem *> &TikzScene::nodeItems() -{ - return _nodeItems; -} - -QMap<Edge*,EdgeItem*> &TikzScene::edgeItems() -{ - return _edgeItems; -} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzit.h"
+#include "util.h"
+#include "tikzscene.h"
+#include "undocommands.h"
+#include "tikzassembler.h"
+
+#include <QPen>
+#include <QBrush>
+#include <QDebug>
+#include <QClipboard>
+#include <QInputDialog>
+#include <cmath>
+
+
+TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools,
+ StylePalette *styles, QObject *parent) :
+ QGraphicsScene(parent), _tikzDocument(tikzDocument), _tools(tools), _styles(styles)
+{
+ _modifyEdgeItem = 0;
+ _edgeStartNodeItem = 0;
+ _drawEdgeItem = new QGraphicsLineItem();
+ _rubberBandItem = new QGraphicsRectItem();
+ _enabled = true;
+ //setSceneRect(-310,-230,620,450);
+ setSceneRect(-1000,-1000,2000,2000);
+
+ QPen pen;
+ pen.setColor(QColor::fromRgbF(0.5f, 0.0f, 0.5f));
+ //pen.setWidth(3.0f);
+ pen.setCosmetic(true);
+ _drawEdgeItem->setPen(pen);
+ _drawEdgeItem->setLine(0,0,0,0);
+ _drawEdgeItem->setVisible(false);
+ addItem(_drawEdgeItem);
+
+ pen.setColor(QColor::fromRgbF(0.6f, 0.6f, 0.8f));
+ //pen.setWidth(3.0f);
+ //QVector<qreal> dash;
+ //dash << 4.0 << 4.0;
+ pen.setStyle(Qt::DashLine);
+ //pen.setDashPattern(dash);
+ _rubberBandItem->setPen(pen);
+
+ QBrush brush(QColor::fromRgbF(0.6,0.6,0.8,0.2));
+ _rubberBandItem->setBrush(brush);
+
+ _rubberBandItem->setVisible(false);
+ addItem(_rubberBandItem);
+}
+
+TikzScene::~TikzScene() {
+}
+
+Graph *TikzScene::graph()
+{
+ return _tikzDocument->graph();
+}
+
+void TikzScene::graphReplaced()
+{
+
+ foreach (NodeItem *ni, _nodeItems) {
+ removeItem(ni);
+ delete ni;
+ }
+ _nodeItems.clear();
+
+ foreach (EdgeItem *ei, _edgeItems) {
+ removeItem(ei);
+ delete ei;
+ }
+ _edgeItems.clear();
+
+ foreach (Edge *e, graph()->edges()) {
+ e->attachStyle();
+ EdgeItem *ei = new EdgeItem(e);
+ _edgeItems.insert(e, ei);
+ addItem(ei);
+ }
+
+ foreach (Node *n, graph()->nodes()) {
+ n->attachStyle();
+ NodeItem *ni = new NodeItem(n);
+ _nodeItems.insert(n, ni);
+ addItem(ni);
+ }
+}
+
+void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ _mouseDownPos = event->scenePos();
+
+ _draggingNodes = false;
+
+ // disable rubber band drag, which will clear the selection. Only re-enable it
+ // for the SELECT tool, and when no control point has been clicked.
+ //views()[0]->setDragMode(QGraphicsView::NoDrag);
+
+ // radius of a control point for bezier edges, in scene coordinates
+ qreal cpR = GLOBAL_SCALEF * (0.1);
+ qreal cpR2 = cpR * cpR;
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ // check if we grabbed a control point of an edge
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
+ qreal dx, dy;
+
+ dx = ei->cp1Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp1Item()->pos().y() - _mouseDownPos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = true;
+ break;
+ }
+
+ dx = ei->cp2Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp2Item()->pos().y() - _mouseDownPos.y();
+
+ if (dx*dx + dy*dy <= cpR2) {
+ _modifyEdgeItem = ei;
+ _firstControlPoint = false;
+ break;
+ }
+ }
+ }
+
+ if (_modifyEdgeItem != 0) {
+ // store for undo purposes
+ Edge *e = _modifyEdgeItem->edge();
+ _oldBend = e->bend();
+ _oldInAngle = e->inAngle();
+ _oldOutAngle = e->outAngle();
+ _oldWeight = e->weight();
+ } else {
+ // since we are not dragging a control point, process the click normally
+ //views()[0]->setDragMode(QGraphicsView::RubberBandDrag);
+ QGraphicsScene::mousePressEvent(event);
+
+ if (items(_mouseDownPos).isEmpty()) {
+ _rubberBandItem->setRect(QRectF(_mouseDownPos,_mouseDownPos));
+ _rubberBandItem->setVisible(true);
+ qDebug() << "starting rubber band drag";
+ }
+
+// foreach (QGraphicsItem *gi, items()) {
+// if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
+// //qDebug() << "got an edge item: " << ei;
+// ei->setFlag(QGraphicsItem::ItemIsSelectable, false);
+// //ei->setSelected(true);
+// }
+// }
+
+ // save current node positions for undo support
+ _oldNodePositions.clear();
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ _oldNodePositions.insert(ni->node(), ni->node()->point());
+ }
+ }
+
+ auto its = items(_mouseDownPos);
+ if (!its.isEmpty() && dynamic_cast<NodeItem*>(its[0]))
+ _draggingNodes = true;
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ break;
+ case ToolPalette::EDGE:
+ foreach (QGraphicsItem *gi, items(_mouseDownPos)) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
+ _edgeStartNodeItem = ni;
+ _edgeEndNodeItem = ni;
+ QLineF line(toScreen(ni->node()->point()), _mouseDownPos);
+ _drawEdgeItem->setLine(line);
+ _drawEdgeItem->setVisible(true);
+ break;
+ }
+ }
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+}
+
+void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ QPointF mousePos = event->scenePos();
+ //QRectF rb = views()[0]->rubberBandRect();
+ //invalidate(-800,-800,1600,1600);
+ //invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ if (_modifyEdgeItem != 0) {
+ Edge *e = _modifyEdgeItem->edge();
+
+ // dragging a control point
+ QPointF src = toScreen(e->source()->point());
+ QPointF targ = toScreen(e->target()->point());
+ float dx1 = targ.x() - src.x();
+ float dy1 = targ.y() - src.y();
+ float dx2, dy2;
+ if (_firstControlPoint) {
+ dx2 = mousePos.x() - src.x();
+ dy2 = mousePos.y() - src.y();
+ } else {
+ dx2 = mousePos.x() - targ.x();
+ dy2 = mousePos.y() - targ.y();
+ }
+
+ float baseDist = sqrt(dx1*dx1 + dy1*dy1);
+ float handleDist = sqrt(dx2*dx2 + dy2*dy2);
+ float wcoarseness = 0.1f;
+
+ if (!e->isSelfLoop()) {
+ if (baseDist != 0) {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist));
+ } else {
+ e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF));
+ }
+ }
+
+ float control_angle = atan2(-dy2, dx2);
+
+ int bcoarseness = 15;
+
+ if(e->basicBendMode()) {
+ float bnd;
+ float base_angle = atan2(-dy1, dx1);
+ if (_firstControlPoint) {
+ bnd = base_angle - control_angle;
+ } else {
+ bnd = control_angle - base_angle + M_PI;
+ if (bnd > M_PI) bnd -= 2*M_PI;
+ }
+
+ e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness);
+
+ } else {
+ int bnd = round(control_angle * (180.0f / M_PI) *
+ (1.0f / (float)bcoarseness)) *
+ bcoarseness;
+ if (_firstControlPoint) {
+ // TODO: enable moving both control points
+// if ([theEvent modifierFlags] & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setInAngle:[modifyEdge inAngle] +
+// (bnd - [modifyEdge outAngle])];
+// } else {
+// [modifyEdge setInAngle:[modifyEdge inAngle] -
+// (bnd - [modifyEdge outAngle])];
+// }
+// }
+
+ e->setOutAngle(bnd);
+ } else {
+// if (theEvent.modifierFlags & NSAlternateKeyMask) {
+// if ([modifyEdge isSelfLoop]) {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] +
+// (bnd - [modifyEdge inAngle])];
+// } else {
+// [modifyEdge setOutAngle:[modifyEdge outAngle] -
+// (bnd - [modifyEdge inAngle])];
+// }
+// }
+
+ e->setInAngle(bnd);
+ }
+ }
+
+ _modifyEdgeItem->readPos();
+
+ } else if (_draggingNodes) { // nodes being dragged
+ QGraphicsScene::mouseMoveEvent(event);
+
+ // apply the same offset to all nodes, otherwise we get odd rounding behaviour with
+ // multiple selection.
+ QPointF shift = mousePos - _mouseDownPos;
+ shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
+
+ foreach (Node *n, _oldNodePositions.keys()) {
+ NodeItem *ni = _nodeItems[n];
+
+ // in (rare) cases, the graph can change while we are dragging
+ if (ni != 0) {
+ ni->setPos(toScreen(_oldNodePositions[n]) + shift);
+ ni->writePos();
+ }
+ }
+
+ refreshAdjacentEdges(_oldNodePositions.keys());
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseMoveEvent(event);
+
+ if (_rubberBandItem->isVisible()) {
+ qreal left = std::min(_mouseDownPos.x(), mousePos.x());
+ qreal top = std::min(_mouseDownPos.y(), mousePos.y());
+ qreal w = std::abs(_mouseDownPos.x() - mousePos.x());
+ qreal h = std::abs(_mouseDownPos.y() - mousePos.y());
+
+ _rubberBandItem->setRect(QRectF(left, top, w, h));
+ }
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ break;
+ case ToolPalette::EDGE:
+ if (_drawEdgeItem->isVisible()) {
+ _edgeEndNodeItem = 0;
+ foreach (QGraphicsItem *gi, items(mousePos)) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
+ _edgeEndNodeItem = ni;
+ break;
+ }
+ }
+ QPointF p1 = _drawEdgeItem->line().p1();
+ QPointF p2 = (_edgeEndNodeItem != 0) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos;
+ QLineF line(p1, p2);
+
+ _drawEdgeItem->setLine(line);
+ }
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+}
+
+void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ // current mouse position, in scene coordinates
+ QPointF mousePos = event->scenePos();
+
+ switch (_tools->currentTool()) {
+ case ToolPalette::SELECT:
+ if (_modifyEdgeItem != 0) {
+ // finished dragging a control point
+ Edge *e = _modifyEdgeItem->edge();
+
+ if (_oldWeight != e->weight() ||
+ _oldBend != e->bend() ||
+ _oldInAngle != e->inAngle() ||
+ _oldOutAngle != e->outAngle())
+ {
+ EdgeBendCommand *cmd = new EdgeBendCommand(this, e, _oldWeight, _oldBend, _oldInAngle, _oldOutAngle);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+
+ _modifyEdgeItem = 0;
+ } else {
+ // otherwise, process mouse move normally
+ QGraphicsScene::mouseReleaseEvent(event);
+
+ if (_rubberBandItem->isVisible()) {
+ QPainterPath sel;
+ sel.addRect(_rubberBandItem->rect());
+ foreach (QGraphicsItem *gi, items()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ if (sel.contains(toScreen(ni->node()->point()))) ni->setSelected(true);
+ }
+ }
+ //setSelectionArea(sel);
+ }
+
+ _rubberBandItem->setVisible(false);
+
+ if (!_oldNodePositions.empty()) {
+ QPointF shift = mousePos - _mouseDownPos;
+ shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP);
+
+ if (shift.x() != 0 || shift.y() != 0) {
+ QMap<Node*,QPointF> newNodePositions;
+
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ ni->writePos();
+ newNodePositions.insert(ni->node(), ni->node()->point());
+ }
+ }
+
+ //qDebug() << _oldNodePositions;
+ //qDebug() << newNodePositions;
+
+ _tikzDocument->undoStack()->push(new MoveCommand(this, _oldNodePositions, newNodePositions));
+ }
+
+ _oldNodePositions.clear();
+ }
+ }
+
+ break;
+ case ToolPalette::VERTEX:
+ {
+ QPointF gridPos(round(mousePos.x()/GRID_SEP)*GRID_SEP, round(mousePos.y()/GRID_SEP)*GRID_SEP);
+ Node *n = new Node(_tikzDocument);
+ n->setName(graph()->freshNodeName());
+ n->setPoint(fromScreen(gridPos));
+ n->setStyleName(_styles->activeNodeStyleName());
+
+ QRectF grow(gridPos.x() - GLOBAL_SCALEF, gridPos.y() - GLOBAL_SCALEF, 2 * GLOBAL_SCALEF, 2 * GLOBAL_SCALEF);
+ QRectF newBounds = sceneRect().united(grow);
+ //qDebug() << grow;
+ //qDebug() << newBounds;
+
+ AddNodeCommand *cmd = new AddNodeCommand(this, n, newBounds);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ break;
+ case ToolPalette::EDGE:
+ if (_edgeStartNodeItem != 0 && _edgeEndNodeItem != 0) {
+ Edge *e = new Edge(_edgeStartNodeItem->node(), _edgeEndNodeItem->node(), _tikzDocument);
+ e->setStyleName(_styles->activeEdgeStyleName());
+ AddEdgeCommand *cmd = new AddEdgeCommand(this, e);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ _edgeStartNodeItem = 0;
+ _edgeEndNodeItem = 0;
+ _drawEdgeItem->setVisible(false);
+ break;
+ case ToolPalette::CROP:
+ break;
+ }
+
+ // clear artefacts from rubber band selection
+ invalidate(QRect(), QGraphicsScene::BackgroundLayer);
+}
+
+
+
+void TikzScene::keyReleaseEvent(QKeyEvent *event)
+{
+ if (!_enabled) return;
+
+ if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
+ deleteSelectedItems();
+ } else if (event->modifiers() == Qt::NoModifier) {
+ switch(event->key()) {
+ case Qt::Key_S:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::SELECT);
+ break;
+ case Qt::Key_V:
+ case Qt::Key_N:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::VERTEX);
+ break;
+ case Qt::Key_E:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::EDGE);
+ break;
+ case Qt::Key_B:
+ tikzit->activeWindow()->toolPalette()->setCurrentTool(ToolPalette::CROP);
+ break;
+ }
+ }
+}
+
+void TikzScene::keyPressEvent(QKeyEvent *event)
+{
+ bool capture = false;
+
+ if (event->key() == Qt::Key_QuoteLeft) {
+ capture = true;
+ _styles->nextNodeStyle();
+ }
+
+ if (event->modifiers() & Qt::ControlModifier) {
+ QPointF delta(0,0);
+ float shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0f : 10.0f;
+ switch(event->key()) {
+ case Qt::Key_Left:
+ delta.setX(-0.025f * shift);
+ break;
+ case Qt::Key_Right:
+ delta.setX(0.025f * shift);
+ break;
+ case Qt::Key_Up:
+ delta.setY(0.025f * shift);
+ break;
+ case Qt::Key_Down:
+ delta.setY(-0.025f * shift);
+ break;
+ }
+
+ if (!delta.isNull()) {
+ capture = true;
+ QMap<Node*,QPointF> oldNodePositions;
+ QMap<Node*,QPointF> newNodePositions;
+ QPointF pos;
+
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) {
+ pos = ni->node()->point();
+ oldNodePositions.insert(ni->node(), pos);
+ newNodePositions.insert(ni->node(), pos + delta);
+ }
+ }
+
+ MoveCommand *cmd = new MoveCommand(this, oldNodePositions, newNodePositions);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ }
+
+ if (!capture) QGraphicsScene::keyPressEvent(event);
+}
+
+void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!_enabled) return;
+
+ QPointF mousePos = event->scenePos();
+
+ foreach (QGraphicsItem *it, items(mousePos)) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
+ ChangeEdgeModeCommand *cmd = new ChangeEdgeModeCommand(this, ei->edge());
+ _tikzDocument->undoStack()->push(cmd);
+ break;
+ } else if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
+ bool ok;
+ QString newLabel = QInputDialog::getText(views()[0], tr("Node label"),
+ tr("Label:"), QLineEdit::Normal,
+ ni->node()->label(), &ok);
+ if (ok && !newLabel.isEmpty()) {
+ QMap<Node*,QString> oldLabels;
+ oldLabels.insert(ni->node(), ni->node()->label());
+ ChangeLabelCommand *cmd = new ChangeLabelCommand(this, graph(), oldLabels, newLabel);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+ break;
+ }
+ }
+}
+
+bool TikzScene::enabled() const
+{
+ return _enabled;
+}
+
+void TikzScene::setEnabled(bool enabled)
+{
+ _enabled = enabled;
+ update();
+}
+
+int TikzScene::lineNumberForSelection()
+{
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) return ni->node()->tikzLine();
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) return ei->edge()->tikzLine();
+ }
+ return 0;
+}
+
+
+void TikzScene::applyActiveStyleToNodes() {
+ ApplyStyleToNodesCommand *cmd = new ApplyStyleToNodesCommand(this, _styles->activeNodeStyleName());
+ _tikzDocument->undoStack()->push(cmd);
+}
+
+void TikzScene::deleteSelectedItems()
+{
+ QSet<Node*> selNodes;
+ QSet<Edge*> selEdges;
+ getSelection(selNodes, selEdges);
+
+ QMap<int,Node*> deleteNodes;
+ QMap<int,Edge*> deleteEdges;
+
+ for (int i = 0; i < _tikzDocument->graph()->nodes().length(); ++i) {
+ Node *n = _tikzDocument->graph()->nodes()[i];
+ if (selNodes.contains(n)) deleteNodes.insert(i, n);
+ }
+
+ for (int i = 0; i < _tikzDocument->graph()->edges().length(); ++i) {
+ Edge *e = _tikzDocument->graph()->edges()[i];
+ if (selEdges.contains(e) ||
+ selNodes.contains(e->source()) ||
+ selNodes.contains(e->target())) deleteEdges.insert(i, e);
+ }
+
+ //qDebug() << "nodes:" << deleteNodes;
+ //qDebug() << "edges:" << deleteEdges;
+ DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges);
+ _tikzDocument->undoStack()->push(cmd);
+}
+
+void TikzScene::copyToClipboard()
+{
+ Graph *g = graph()->copyOfSubgraphWithNodes(getSelectedNodes());
+ QGuiApplication::clipboard()->setText(g->tikz());
+ delete g;
+}
+
+void TikzScene::cutToClipboard()
+{
+ copyToClipboard();
+ deleteSelectedItems();
+}
+
+
+void TikzScene::pasteFromClipboard()
+{
+ QString tikz = QGuiApplication::clipboard()->text();
+ Graph *g = new Graph();
+ TikzAssembler ass(g);
+
+ // attempt to parse whatever's on the clipboard, if we get a
+ // non-empty tikz graph, insert it.
+ if (ass.parse(tikz) && !g->nodes().isEmpty()) {
+ // make sure names in the new subgraph are fresh
+ g->renameApart(graph());
+
+ QRectF srcRect = g->realBbox();
+ QRectF tgtRect = graph()->realBbox();
+ QPointF shift(tgtRect.right() - srcRect.left(), 0.0f);
+
+ if (shift.x() > 0) {
+ foreach (Node *n, g->nodes()) {
+ n->setPoint(n->point() + shift);
+ }
+ }
+
+ PasteCommand *cmd = new PasteCommand(this, g);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+}
+
+void TikzScene::selectAllNodes()
+{
+ foreach (NodeItem *ni, _nodeItems.values()) {
+ ni->setSelected(true);
+ }
+}
+
+void TikzScene::deselectAll()
+{
+ selectedItems().clear();
+}
+
+void TikzScene::parseTikz(QString tikz)
+{
+ Graph *newGraph = new Graph(this);
+ TikzAssembler ass(newGraph);
+ if (ass.parse(tikz)) {
+ ReplaceGraphCommand *cmd = new ReplaceGraphCommand(this, graph(), newGraph);
+ tikzDocument()->undoStack()->push(cmd);
+ setEnabled(true);
+ }
+}
+
+void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges)
+{
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) selEdges << ei->edge();
+ }
+}
+
+QSet<Node *> TikzScene::getSelectedNodes()
+{
+ QSet<Node*> selNodes;
+ foreach (QGraphicsItem *gi, selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)) selNodes << ni->node();
+ }
+ return selNodes;
+}
+
+
+TikzDocument *TikzScene::tikzDocument() const
+{
+ return _tikzDocument;
+}
+
+void TikzScene::setTikzDocument(TikzDocument *tikzDocument)
+{
+ _tikzDocument = tikzDocument;
+ graphReplaced();
+}
+
+void TikzScene::reloadStyles()
+{
+ _styles->reloadStyles();
+ foreach(EdgeItem *ei, _edgeItems) {
+ ei->edge()->attachStyle();
+ ei->readPos(); // trigger a repaint
+ }
+
+ foreach (NodeItem *ni, _nodeItems) {
+ ni->node()->attachStyle();
+ ni->readPos(); // trigger a repaint
+ }
+}
+
+// void TikzScene::refreshSceneBounds()
+// {
+// // if (!views().empty()) {
+// // QGraphicsView *v = views().first();
+// // QRectF viewB = v->mapToScene(v->viewport()->rect()).boundingRect();
+// // //QPointF tl = v->mapToScene(viewB.topLeft());
+// // //viewB.setTopLeft(tl);
+//
+// // QRectF bounds = viewB.united(rectToScreen(graph()->realBbox().adjusted(-1.0f, -1.0f, 1.0f, 1.0f)));
+// // //qDebug() << viewB;
+//
+// // if (bounds != sceneRect()) {
+// // QPointF c = viewB.center();
+// // setSceneRect(bounds);
+// // v->centerOn(c);
+// // }
+// // }
+// //setBounds(graphB);
+// }
+
+void TikzScene::refreshAdjacentEdges(QList<Node*> nodes)
+{
+ if (nodes.empty()) return;
+ foreach (Edge *e, _edgeItems.keys()) {
+ EdgeItem *ei = _edgeItems[e];
+
+ // the list "nodes" can be out of date, e.g. if the graph changes while dragging
+ if (ei != 0) {
+ if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) {
+ ei->edge()->updateControls();
+ ei->readPos();
+ }
+ }
+ }
+}
+
+//void TikzScene::setBounds(QRectF bounds)
+//{
+// if (bounds != sceneRect()) {
+// if (!views().empty()) {
+// QGraphicsView *v = views().first();
+// QPointF c = v->mapToScene(v->viewport()->rect().center());
+// setSceneRect(bounds);
+// v->centerOn(c);
+// } else {
+// setSceneRect(bounds);
+// }
+// }
+//}
+
+QMap<Node*,NodeItem *> &TikzScene::nodeItems()
+{
+ return _nodeItems;
+}
+
+QMap<Edge*,EdgeItem*> &TikzScene::edgeItems()
+{
+ return _edgeItems;
+}
diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h index 4ac56c7..8aafe28 100644 --- a/src/gui/tikzscene.h +++ b/src/gui/tikzscene.h @@ -1,107 +1,107 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * Manage the scene, which contains a single Graph, and respond to user input. This serves as - * the controller for the MVC (TikzDocument, TikzView, TikzScene). - */ - -#ifndef TIKZSCENE_H -#define TIKZSCENE_H - -#include "graph.h" -#include "nodeitem.h" -#include "edgeitem.h" -#include "tikzdocument.h" -#include "toolpalette.h" -#include "stylepalette.h" - -#include <QWidget> -#include <QGraphicsScene> -#include <QPainter> -#include <QRectF> -#include <QVector> -#include <QGraphicsEllipseItem> -#include <QGraphicsSceneMouseEvent> - -class TikzScene : public QGraphicsScene -{ - Q_OBJECT -public: - TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent); - ~TikzScene(); - Graph *graph(); - QMap<Node*,NodeItem*> &nodeItems(); - QMap<Edge*,EdgeItem*> &edgeItems(); - void refreshAdjacentEdges(QList<Node*> nodes); -// void setBounds(QRectF bounds); - - TikzDocument *tikzDocument() const; - void setTikzDocument(TikzDocument *tikzDocument); - void reloadStyles(); - //void refreshSceneBounds(); - void applyActiveStyleToNodes(); - void deleteSelectedItems(); - void copyToClipboard(); - void cutToClipboard(); - void pasteFromClipboard(); - void selectAllNodes(); - void deselectAll(); - void parseTikz(QString tikz); - bool enabled() const; - void setEnabled(bool enabled); - int lineNumberForSelection(); - - - void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges); - QSet<Node*> getSelectedNodes(); - -public slots: - void graphReplaced(); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; - void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; - void keyReleaseEvent(QKeyEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; -private: - TikzDocument *_tikzDocument; - ToolPalette *_tools; - StylePalette *_styles; - QMap<Node*,NodeItem*> _nodeItems; - QMap<Edge*,EdgeItem*> _edgeItems; - QGraphicsLineItem *_drawEdgeItem; - QGraphicsRectItem *_rubberBandItem; - EdgeItem *_modifyEdgeItem; - NodeItem *_edgeStartNodeItem; - NodeItem *_edgeEndNodeItem; - bool _firstControlPoint; - QPointF _mouseDownPos; - bool _draggingNodes; - - QMap<Node*,QPointF> _oldNodePositions; - float _oldWeight; - int _oldBend; - int _oldInAngle; - int _oldOutAngle; - bool _enabled; -}; - -#endif // TIKZSCENE_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Manage the scene, which contains a single Graph, and respond to user input. This serves as
+ * the controller for the MVC (TikzDocument, TikzView, TikzScene).
+ */
+
+#ifndef TIKZSCENE_H
+#define TIKZSCENE_H
+
+#include "graph.h"
+#include "nodeitem.h"
+#include "edgeitem.h"
+#include "tikzdocument.h"
+#include "toolpalette.h"
+#include "stylepalette.h"
+
+#include <QWidget>
+#include <QGraphicsScene>
+#include <QPainter>
+#include <QRectF>
+#include <QVector>
+#include <QGraphicsEllipseItem>
+#include <QGraphicsSceneMouseEvent>
+
+class TikzScene : public QGraphicsScene
+{
+ Q_OBJECT
+public:
+ TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent);
+ ~TikzScene();
+ Graph *graph();
+ QMap<Node*,NodeItem*> &nodeItems();
+ QMap<Edge*,EdgeItem*> &edgeItems();
+ void refreshAdjacentEdges(QList<Node*> nodes);
+// void setBounds(QRectF bounds);
+
+ TikzDocument *tikzDocument() const;
+ void setTikzDocument(TikzDocument *tikzDocument);
+ void reloadStyles();
+ //void refreshSceneBounds();
+ void applyActiveStyleToNodes();
+ void deleteSelectedItems();
+ void copyToClipboard();
+ void cutToClipboard();
+ void pasteFromClipboard();
+ void selectAllNodes();
+ void deselectAll();
+ void parseTikz(QString tikz);
+ bool enabled() const;
+ void setEnabled(bool enabled);
+ int lineNumberForSelection();
+
+
+ void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges);
+ QSet<Node*> getSelectedNodes();
+
+public slots:
+ void graphReplaced();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
+private:
+ TikzDocument *_tikzDocument;
+ ToolPalette *_tools;
+ StylePalette *_styles;
+ QMap<Node*,NodeItem*> _nodeItems;
+ QMap<Edge*,EdgeItem*> _edgeItems;
+ QGraphicsLineItem *_drawEdgeItem;
+ QGraphicsRectItem *_rubberBandItem;
+ EdgeItem *_modifyEdgeItem;
+ NodeItem *_edgeStartNodeItem;
+ NodeItem *_edgeEndNodeItem;
+ bool _firstControlPoint;
+ QPointF _mouseDownPos;
+ bool _draggingNodes;
+
+ QMap<Node*,QPointF> _oldNodePositions;
+ float _oldWeight;
+ int _oldBend;
+ int _oldInAngle;
+ int _oldOutAngle;
+ bool _enabled;
+};
+
+#endif // TIKZSCENE_H
diff --git a/src/gui/tikzview.cpp b/src/gui/tikzview.cpp index 6cdb17c..f0084fb 100644 --- a/src/gui/tikzview.cpp +++ b/src/gui/tikzview.cpp @@ -1,128 +1,128 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "tikzview.h" -#include "tikzit.h" - -#include <QDebug> -#include <QScrollBar> - -TikzView::TikzView(QWidget *parent) : QGraphicsView(parent) -{ - setRenderHint(QPainter::Antialiasing); - //setDragMode(QGraphicsView::RubberBandDrag); - - _scale = 1.0f; -} - -void TikzView::zoomIn() -{ - _scale *= 1.6f; - scale(1.6,1.6); -} - -void TikzView::zoomOut() -{ - _scale *= 0.625f; - scale(0.625,0.625); -} - -void TikzView::setScene(QGraphicsScene *scene) -{ - QGraphicsView::setScene(scene); - centerOn(QPointF(0.0f,-230.0f)); -} - -void TikzView::drawBackground(QPainter *painter, const QRectF &rect) -{ - // draw a gray background if disabled - TikzScene *sc = static_cast<TikzScene*>(scene()); - if (!sc->enabled()) painter->fillRect(rect, QBrush(QColor(240,240,240))); - - // draw the grid - - QPen pen1; - //pen1.setWidthF(0.5); - pen1.setCosmetic(true); - pen1.setColor(QColor(250,250,255)); - - QPen pen2 = pen1; - pen2.setColor(QColor(240,240,250)); - - QPen pen3 = pen1; - pen3.setColor(QColor(220,220,240)); - - painter->setPen(pen1); - - if (_scale > 0.2f) { - for (int x = -GRID_SEP; x > rect.left(); x -= GRID_SEP) { - if (x % (GRID_SEP * GRID_N) != 0) { - qreal xf = (qreal)x; - painter->drawLine(xf, rect.top(), xf, rect.bottom()); - } - } - - for (int x = GRID_SEP; x < rect.right(); x += GRID_SEP) { - if (x % (GRID_SEP * GRID_N) != 0) { - qreal xf = (qreal)x; - painter->drawLine(xf, rect.top(), xf, rect.bottom()); - } - } - - for (int y = -GRID_SEP; y > rect.top(); y -= GRID_SEP) { - if (y % (GRID_SEP * GRID_N) != 0) { - qreal yf = (qreal)y; - painter->drawLine(rect.left(), yf, rect.right(), yf); - } - } - - for (int y = GRID_SEP; y < rect.bottom(); y += GRID_SEP) { - if (y % (GRID_SEP * GRID_N) != 0) { - qreal yf = (qreal)y; - painter->drawLine(rect.left(), yf, rect.right(), yf); - } - } - } - - painter->setPen(pen2); - - for (int x = -GRID_SEP*GRID_N; x > rect.left(); x -= GRID_SEP*GRID_N) { - qreal xf = (qreal)x; - painter->drawLine(xf, rect.top(), xf, rect.bottom()); - } - - for (int x = GRID_SEP*GRID_N; x < rect.right(); x += GRID_SEP*GRID_N) { - qreal xf = (qreal)x; - painter->drawLine(xf, rect.top(), xf, rect.bottom()); - } - - for (int y = -GRID_SEP*GRID_N; y > rect.top(); y -= GRID_SEP*GRID_N) { - qreal yf = (qreal)y; - painter->drawLine(rect.left(), yf, rect.right(), yf); - } - - for (int y = GRID_SEP*GRID_N; y < rect.bottom(); y += GRID_SEP*GRID_N) { - qreal yf = (qreal)y; - painter->drawLine(rect.left(), yf, rect.right(), yf); - } - - painter->setPen(pen3); - painter->drawLine(rect.left(), 0, rect.right(), 0); - painter->drawLine(0, rect.top(), 0, rect.bottom()); -} - +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "tikzview.h"
+#include "tikzit.h"
+
+#include <QDebug>
+#include <QScrollBar>
+
+TikzView::TikzView(QWidget *parent) : QGraphicsView(parent)
+{
+ setRenderHint(QPainter::Antialiasing);
+ //setDragMode(QGraphicsView::RubberBandDrag);
+
+ _scale = 1.0f;
+}
+
+void TikzView::zoomIn()
+{
+ _scale *= 1.6f;
+ scale(1.6,1.6);
+}
+
+void TikzView::zoomOut()
+{
+ _scale *= 0.625f;
+ scale(0.625,0.625);
+}
+
+void TikzView::setScene(QGraphicsScene *scene)
+{
+ QGraphicsView::setScene(scene);
+ centerOn(QPointF(0.0f,-230.0f));
+}
+
+void TikzView::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ // draw a gray background if disabled
+ TikzScene *sc = static_cast<TikzScene*>(scene());
+ if (!sc->enabled()) painter->fillRect(rect, QBrush(QColor(240,240,240)));
+
+ // draw the grid
+
+ QPen pen1;
+ //pen1.setWidthF(0.5);
+ pen1.setCosmetic(true);
+ pen1.setColor(QColor(250,250,255));
+
+ QPen pen2 = pen1;
+ pen2.setColor(QColor(240,240,250));
+
+ QPen pen3 = pen1;
+ pen3.setColor(QColor(220,220,240));
+
+ painter->setPen(pen1);
+
+ if (_scale > 0.2f) {
+ for (int x = -GRID_SEP; x > rect.left(); x -= GRID_SEP) {
+ if (x % (GRID_SEP * GRID_N) != 0) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+ }
+
+ for (int x = GRID_SEP; x < rect.right(); x += GRID_SEP) {
+ if (x % (GRID_SEP * GRID_N) != 0) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+ }
+
+ for (int y = -GRID_SEP; y > rect.top(); y -= GRID_SEP) {
+ if (y % (GRID_SEP * GRID_N) != 0) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+ }
+
+ for (int y = GRID_SEP; y < rect.bottom(); y += GRID_SEP) {
+ if (y % (GRID_SEP * GRID_N) != 0) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+ }
+ }
+
+ painter->setPen(pen2);
+
+ for (int x = -GRID_SEP*GRID_N; x > rect.left(); x -= GRID_SEP*GRID_N) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+
+ for (int x = GRID_SEP*GRID_N; x < rect.right(); x += GRID_SEP*GRID_N) {
+ qreal xf = (qreal)x;
+ painter->drawLine(xf, rect.top(), xf, rect.bottom());
+ }
+
+ for (int y = -GRID_SEP*GRID_N; y > rect.top(); y -= GRID_SEP*GRID_N) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+
+ for (int y = GRID_SEP*GRID_N; y < rect.bottom(); y += GRID_SEP*GRID_N) {
+ qreal yf = (qreal)y;
+ painter->drawLine(rect.left(), yf, rect.right(), yf);
+ }
+
+ painter->setPen(pen3);
+ painter->drawLine(rect.left(), 0, rect.right(), 0);
+ painter->drawLine(0, rect.top(), 0, rect.bottom());
+}
+
diff --git a/src/gui/tikzview.h b/src/gui/tikzview.h index 4ec9f3d..bfa7ace 100644 --- a/src/gui/tikzview.h +++ b/src/gui/tikzview.h @@ -1,52 +1,52 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * Display a Graph, and manage any user input that purely changes the view (e.g. Zoom). This - * serves as the view in the MVC (TikzDocument, TikzView, TikzScene). - */ - -#ifndef TIKZVIEW_H -#define TIKZVIEW_H - -#include <QObject> -#include <QWidget> -#include <QGraphicsView> -#include <QPainter> -#include <QGraphicsItem> -#include <QStyleOptionGraphicsItem> -#include <QRectF> -#include <QMouseEvent> - -class TikzView : public QGraphicsView -{ - Q_OBJECT -public: - explicit TikzView(QWidget *parent = 0); - -public slots: - void zoomIn(); - void zoomOut(); - void setScene(QGraphicsScene *scene); -protected: - void drawBackground(QPainter *painter, const QRectF &rect); -private: - float _scale; -}; - -#endif // TIKZVIEW_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * Display a Graph, and manage any user input that purely changes the view (e.g. Zoom). This
+ * serves as the view in the MVC (TikzDocument, TikzView, TikzScene).
+ */
+
+#ifndef TIKZVIEW_H
+#define TIKZVIEW_H
+
+#include <QObject>
+#include <QWidget>
+#include <QGraphicsView>
+#include <QPainter>
+#include <QGraphicsItem>
+#include <QStyleOptionGraphicsItem>
+#include <QRectF>
+#include <QMouseEvent>
+
+class TikzView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ explicit TikzView(QWidget *parent = 0);
+
+public slots:
+ void zoomIn();
+ void zoomOut();
+ void setScene(QGraphicsScene *scene);
+protected:
+ void drawBackground(QPainter *painter, const QRectF &rect);
+private:
+ float _scale;
+};
+
+#endif // TIKZVIEW_H
diff --git a/src/gui/toolpalette.cpp b/src/gui/toolpalette.cpp index 43a4a49..2931f82 100644 --- a/src/gui/toolpalette.cpp +++ b/src/gui/toolpalette.cpp @@ -1,86 +1,86 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "toolpalette.h" - -#include <QVector> -#include <QLayout> -#include <QVBoxLayout> -#include <QDebug> - -ToolPalette::ToolPalette(QWidget *parent) : - QToolBar(parent) -{ - setWindowFlags(Qt::Window - | Qt::CustomizeWindowHint - | Qt::WindowDoesNotAcceptFocus); - setOrientation(Qt::Vertical); - setFocusPolicy(Qt::NoFocus); - //setGeometry(100,200,30,195); - - tools = new QActionGroup(this); - - select = new QAction(QIcon(":/images/Inkscape_icons_edit_select_all.svg"), "Select"); - vertex = new QAction(QIcon(":/images/Inkscape_icons_draw_ellipse.svg"), "Add Vertex"); - edge = new QAction(QIcon(":/images/Inkscape_icons_draw_path.svg"), "Add Edge"); - crop = new QAction(QIcon(":/images/crop.svg"), "Bounding Box"); - - tools->addAction(select); - tools->addAction(vertex); - tools->addAction(edge); - tools->addAction(crop); - - select->setCheckable(true); - vertex->setCheckable(true); - edge->setCheckable(true); - crop->setCheckable(true); - select->setChecked(true); - - addAction(select); - addAction(vertex); - addAction(edge); - addAction(crop); -} - -ToolPalette::Tool ToolPalette::currentTool() const -{ - QAction *a = tools->checkedAction(); - if (a == vertex) return VERTEX; - else if (a == edge) return EDGE; - else if (a == crop) return CROP; - else return SELECT; -} - -void ToolPalette::setCurrentTool(ToolPalette::Tool tool) -{ - switch(tool) { - case SELECT: - select->setChecked(true); - break; - case VERTEX: - vertex->setChecked(true); - break; - case EDGE: - edge->setChecked(true); - break; - case CROP: - crop->setChecked(true); - break; - } -} - +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "toolpalette.h"
+
+#include <QVector>
+#include <QLayout>
+#include <QVBoxLayout>
+#include <QDebug>
+
+ToolPalette::ToolPalette(QWidget *parent) :
+ QToolBar(parent)
+{
+ setWindowFlags(Qt::Window
+ | Qt::CustomizeWindowHint
+ | Qt::WindowDoesNotAcceptFocus);
+ setOrientation(Qt::Vertical);
+ setFocusPolicy(Qt::NoFocus);
+ //setGeometry(100,200,30,195);
+
+ tools = new QActionGroup(this);
+
+ select = new QAction(QIcon(":/images/Inkscape_icons_edit_select_all.svg"), "Select");
+ vertex = new QAction(QIcon(":/images/Inkscape_icons_draw_ellipse.svg"), "Add Vertex");
+ edge = new QAction(QIcon(":/images/Inkscape_icons_draw_path.svg"), "Add Edge");
+ crop = new QAction(QIcon(":/images/crop.svg"), "Bounding Box");
+
+ tools->addAction(select);
+ tools->addAction(vertex);
+ tools->addAction(edge);
+ tools->addAction(crop);
+
+ select->setCheckable(true);
+ vertex->setCheckable(true);
+ edge->setCheckable(true);
+ crop->setCheckable(true);
+ select->setChecked(true);
+
+ addAction(select);
+ addAction(vertex);
+ addAction(edge);
+ addAction(crop);
+}
+
+ToolPalette::Tool ToolPalette::currentTool() const
+{
+ QAction *a = tools->checkedAction();
+ if (a == vertex) return VERTEX;
+ else if (a == edge) return EDGE;
+ else if (a == crop) return CROP;
+ else return SELECT;
+}
+
+void ToolPalette::setCurrentTool(ToolPalette::Tool tool)
+{
+ switch(tool) {
+ case SELECT:
+ select->setChecked(true);
+ break;
+ case VERTEX:
+ vertex->setChecked(true);
+ break;
+ case EDGE:
+ edge->setChecked(true);
+ break;
+ case CROP:
+ crop->setChecked(true);
+ break;
+ }
+}
+
diff --git a/src/gui/toolpalette.h b/src/gui/toolpalette.h index a001055..d095d93 100644 --- a/src/gui/toolpalette.h +++ b/src/gui/toolpalette.h @@ -1,53 +1,53 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * A small window that lets the user select the current editing tool. - */ - -#ifndef TOOLPALETTE_H -#define TOOLPALETTE_H - -#include <QObject> -#include <QToolBar> -#include <QAction> -#include <QActionGroup> - -class ToolPalette : public QToolBar -{ - Q_OBJECT -public: - ToolPalette(QWidget *parent = 0); - enum Tool { - SELECT, - VERTEX, - EDGE, - CROP - }; - - Tool currentTool() const; - void setCurrentTool(Tool tool); -private: - QActionGroup *tools; - QAction *select; - QAction *vertex; - QAction *edge; - QAction *crop; -}; - -#endif // TOOLPALETTE_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * A small window that lets the user select the current editing tool.
+ */
+
+#ifndef TOOLPALETTE_H
+#define TOOLPALETTE_H
+
+#include <QObject>
+#include <QToolBar>
+#include <QAction>
+#include <QActionGroup>
+
+class ToolPalette : public QToolBar
+{
+ Q_OBJECT
+public:
+ ToolPalette(QWidget *parent = 0);
+ enum Tool {
+ SELECT,
+ VERTEX,
+ EDGE,
+ CROP
+ };
+
+ Tool currentTool() const;
+ void setCurrentTool(Tool tool);
+private:
+ QActionGroup *tools;
+ QAction *select;
+ QAction *vertex;
+ QAction *edge;
+ QAction *crop;
+};
+
+#endif // TOOLPALETTE_H
diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp index 5525cb7..dc7a797 100644 --- a/src/gui/undocommands.cpp +++ b/src/gui/undocommands.cpp @@ -1,428 +1,428 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -#include "undocommands.h" -#include "nodeitem.h" -#include "edgeitem.h" - -#include <QGraphicsView> - -GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent), _scene(scene) -{ -} - -void GraphUpdateCommand::undo() -{ - _scene->tikzDocument()->refreshTikz(); - //refreshSceneBounds does nothing - //_scene->refreshSceneBounds(); - _scene->invalidate(); -} - -void GraphUpdateCommand::redo() -{ - _scene->tikzDocument()->refreshTikz(); - //refreshSceneBounds does nothing - //_scene->refreshSceneBounds(); - _scene->invalidate(); -} - - -MoveCommand::MoveCommand(TikzScene *scene, - QMap<Node*, QPointF> oldNodePositions, - QMap<Node*, QPointF> newNodePositions, - QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), - _oldNodePositions(oldNodePositions), - _newNodePositions(newNodePositions) -{} - - -void MoveCommand::undo() -{ - foreach (NodeItem *ni, _scene->nodeItems()) { - if (_oldNodePositions.contains(ni->node())) { - ni->node()->setPoint(_oldNodePositions.value(ni->node())); - ni->readPos(); - } - } - - _scene->refreshAdjacentEdges(_oldNodePositions.keys()); - GraphUpdateCommand::undo(); -} - -void MoveCommand::redo() -{ - foreach (NodeItem *ni, _scene->nodeItems()) { - if (_newNodePositions.contains(ni->node())) { - ni->node()->setPoint(_newNodePositions.value(ni->node())); - ni->readPos(); - } - } - - _scene->refreshAdjacentEdges(_newNodePositions.keys()); - GraphUpdateCommand::redo(); -} - -EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge, - float oldWeight, int oldBend, - int oldInAngle, int oldOutAngle, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), - _edge(edge), - _oldWeight(oldWeight), _oldBend(oldBend), - _oldInAngle(oldInAngle), _oldOutAngle(oldOutAngle) -{ - _newWeight = edge->weight(); - _newBend = edge->bend(); - _newInAngle = edge->inAngle(); - _newOutAngle = edge->outAngle(); -} - -void EdgeBendCommand::undo() -{ - _edge->setWeight(_oldWeight); - _edge->setBend(_oldBend); - _edge->setInAngle(_oldInAngle); - _edge->setOutAngle(_oldOutAngle); - - foreach(EdgeItem *ei, _scene->edgeItems()) { - if (ei->edge() == _edge) { - ei->readPos(); - break; - } - } - GraphUpdateCommand::undo(); -} - -void EdgeBendCommand::redo() -{ - _edge->setWeight(_newWeight); - _edge->setBend(_newBend); - _edge->setInAngle(_newInAngle); - _edge->setOutAngle(_newOutAngle); - - foreach(EdgeItem *ei, _scene->edgeItems()) { - if (ei->edge() == _edge) { - ei->readPos(); - break; - } - } - - GraphUpdateCommand::redo(); -} - -DeleteCommand::DeleteCommand(TikzScene *scene, - QMap<int, Node *> deleteNodes, - QMap<int, Edge *> deleteEdges, - QSet<Edge *> selEdges, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), - _deleteNodes(deleteNodes), _deleteEdges(deleteEdges), _selEdges(selEdges) -{} - -void DeleteCommand::undo() -{ - for (auto it = _deleteNodes.begin(); it != _deleteNodes.end(); ++it) { - Node *n = it.value(); - n->attachStyle(); // in case styles have changed - _scene->graph()->addNode(n, it.key()); - NodeItem *ni = new NodeItem(n); - _scene->nodeItems().insert(n, ni); - _scene->addItem(ni); - ni->setSelected(true); - } - - for (auto it = _deleteEdges.begin(); it != _deleteEdges.end(); ++it) { - Edge *e = it.value(); - e->attachStyle(); - _scene->graph()->addEdge(e, it.key()); - EdgeItem *ei = new EdgeItem(e); - _scene->edgeItems().insert(e, ei); - _scene->addItem(ei); - - if (_selEdges.contains(e)) ei->setSelected(true); - } - - GraphUpdateCommand::undo(); -} - -void DeleteCommand::redo() -{ - foreach (Edge *e, _deleteEdges.values()) { - EdgeItem *ei = _scene->edgeItems()[e]; - _scene->edgeItems().remove(e); - _scene->removeItem(ei); - delete ei; - - _scene->graph()->removeEdge(e); - } - - foreach (Node *n, _deleteNodes.values()) { - NodeItem *ni = _scene->nodeItems()[n]; - _scene->nodeItems().remove(n); - _scene->removeItem(ni); - delete ni; - - _scene->graph()->removeNode(n); - } - - GraphUpdateCommand::redo(); -} - -AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds) -{ -} - -void AddNodeCommand::undo() -{ - NodeItem *ni = _scene->nodeItems()[_node]; - _scene->removeItem(ni); - _scene->nodeItems().remove(_node); - delete ni; - - _scene->graph()->removeNode(_node); - - //_scene->setBounds(_oldBounds); - - GraphUpdateCommand::undo(); -} - -void AddNodeCommand::redo() -{ - _node->attachStyle(); // do for every redo, in case styles have changed - _scene->graph()->addNode(_node); - NodeItem *ni = new NodeItem(_node); - _scene->nodeItems().insert(_node, ni); - _scene->addItem(ni); - - //_scene->setBounds(_newBounds); - - GraphUpdateCommand::redo(); -} - -AddEdgeCommand::AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _edge(edge) -{ -} - -void AddEdgeCommand::undo() -{ - EdgeItem *ei = _scene->edgeItems()[_edge]; - _scene->removeItem(ei); - _scene->edgeItems().remove(_edge); - delete ei; - - _scene->graph()->removeEdge(_edge); - GraphUpdateCommand::undo(); -} - -void AddEdgeCommand::redo() -{ - _edge->attachStyle(); // do for every redo, in case styles have changed - _scene->graph()->addEdge(_edge); - EdgeItem *ei = new EdgeItem(_edge); - _scene->edgeItems().insert(_edge, ei); - _scene->addItem(ei); - - // TODO: deal consistently with stacking order - // edges should always be stacked below nodes - if (!_scene->graph()->nodes().isEmpty()) { - ei->stackBefore(_scene->nodeItems()[_scene->graph()->nodes().first()]); - } - - GraphUpdateCommand::redo(); -} - -ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _edge(edge) -{ -} - -void ChangeEdgeModeCommand::undo() -{ - // FIXME: this act strangely sometimes - _edge->setBasicBendMode(!_edge->basicBendMode()); - _scene->edgeItems()[_edge]->readPos(); - GraphUpdateCommand::undo(); -} - -void ChangeEdgeModeCommand::redo() -{ - _edge->setBasicBendMode(!_edge->basicBendMode()); - _scene->edgeItems()[_edge]->readPos(); - GraphUpdateCommand::redo(); -} - -ApplyStyleToNodesCommand::ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _style(style), _oldStyles() -{ - foreach (QGraphicsItem *it, scene->selectedItems()) { - if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) { - _oldStyles.insert(ni->node(), ni->node()->styleName()); - } - } -} - -void ApplyStyleToNodesCommand::undo() -{ - foreach (Node *n, _oldStyles.keys()) { - n->setStyleName(_oldStyles[n]); - n->attachStyle(); - } - - GraphUpdateCommand::undo(); -} - -void ApplyStyleToNodesCommand::redo() -{ - foreach (Node *n, _oldStyles.keys()) { - n->setStyleName(_style); - n->attachStyle(); - } - GraphUpdateCommand::redo(); -} - -ApplyStyleToEdgesCommand::ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _style(style), _oldStyles() -{ - foreach(QGraphicsItem *it, scene->selectedItems()) { - if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) { - _oldStyles.insert(ei->edge(), ei->edge()->styleName()); - } - } -} - -void ApplyStyleToEdgesCommand::undo() -{ - foreach(Edge *e, _oldStyles.keys()) { - e->setStyleName(_oldStyles[e]); - e->attachStyle(); - } - - GraphUpdateCommand::undo(); -} - -void ApplyStyleToEdgesCommand::redo() -{ - foreach(Edge *e, _oldStyles.keys()) { - e->setStyleName(_style); - e->attachStyle(); - } - GraphUpdateCommand::redo(); -} - -PasteCommand::PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _graph(graph) -{ - scene->getSelection(_oldSelectedNodes, _oldSelectedEdges); -} - -void PasteCommand::undo() -{ - _scene->clearSelection(); - - foreach (Edge *e, _graph->edges()) { - EdgeItem *ei = _scene->edgeItems()[e]; - _scene->edgeItems().remove(e); - _scene->removeItem(ei); - delete ei; - - _scene->graph()->removeEdge(e); - } - - foreach (Node *n, _graph->nodes()) { - NodeItem *ni = _scene->nodeItems()[n]; - _scene->nodeItems().remove(n); - _scene->removeItem(ni); - delete ni; - - _scene->graph()->removeNode(n); - } - - foreach(Node *n, _oldSelectedNodes) _scene->nodeItems()[n]->setSelected(true); - foreach(Edge *e, _oldSelectedEdges) _scene->edgeItems()[e]->setSelected(true); - - GraphUpdateCommand::undo(); -} - -void PasteCommand::redo() -{ - _scene->clearSelection(); - _scene->graph()->insertGraph(_graph); - - foreach (Edge *e, _graph->edges()) { - e->attachStyle(); // in case styles have changed - EdgeItem *ei = new EdgeItem(e); - _scene->edgeItems().insert(e, ei); - _scene->addItem(ei); - } - - foreach (Node *n, _graph->nodes()) { - n->attachStyle(); // in case styles have changed - NodeItem *ni = new NodeItem(n); - _scene->nodeItems().insert(n, ni); - _scene->addItem(ni); - ni->setSelected(true); - } - - GraphUpdateCommand::redo(); -} - -ChangeLabelCommand::ChangeLabelCommand(TikzScene *scene, Graph *graph, QMap<Node *, QString> oldLabels, QString newLabel, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _oldLabels(oldLabels), _newLabel(newLabel) -{ -} - -void ChangeLabelCommand::undo() -{ - foreach (Node *n, _oldLabels.keys()) { - n->setLabel(_oldLabels[n]); - NodeItem *ni = _scene->nodeItems()[n]; - if (ni != 0) ni->updateBounds(); - } - - GraphUpdateCommand::undo(); -} - -void ChangeLabelCommand::redo() -{ - foreach (Node *n, _oldLabels.keys()) { - n->setLabel(_newLabel); - NodeItem *ni = _scene->nodeItems()[n]; - if (ni != 0) ni->updateBounds(); - } - - GraphUpdateCommand::redo(); -} - -ReplaceGraphCommand::ReplaceGraphCommand(TikzScene *scene, Graph *oldGraph, Graph *newGraph, QUndoCommand *parent) : - GraphUpdateCommand(scene, parent), _oldGraph(oldGraph), _newGraph(newGraph) -{ -} - -void ReplaceGraphCommand::undo() -{ - _scene->tikzDocument()->setGraph(_oldGraph); - _scene->graphReplaced(); -} - -void ReplaceGraphCommand::redo() -{ - _scene->tikzDocument()->setGraph(_newGraph); - _scene->graphReplaced(); -} +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "undocommands.h"
+#include "nodeitem.h"
+#include "edgeitem.h"
+
+#include <QGraphicsView>
+
+GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent), _scene(scene)
+{
+}
+
+void GraphUpdateCommand::undo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ //refreshSceneBounds does nothing
+ //_scene->refreshSceneBounds();
+ _scene->invalidate();
+}
+
+void GraphUpdateCommand::redo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ //refreshSceneBounds does nothing
+ //_scene->refreshSceneBounds();
+ _scene->invalidate();
+}
+
+
+MoveCommand::MoveCommand(TikzScene *scene,
+ QMap<Node*, QPointF> oldNodePositions,
+ QMap<Node*, QPointF> newNodePositions,
+ QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _oldNodePositions(oldNodePositions),
+ _newNodePositions(newNodePositions)
+{}
+
+
+void MoveCommand::undo()
+{
+ foreach (NodeItem *ni, _scene->nodeItems()) {
+ if (_oldNodePositions.contains(ni->node())) {
+ ni->node()->setPoint(_oldNodePositions.value(ni->node()));
+ ni->readPos();
+ }
+ }
+
+ _scene->refreshAdjacentEdges(_oldNodePositions.keys());
+ GraphUpdateCommand::undo();
+}
+
+void MoveCommand::redo()
+{
+ foreach (NodeItem *ni, _scene->nodeItems()) {
+ if (_newNodePositions.contains(ni->node())) {
+ ni->node()->setPoint(_newNodePositions.value(ni->node()));
+ ni->readPos();
+ }
+ }
+
+ _scene->refreshAdjacentEdges(_newNodePositions.keys());
+ GraphUpdateCommand::redo();
+}
+
+EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge,
+ float oldWeight, int oldBend,
+ int oldInAngle, int oldOutAngle, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _edge(edge),
+ _oldWeight(oldWeight), _oldBend(oldBend),
+ _oldInAngle(oldInAngle), _oldOutAngle(oldOutAngle)
+{
+ _newWeight = edge->weight();
+ _newBend = edge->bend();
+ _newInAngle = edge->inAngle();
+ _newOutAngle = edge->outAngle();
+}
+
+void EdgeBendCommand::undo()
+{
+ _edge->setWeight(_oldWeight);
+ _edge->setBend(_oldBend);
+ _edge->setInAngle(_oldInAngle);
+ _edge->setOutAngle(_oldOutAngle);
+
+ foreach(EdgeItem *ei, _scene->edgeItems()) {
+ if (ei->edge() == _edge) {
+ ei->readPos();
+ break;
+ }
+ }
+ GraphUpdateCommand::undo();
+}
+
+void EdgeBendCommand::redo()
+{
+ _edge->setWeight(_newWeight);
+ _edge->setBend(_newBend);
+ _edge->setInAngle(_newInAngle);
+ _edge->setOutAngle(_newOutAngle);
+
+ foreach(EdgeItem *ei, _scene->edgeItems()) {
+ if (ei->edge() == _edge) {
+ ei->readPos();
+ break;
+ }
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+DeleteCommand::DeleteCommand(TikzScene *scene,
+ QMap<int, Node *> deleteNodes,
+ QMap<int, Edge *> deleteEdges,
+ QSet<Edge *> selEdges, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _deleteNodes(deleteNodes), _deleteEdges(deleteEdges), _selEdges(selEdges)
+{}
+
+void DeleteCommand::undo()
+{
+ for (auto it = _deleteNodes.begin(); it != _deleteNodes.end(); ++it) {
+ Node *n = it.value();
+ n->attachStyle(); // in case styles have changed
+ _scene->graph()->addNode(n, it.key());
+ NodeItem *ni = new NodeItem(n);
+ _scene->nodeItems().insert(n, ni);
+ _scene->addItem(ni);
+ ni->setSelected(true);
+ }
+
+ for (auto it = _deleteEdges.begin(); it != _deleteEdges.end(); ++it) {
+ Edge *e = it.value();
+ e->attachStyle();
+ _scene->graph()->addEdge(e, it.key());
+ EdgeItem *ei = new EdgeItem(e);
+ _scene->edgeItems().insert(e, ei);
+ _scene->addItem(ei);
+
+ if (_selEdges.contains(e)) ei->setSelected(true);
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void DeleteCommand::redo()
+{
+ foreach (Edge *e, _deleteEdges.values()) {
+ EdgeItem *ei = _scene->edgeItems()[e];
+ _scene->edgeItems().remove(e);
+ _scene->removeItem(ei);
+ delete ei;
+
+ _scene->graph()->removeEdge(e);
+ }
+
+ foreach (Node *n, _deleteNodes.values()) {
+ NodeItem *ni = _scene->nodeItems()[n];
+ _scene->nodeItems().remove(n);
+ _scene->removeItem(ni);
+ delete ni;
+
+ _scene->graph()->removeNode(n);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds)
+{
+}
+
+void AddNodeCommand::undo()
+{
+ NodeItem *ni = _scene->nodeItems()[_node];
+ _scene->removeItem(ni);
+ _scene->nodeItems().remove(_node);
+ delete ni;
+
+ _scene->graph()->removeNode(_node);
+
+ //_scene->setBounds(_oldBounds);
+
+ GraphUpdateCommand::undo();
+}
+
+void AddNodeCommand::redo()
+{
+ _node->attachStyle(); // do for every redo, in case styles have changed
+ _scene->graph()->addNode(_node);
+ NodeItem *ni = new NodeItem(_node);
+ _scene->nodeItems().insert(_node, ni);
+ _scene->addItem(ni);
+
+ //_scene->setBounds(_newBounds);
+
+ GraphUpdateCommand::redo();
+}
+
+AddEdgeCommand::AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
+{
+}
+
+void AddEdgeCommand::undo()
+{
+ EdgeItem *ei = _scene->edgeItems()[_edge];
+ _scene->removeItem(ei);
+ _scene->edgeItems().remove(_edge);
+ delete ei;
+
+ _scene->graph()->removeEdge(_edge);
+ GraphUpdateCommand::undo();
+}
+
+void AddEdgeCommand::redo()
+{
+ _edge->attachStyle(); // do for every redo, in case styles have changed
+ _scene->graph()->addEdge(_edge);
+ EdgeItem *ei = new EdgeItem(_edge);
+ _scene->edgeItems().insert(_edge, ei);
+ _scene->addItem(ei);
+
+ // TODO: deal consistently with stacking order
+ // edges should always be stacked below nodes
+ if (!_scene->graph()->nodes().isEmpty()) {
+ ei->stackBefore(_scene->nodeItems()[_scene->graph()->nodes().first()]);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
+{
+}
+
+void ChangeEdgeModeCommand::undo()
+{
+ // FIXME: this act strangely sometimes
+ _edge->setBasicBendMode(!_edge->basicBendMode());
+ _scene->edgeItems()[_edge]->readPos();
+ GraphUpdateCommand::undo();
+}
+
+void ChangeEdgeModeCommand::redo()
+{
+ _edge->setBasicBendMode(!_edge->basicBendMode());
+ _scene->edgeItems()[_edge]->readPos();
+ GraphUpdateCommand::redo();
+}
+
+ApplyStyleToNodesCommand::ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
+{
+ foreach (QGraphicsItem *it, scene->selectedItems()) {
+ if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) {
+ _oldStyles.insert(ni->node(), ni->node()->styleName());
+ }
+ }
+}
+
+void ApplyStyleToNodesCommand::undo()
+{
+ foreach (Node *n, _oldStyles.keys()) {
+ n->setStyleName(_oldStyles[n]);
+ n->attachStyle();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ApplyStyleToNodesCommand::redo()
+{
+ foreach (Node *n, _oldStyles.keys()) {
+ n->setStyleName(_style);
+ n->attachStyle();
+ }
+ GraphUpdateCommand::redo();
+}
+
+ApplyStyleToEdgesCommand::ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _style(style), _oldStyles()
+{
+ foreach(QGraphicsItem *it, scene->selectedItems()) {
+ if (EdgeItem *ei = dynamic_cast<EdgeItem*>(it)) {
+ _oldStyles.insert(ei->edge(), ei->edge()->styleName());
+ }
+ }
+}
+
+void ApplyStyleToEdgesCommand::undo()
+{
+ foreach(Edge *e, _oldStyles.keys()) {
+ e->setStyleName(_oldStyles[e]);
+ e->attachStyle();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ApplyStyleToEdgesCommand::redo()
+{
+ foreach(Edge *e, _oldStyles.keys()) {
+ e->setStyleName(_style);
+ e->attachStyle();
+ }
+ GraphUpdateCommand::redo();
+}
+
+PasteCommand::PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _graph(graph)
+{
+ scene->getSelection(_oldSelectedNodes, _oldSelectedEdges);
+}
+
+void PasteCommand::undo()
+{
+ _scene->clearSelection();
+
+ foreach (Edge *e, _graph->edges()) {
+ EdgeItem *ei = _scene->edgeItems()[e];
+ _scene->edgeItems().remove(e);
+ _scene->removeItem(ei);
+ delete ei;
+
+ _scene->graph()->removeEdge(e);
+ }
+
+ foreach (Node *n, _graph->nodes()) {
+ NodeItem *ni = _scene->nodeItems()[n];
+ _scene->nodeItems().remove(n);
+ _scene->removeItem(ni);
+ delete ni;
+
+ _scene->graph()->removeNode(n);
+ }
+
+ foreach(Node *n, _oldSelectedNodes) _scene->nodeItems()[n]->setSelected(true);
+ foreach(Edge *e, _oldSelectedEdges) _scene->edgeItems()[e]->setSelected(true);
+
+ GraphUpdateCommand::undo();
+}
+
+void PasteCommand::redo()
+{
+ _scene->clearSelection();
+ _scene->graph()->insertGraph(_graph);
+
+ foreach (Edge *e, _graph->edges()) {
+ e->attachStyle(); // in case styles have changed
+ EdgeItem *ei = new EdgeItem(e);
+ _scene->edgeItems().insert(e, ei);
+ _scene->addItem(ei);
+ }
+
+ foreach (Node *n, _graph->nodes()) {
+ n->attachStyle(); // in case styles have changed
+ NodeItem *ni = new NodeItem(n);
+ _scene->nodeItems().insert(n, ni);
+ _scene->addItem(ni);
+ ni->setSelected(true);
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ChangeLabelCommand::ChangeLabelCommand(TikzScene *scene, Graph *graph, QMap<Node *, QString> oldLabels, QString newLabel, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _oldLabels(oldLabels), _newLabel(newLabel)
+{
+}
+
+void ChangeLabelCommand::undo()
+{
+ foreach (Node *n, _oldLabels.keys()) {
+ n->setLabel(_oldLabels[n]);
+ NodeItem *ni = _scene->nodeItems()[n];
+ if (ni != 0) ni->updateBounds();
+ }
+
+ GraphUpdateCommand::undo();
+}
+
+void ChangeLabelCommand::redo()
+{
+ foreach (Node *n, _oldLabels.keys()) {
+ n->setLabel(_newLabel);
+ NodeItem *ni = _scene->nodeItems()[n];
+ if (ni != 0) ni->updateBounds();
+ }
+
+ GraphUpdateCommand::redo();
+}
+
+ReplaceGraphCommand::ReplaceGraphCommand(TikzScene *scene, Graph *oldGraph, Graph *newGraph, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _oldGraph(oldGraph), _newGraph(newGraph)
+{
+}
+
+void ReplaceGraphCommand::undo()
+{
+ _scene->tikzDocument()->setGraph(_oldGraph);
+ _scene->graphReplaced();
+}
+
+void ReplaceGraphCommand::redo()
+{
+ _scene->tikzDocument()->setGraph(_newGraph);
+ _scene->graphReplaced();
+}
diff --git a/src/gui/undocommands.h b/src/gui/undocommands.h index 292632e..9164f01 100644 --- a/src/gui/undocommands.h +++ b/src/gui/undocommands.h @@ -1,194 +1,194 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -*/ - -/*! - * \file undocommands.h - * - * All changes to a TikzDocument are done via subclasses of QUndoCommand. When a controller - * (e.g. TikzScene) gets input from the user to change the document, it will push one of - * these commands onto the TikzDocument's undo stack, which automatically calls the redo() - * method of the command. - */ - -#ifndef UNDOCOMMANDS_H -#define UNDOCOMMANDS_H - -#include "tikzscene.h" - -#include <QUndoCommand> -#include <QSet> - -class GraphUpdateCommand : public QUndoCommand { -public: - explicit GraphUpdateCommand(TikzScene *scene, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -protected: - TikzScene *_scene; -}; - -class MoveCommand : public GraphUpdateCommand -{ -public: - explicit MoveCommand(TikzScene *scene, - QMap<Node*,QPointF> oldNodePositions, - QMap<Node*,QPointF> newNodePositions, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - QMap<Node*,QPointF> _oldNodePositions; - QMap<Node*,QPointF> _newNodePositions; -}; - -class EdgeBendCommand : public GraphUpdateCommand -{ -public: - explicit EdgeBendCommand(TikzScene *scene, Edge *edge, - float oldWeight, int oldBend, - int oldInAngle, int oldOutAngle, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Edge *_edge; - float _oldWeight; - int _oldBend; - int _oldInAngle; - int _oldOutAngle; - float _newWeight; - int _newBend; - int _newInAngle; - int _newOutAngle; -}; - -class DeleteCommand : public GraphUpdateCommand -{ -public: - explicit DeleteCommand(TikzScene *scene, - QMap<int,Node*> deleteNodes, - QMap<int,Edge*> deleteEdges, - QSet<Edge*> selEdges, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - QMap<int,Node*> _deleteNodes; - QMap<int,Edge*> _deleteEdges; - QSet<Edge*> _selEdges; -}; - -class AddNodeCommand : public GraphUpdateCommand -{ -public: - explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Node *_node; - QRectF _oldBounds; - QRectF _newBounds; -}; - -class AddEdgeCommand : public GraphUpdateCommand -{ -public: - explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Edge *_edge; -}; - -class ChangeEdgeModeCommand : public GraphUpdateCommand -{ -public: - explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Edge *_edge; -}; - -class ApplyStyleToNodesCommand : public GraphUpdateCommand -{ -public: - explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - QString _style; - QMap<Node*,QString> _oldStyles; -}; - -class ApplyStyleToEdgesCommand : public GraphUpdateCommand -{ -public: - explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - QString _style; - QMap<Edge*, QString> _oldStyles; -}; - -class PasteCommand : public GraphUpdateCommand -{ -public: - explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Graph *_graph; - QSet<Node*> _oldSelectedNodes; - QSet<Edge*> _oldSelectedEdges; -}; - -class ChangeLabelCommand : public GraphUpdateCommand -{ -public: - explicit ChangeLabelCommand(TikzScene *scene, - Graph *graph, - QMap<Node*,QString> oldLabels, - QString newLabel, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Graph *_graph; - QMap<Node*,QString> _oldLabels; - QString _newLabel; -}; - -class ReplaceGraphCommand : public GraphUpdateCommand -{ -public: - explicit ReplaceGraphCommand(TikzScene *scene, - Graph *oldGraph, - Graph *newGraph, - QUndoCommand *parent = 0); - void undo() override; - void redo() override; -private: - Graph *_oldGraph; - Graph *_newGraph; -}; - -#endif // UNDOCOMMANDS_H +/*
+ TikZiT - a GUI diagram editor for TikZ
+ Copyright (C) 2018 Aleks Kissinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+/*!
+ * \file undocommands.h
+ *
+ * All changes to a TikzDocument are done via subclasses of QUndoCommand. When a controller
+ * (e.g. TikzScene) gets input from the user to change the document, it will push one of
+ * these commands onto the TikzDocument's undo stack, which automatically calls the redo()
+ * method of the command.
+ */
+
+#ifndef UNDOCOMMANDS_H
+#define UNDOCOMMANDS_H
+
+#include "tikzscene.h"
+
+#include <QUndoCommand>
+#include <QSet>
+
+class GraphUpdateCommand : public QUndoCommand {
+public:
+ explicit GraphUpdateCommand(TikzScene *scene,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+protected:
+ TikzScene *_scene;
+};
+
+class MoveCommand : public GraphUpdateCommand
+{
+public:
+ explicit MoveCommand(TikzScene *scene,
+ QMap<Node*,QPointF> oldNodePositions,
+ QMap<Node*,QPointF> newNodePositions,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QMap<Node*,QPointF> _oldNodePositions;
+ QMap<Node*,QPointF> _newNodePositions;
+};
+
+class EdgeBendCommand : public GraphUpdateCommand
+{
+public:
+ explicit EdgeBendCommand(TikzScene *scene, Edge *edge,
+ float oldWeight, int oldBend,
+ int oldInAngle, int oldOutAngle,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+ float _oldWeight;
+ int _oldBend;
+ int _oldInAngle;
+ int _oldOutAngle;
+ float _newWeight;
+ int _newBend;
+ int _newInAngle;
+ int _newOutAngle;
+};
+
+class DeleteCommand : public GraphUpdateCommand
+{
+public:
+ explicit DeleteCommand(TikzScene *scene,
+ QMap<int,Node*> deleteNodes,
+ QMap<int,Edge*> deleteEdges,
+ QSet<Edge*> selEdges,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QMap<int,Node*> _deleteNodes;
+ QMap<int,Edge*> _deleteEdges;
+ QSet<Edge*> _selEdges;
+};
+
+class AddNodeCommand : public GraphUpdateCommand
+{
+public:
+ explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Node *_node;
+ QRectF _oldBounds;
+ QRectF _newBounds;
+};
+
+class AddEdgeCommand : public GraphUpdateCommand
+{
+public:
+ explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+};
+
+class ChangeEdgeModeCommand : public GraphUpdateCommand
+{
+public:
+ explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Edge *_edge;
+};
+
+class ApplyStyleToNodesCommand : public GraphUpdateCommand
+{
+public:
+ explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QString _style;
+ QMap<Node*,QString> _oldStyles;
+};
+
+class ApplyStyleToEdgesCommand : public GraphUpdateCommand
+{
+public:
+ explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ QString _style;
+ QMap<Edge*, QString> _oldStyles;
+};
+
+class PasteCommand : public GraphUpdateCommand
+{
+public:
+ explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_graph;
+ QSet<Node*> _oldSelectedNodes;
+ QSet<Edge*> _oldSelectedEdges;
+};
+
+class ChangeLabelCommand : public GraphUpdateCommand
+{
+public:
+ explicit ChangeLabelCommand(TikzScene *scene,
+ Graph *graph,
+ QMap<Node*,QString> oldLabels,
+ QString newLabel,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_graph;
+ QMap<Node*,QString> _oldLabels;
+ QString _newLabel;
+};
+
+class ReplaceGraphCommand : public GraphUpdateCommand
+{
+public:
+ explicit ReplaceGraphCommand(TikzScene *scene,
+ Graph *oldGraph,
+ Graph *newGraph,
+ QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_oldGraph;
+ Graph *_newGraph;
+};
+
+#endif // UNDOCOMMANDS_H
|