summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/mainmenu.cpp21
-rw-r--r--src/gui/mainwindow.cpp23
-rw-r--r--src/gui/mainwindow.h8
-rw-r--r--src/gui/nodeitem.cpp4
-rw-r--r--src/gui/tikzscene.cpp176
-rw-r--r--src/gui/tikzscene.h10
-rw-r--r--src/gui/toolpalette.cpp18
-rw-r--r--src/gui/toolpalette.h1
-rw-r--r--src/gui/undocommands.cpp147
-rw-r--r--src/gui/undocommands.h63
10 files changed, 391 insertions, 80 deletions
diff --git a/src/gui/mainmenu.cpp b/src/gui/mainmenu.cpp
index 714ed34..dfb447f 100644
--- a/src/gui/mainmenu.cpp
+++ b/src/gui/mainmenu.cpp
@@ -19,17 +19,20 @@ void MainMenu::on_actionOpen_triggered()
void MainMenu::on_actionClose_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->close();
}
void MainMenu::on_actionSave_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->save();
}
void MainMenu::on_actionSave_As_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzDocument()->saveAs();
}
void MainMenu::on_actionExit_triggered()
@@ -53,22 +56,26 @@ void MainMenu::on_actionRedo_triggered()
void MainMenu::on_actionCut_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->cutToClipboard();
}
void MainMenu::on_actionCopy_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->copyToClipboard();
}
void MainMenu::on_actionPaste_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->pasteFromClipboard();
}
void MainMenu::on_actionDelete_triggered()
{
- // TODO
+ if (tikzit->activeWindow() != 0)
+ tikzit->activeWindow()->tikzScene()->deleteSelectedItems();
}
void MainMenu::on_actionSelect_All_triggered()
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
index eac7c44..26e19b6 100644
--- a/src/gui/mainwindow.cpp
+++ b/src/gui/mainwindow.cpp
@@ -25,12 +25,11 @@ MainWindow::MainWindow(QWidget *parent) :
setAttribute(Qt::WA_DeleteOnClose, true);
_tikzDocument = new TikzDocument(this);
- _tools = new ToolPalette(this);
- addToolBar(_tools);
+ _toolPalette = new ToolPalette(this);
+ addToolBar(_toolPalette);
- _tikzScene = new TikzScene(_tikzDocument, _tools, this);
+ _tikzScene = new TikzScene(_tikzDocument, _toolPalette, this);
ui->tikzView->setScene(_tikzScene);
- _fileName = "";
_pristine = true;
@@ -80,10 +79,26 @@ void MainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::ActivationChange && isActiveWindow()) {
tikzit->setActiveWindow(this);
+ tikzit->stylePalette()->raise();
}
QMainWindow::changeEvent(event);
}
+void MainWindow::updateFileName()
+{
+ setWindowTitle("TiKZiT - " + _tikzDocument->shortName());
+}
+
+void MainWindow::refreshTikz()
+{
+ ui->tikzSource->setText(_tikzDocument->tikz());
+}
+
+ToolPalette *MainWindow::toolPalette() const
+{
+ return _toolPalette;
+}
+
TikzDocument *MainWindow::tikzDocument() const
{
return _tikzDocument;
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
index ba680b0..613bfcb 100644
--- a/src/gui/mainwindow.h
+++ b/src/gui/mainwindow.h
@@ -33,17 +33,19 @@ public:
TikzView *tikzView() const;
TikzScene *tikzScene() const;
TikzDocument *tikzDocument() const;
-
+ ToolPalette *toolPalette() const;
+ void updateFileName();
+ void refreshTikz();
protected:
void closeEvent(QCloseEvent *event);
void changeEvent(QEvent *event);
+
private:
TikzScene *_tikzScene;
TikzDocument *_tikzDocument;
MainMenu *_menu;
- ToolPalette *_tools;
+ ToolPalette *_toolPalette;
Ui::MainWindow *ui;
- QString _fileName;
bool _pristine;
int _windowId;
static int _numWindows;
diff --git a/src/gui/nodeitem.cpp b/src/gui/nodeitem.cpp
index 21cdf79..36d488c 100644
--- a/src/gui/nodeitem.cpp
+++ b/src/gui/nodeitem.cpp
@@ -15,8 +15,8 @@ NodeItem::NodeItem(Node *node)
{
_node = node;
setFlag(QGraphicsItem::ItemIsSelectable);
- setFlag(QGraphicsItem::ItemIsMovable);
- setFlag(QGraphicsItem::ItemSendsGeometryChanges);
+ //setFlag(QGraphicsItem::ItemIsMovable);
+ //setFlag(QGraphicsItem::ItemSendsGeometryChanges);
readPos();
}
diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp
index a3dd8ce..2ee3c50 100644
--- a/src/gui/tikzscene.cpp
+++ b/src/gui/tikzscene.cpp
@@ -2,10 +2,12 @@
#include "util.h"
#include "tikzscene.h"
#include "undocommands.h"
+#include "tikzassembler.h"
#include <QPen>
#include <QBrush>
#include <QDebug>
+#include <QClipboard>
TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, QObject *parent) :
@@ -63,7 +65,9 @@ void TikzScene::graphReplaced()
void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
// current mouse position, in scene coordinates
- QPointF mousePos = event->scenePos();
+ _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.
@@ -80,8 +84,8 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (EdgeItem *ei = dynamic_cast<EdgeItem*>(gi)) {
qreal dx, dy;
- dx = ei->cp1Item()->pos().x() - mousePos.x();
- dy = ei->cp1Item()->pos().y() - mousePos.y();
+ dx = ei->cp1Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp1Item()->pos().y() - _mouseDownPos.y();
if (dx*dx + dy*dy <= cpR2) {
_modifyEdgeItem = ei;
@@ -89,8 +93,8 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
break;
}
- dx = ei->cp2Item()->pos().x() - mousePos.x();
- dy = ei->cp2Item()->pos().y() - mousePos.y();
+ dx = ei->cp2Item()->pos().x() - _mouseDownPos.x();
+ dy = ei->cp2Item()->pos().y() - _mouseDownPos.y();
if (dx*dx + dy*dy <= cpR2) {
_modifyEdgeItem = ei;
@@ -119,17 +123,21 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
_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(mousePos)) {
+ foreach (QGraphicsItem *gi, items(_mouseDownPos)) {
if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){
_edgeStartNodeItem = ni;
_edgeEndNodeItem = ni;
- QLineF line(toScreen(ni->node()->point()), mousePos);
+ QLineF line(toScreen(ni->node()->point()), _mouseDownPos);
_drawEdgeItem->setLine(line);
_drawEdgeItem->setVisible(true);
break;
@@ -145,8 +153,9 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
// current mouse position, in scene coordinates
QPointF mousePos = event->scenePos();
- QRectF rb = views()[0]->rubberBandRect();
- invalidate(-800,-800,1600,1600);
+ //QRectF rb = views()[0]->rubberBandRect();
+ //invalidate(-800,-800,1600,1600);
+ invalidate(QRectF(), QGraphicsScene::BackgroundLayer);
switch (_tools->currentTool()) {
case ToolPalette::SELECT:
@@ -229,10 +238,25 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
_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;
+ int gridSize = GLOBAL_SCALE / 8;
+ shift = QPointF(round(shift.x()/gridSize)*gridSize, round(shift.y()/gridSize)*gridSize);
+
+ foreach (Node *n, _oldNodePositions.keys()) {
+ NodeItem *ni = _nodeItems[n];
+ ni->setPos(toScreen(_oldNodePositions[n]) + shift);
+ ni->writePos();
+ }
+
+ refreshAdjacentEdges(_oldNodePositions.keys());
} else {
// otherwise, process mouse move normally
QGraphicsScene::mouseMoveEvent(event);
- refreshAdjacentEdges(_oldNodePositions.keys());
}
break;
@@ -308,7 +332,9 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
int gridSize = GLOBAL_SCALE / 8;
QPointF gridPos(round(mousePos.x()/gridSize)*gridSize, round(mousePos.y()/gridSize)*gridSize);
Node *n = new Node(_tikzDocument);
+ n->setName(graph()->freshNodeName());
n->setPoint(fromScreen(gridPos));
+ n->setStyleName(tikzit->stylePalette()->activeNodeStyleName());
QRectF grow(gridPos.x() - GLOBAL_SCALEF, gridPos.y() - GLOBAL_SCALEF, 2 * GLOBAL_SCALEF, 2 * GLOBAL_SCALEF);
QRectF newBounds = sceneRect().united(grow);
@@ -332,34 +358,31 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
case ToolPalette::CROP:
break;
}
+
+ // clear artefacts from rubber band selection
+ invalidate(QRect(), QGraphicsScene::BackgroundLayer);
}
void TikzScene::keyReleaseEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
- 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);
+ 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;
}
-
- //qDebug() << "nodes:" << deleteNodes;
- //qDebug() << "edges:" << deleteEdges;
- DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges);
- _tikzDocument->undoStack()->push(cmd);
}
}
@@ -375,6 +398,78 @@ void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
}
}
+void TikzScene::applyActiveStyleToNodes() {
+ ApplyStyleToNodesCommand *cmd = new ApplyStyleToNodesCommand(this, tikzit->stylePalette()->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());
+
+ // shift g to the right until there is some free space
+ QPointF p0 = toScreen(g->nodes()[0]->point());
+ QPointF p = p0;
+ while (!items(p).isEmpty()) p.setX(p.x()+GLOBAL_SCALEF);
+ QPointF shift(roundf((p.x() - p0.x())/GLOBAL_SCALEF), 0.0f);
+ foreach (Node *n, g->nodes()) {
+ n->setPoint(n->point() + shift);
+ }
+
+ PasteCommand *cmd = new PasteCommand(this, g);
+ _tikzDocument->undoStack()->push(cmd);
+ }
+}
+
void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges)
{
foreach (QGraphicsItem *gi, selectedItems()) {
@@ -383,6 +478,15 @@ void TikzScene::getSelection(QSet<Node *> &selNodes, QSet<Edge *> &selEdges)
}
}
+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
{
@@ -395,6 +499,14 @@ void TikzScene::setTikzDocument(TikzDocument *tikzDocument)
graphReplaced();
}
+void TikzScene::reloadStyles()
+{
+ foreach (NodeItem *ni, _nodeItems) {
+ ni->node()->attachStyle();
+ ni->readPos(); // trigger a repaint
+ }
+}
+
void TikzScene::refreshAdjacentEdges(QList<Node*> nodes)
{
if (nodes.empty()) return;
diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h
index cb684b2..5d3eec2 100644
--- a/src/gui/tikzscene.h
+++ b/src/gui/tikzscene.h
@@ -34,7 +34,12 @@ public:
TikzDocument *tikzDocument() const;
void setTikzDocument(TikzDocument *tikzDocument);
-
+ void reloadStyles();
+ void applyActiveStyleToNodes();
+ void deleteSelectedItems();
+ void copyToClipboard();
+ void cutToClipboard();
+ void pasteFromClipboard();
public slots:
void graphReplaced();
@@ -54,6 +59,8 @@ private:
NodeItem *_edgeStartNodeItem;
NodeItem *_edgeEndNodeItem;
bool _firstControlPoint;
+ QPointF _mouseDownPos;
+ bool _draggingNodes;
QMap<Node*,QPointF> _oldNodePositions;
float _oldWeight;
@@ -62,6 +69,7 @@ private:
int _oldOutAngle;
void getSelection(QSet<Node*> &selNodes, QSet<Edge*> &selEdges);
+ QSet<Node*> getSelectedNodes();
};
#endif // TIKZSCENE_H
diff --git a/src/gui/toolpalette.cpp b/src/gui/toolpalette.cpp
index 0a832a6..0d0bd30 100644
--- a/src/gui/toolpalette.cpp
+++ b/src/gui/toolpalette.cpp
@@ -48,3 +48,21 @@ ToolPalette::Tool ToolPalette::currentTool() const
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 c28b5a1..1876043 100644
--- a/src/gui/toolpalette.h
+++ b/src/gui/toolpalette.h
@@ -23,6 +23,7 @@ public:
};
Tool currentTool() const;
+ void setCurrentTool(Tool tool);
private:
QActionGroup *tools;
QAction *select;
diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp
index 9c6a9c3..0ebfd21 100644
--- a/src/gui/undocommands.cpp
+++ b/src/gui/undocommands.cpp
@@ -4,12 +4,28 @@
#include <QGraphicsView>
+GraphUpdateCommand::GraphUpdateCommand(TikzScene *scene, QUndoCommand *parent) : QUndoCommand(parent), _scene(scene)
+{
+}
+
+void GraphUpdateCommand::undo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ _scene->invalidate();
+}
+
+void GraphUpdateCommand::redo()
+{
+ _scene->tikzDocument()->refreshTikz();
+ _scene->invalidate();
+}
+
+
MoveCommand::MoveCommand(TikzScene *scene,
QMap<Node*, QPointF> oldNodePositions,
QMap<Node*, QPointF> newNodePositions,
QUndoCommand *parent) :
- QUndoCommand(parent),
- _scene(scene),
+ GraphUpdateCommand(scene, parent),
_oldNodePositions(oldNodePositions),
_newNodePositions(newNodePositions)
{}
@@ -25,6 +41,7 @@ void MoveCommand::undo()
}
_scene->refreshAdjacentEdges(_oldNodePositions.keys());
+ GraphUpdateCommand::undo();
}
void MoveCommand::redo()
@@ -37,12 +54,14 @@ void MoveCommand::redo()
}
_scene->refreshAdjacentEdges(_newNodePositions.keys());
+ GraphUpdateCommand::redo();
}
EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge,
float oldWeight, int oldBend,
- int oldInAngle, int oldOutAngle) :
- _scene(scene), _edge(edge),
+ int oldInAngle, int oldOutAngle, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent),
+ _edge(edge),
_oldWeight(oldWeight), _oldBend(oldBend),
_oldInAngle(oldInAngle), _oldOutAngle(oldOutAngle)
{
@@ -65,6 +84,7 @@ void EdgeBendCommand::undo()
break;
}
}
+ GraphUpdateCommand::undo();
}
void EdgeBendCommand::redo()
@@ -80,20 +100,23 @@ void EdgeBendCommand::redo()
break;
}
}
+
+ GraphUpdateCommand::redo();
}
DeleteCommand::DeleteCommand(TikzScene *scene,
QMap<int, Node *> deleteNodes,
QMap<int, Edge *> deleteEdges,
- QSet<Edge *> selEdges) :
- _scene(scene), _deleteNodes(deleteNodes),
- _deleteEdges(deleteEdges), _selEdges(selEdges)
+ 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);
@@ -110,6 +133,8 @@ void DeleteCommand::undo()
if (_selEdges.contains(e)) ei->setSelected(true);
}
+
+ GraphUpdateCommand::undo();
}
void DeleteCommand::redo()
@@ -131,10 +156,12 @@ void DeleteCommand::redo()
_scene->graph()->removeNode(n);
}
+
+ GraphUpdateCommand::redo();
}
-AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds) :
- _scene(scene), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds)
+AddNodeCommand::AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _node(node), _oldBounds(_scene->sceneRect()), _newBounds(newBounds)
{
}
@@ -148,21 +175,24 @@ void AddNodeCommand::undo()
_scene->graph()->removeNode(_node);
_scene->setBounds(_oldBounds);
+
+ GraphUpdateCommand::undo();
}
void AddNodeCommand::redo()
{
- // TODO: get the current style
+ _node->attachStyle(); // 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) :
- _scene(scene), _edge(edge)
+AddEdgeCommand::AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
{
}
@@ -174,6 +204,7 @@ void AddEdgeCommand::undo()
delete ei;
_scene->graph()->removeEdge(_edge);
+ GraphUpdateCommand::undo();
}
void AddEdgeCommand::redo()
@@ -188,10 +219,12 @@ void AddEdgeCommand::redo()
if (!_scene->graph()->nodes().isEmpty()) {
ei->stackBefore(_scene->nodeItems()[_scene->graph()->nodes().first()]);
}
+
+ GraphUpdateCommand::redo();
}
-ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge) :
- _scene(scene), _edge(edge)
+ChangeEdgeModeCommand::ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _edge(edge)
{
}
@@ -199,10 +232,96 @@ void ChangeEdgeModeCommand::undo()
{
_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();
+}
+
+PasteCommand::PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent) :
+ GraphUpdateCommand(scene, parent), _graph(graph)
+{
+ _oldSelection = scene->selectedItems();
+}
+
+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 (auto it, _oldSelection) it->setSelected(true);
+
+ GraphUpdateCommand::undo();
+}
+
+void PasteCommand::redo()
+{
+ _scene->clearSelection();
+ _scene->graph()->insertGraph(_graph);
+
+ 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);
+ }
+
+ foreach (Edge *e, _graph->edges()) {
+ EdgeItem *ei = new EdgeItem(e);
+ _scene->edgeItems().insert(e, ei);
+ _scene->addItem(ei);
+ }
+
+ GraphUpdateCommand::redo();
}
diff --git a/src/gui/undocommands.h b/src/gui/undocommands.h
index eea39ae..354e455 100644
--- a/src/gui/undocommands.h
+++ b/src/gui/undocommands.h
@@ -14,7 +14,17 @@
#include <QUndoCommand>
-class MoveCommand : public QUndoCommand
+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,
@@ -24,21 +34,20 @@ public:
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
QMap<Node*,QPointF> _oldNodePositions;
QMap<Node*,QPointF> _newNodePositions;
};
-class EdgeBendCommand : public QUndoCommand
+class EdgeBendCommand : public GraphUpdateCommand
{
public:
explicit EdgeBendCommand(TikzScene *scene, Edge *edge,
float oldWeight, int oldBend,
- int oldInAngle, int oldOutAngle);
+ int oldInAngle, int oldOutAngle,
+ QUndoCommand *parent = 0);
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
Edge *_edge;
float _oldWeight;
int _oldBend;
@@ -50,55 +59,75 @@ private:
int _newOutAngle;
};
-class DeleteCommand : public QUndoCommand
+class DeleteCommand : public GraphUpdateCommand
{
public:
explicit DeleteCommand(TikzScene *scene,
QMap<int,Node*> deleteNodes,
QMap<int,Edge*> deleteEdges,
- QSet<Edge*> selEdges);
+ QSet<Edge*> selEdges,
+ QUndoCommand *parent = 0);
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
QMap<int,Node*> _deleteNodes;
QMap<int,Edge*> _deleteEdges;
QSet<Edge*> _selEdges;
};
-class AddNodeCommand : public QUndoCommand
+class AddNodeCommand : public GraphUpdateCommand
{
public:
- explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds);
+ explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds,
+ QUndoCommand *parent = 0);
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
Node *_node;
QRectF _oldBounds;
QRectF _newBounds;
};
-class AddEdgeCommand : public QUndoCommand
+class AddEdgeCommand : public GraphUpdateCommand
{
public:
- explicit AddEdgeCommand(TikzScene *scene, Edge *edge);
+ explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
Edge *_edge;
};
-class ChangeEdgeModeCommand : public QUndoCommand
+class ChangeEdgeModeCommand : public GraphUpdateCommand
{
public:
- explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge);
+ explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0);
void undo() override;
void redo() override;
private:
- TikzScene *_scene;
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 PasteCommand : public GraphUpdateCommand
+{
+public:
+ explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0);
+ void undo() override;
+ void redo() override;
+private:
+ Graph *_graph;
+ QList<QGraphicsItem*> _oldSelection;
+};
+
#endif // UNDOCOMMANDS_H