From ebbd74147dfae75e503ea83e9dbd51d0a3d55629 Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Thu, 7 Jul 2011 13:45:38 +0200 Subject: [PATCH] got rig of throwing exceptions, and friend classes: undoCommands get contexts --- include/commands.h | 92 +++++++------- include/edge.h | 1 + include/graphlogic.h | 17 ++- src/commands.cpp | 290 ++++++++++++++++--------------------------- src/edge.cpp | 6 + src/graphlogic.cpp | 125 +++++++++++++++---- src/graphwidget.cpp | 2 - src/mainwindow.cpp | 2 + src/node.cpp | 14 +-- 9 files changed, 276 insertions(+), 273 deletions(-) diff --git a/include/commands.h b/include/commands.h index b9c5d95..413773f 100644 --- a/include/commands.h +++ b/include/commands.h @@ -9,63 +9,57 @@ class GraphLogic; -// exceptions: - -class NoActiveNodeException : public std::exception -{ -public: - const char* what() const throw(); -}; - -class CannotPlaceNewNodeException : public std::exception +struct UndoContext { -public: - const char* what() const throw(); -}; - -class CannotDeleteBaseNodeException : public std::exception -{ -public: - const char* what() const throw(); -}; - -class BaseNodeCannotBeEdgeTargetException : public std::exception -{ -public: - const char* what() const throw(); -}; - -class EdgeExistsBetweenNodesException : public std::exception -{ -public: - const char* what() const throw(); -}; + GraphLogic *m_graphLogic; + Node *m_activeNode; + Node *m_hintNode; + QList *m_nodeList; -class EdgeDoesntExistsBetweenNodesException : public std::exception -{ -public: - const char* what() const throw(); + QPointF m_pos; + QColor m_color; + Node *m_source; + Node *m_destination; + bool m_secondary; + + UndoContext(GraphLogic *graphLogic = 0, + Node *activeNode = 0, + Node *hintNode = 0, + QList *nodeList = 0, + QPointF pos = QPointF(), + QColor color = QColor(), + Node *source = 0, + Node *destination = 0, + bool secondary = false) + : m_graphLogic(graphLogic) + , m_activeNode(activeNode) + , m_hintNode(hintNode) + , m_nodeList(nodeList) + , m_pos(pos) + , m_color(color) + , m_source(source) + , m_destination(destination) + , m_secondary(secondary) {}; }; -// commands: - class InsertNodeCommand : public QUndoCommand { public: - InsertNodeCommand(GraphLogic *graphLogic); + InsertNodeCommand(UndoContext context); + ~InsertNodeCommand(); void undo(); void redo(); private: - GraphLogic *m_graphLogic; + bool m_done; + UndoContext m_context; Node *m_node; - QPointF m_pos; Node *m_activeNode; Edge *m_edge; }; @@ -75,14 +69,15 @@ class RemoveNodeCommand : public QUndoCommand public: - RemoveNodeCommand(GraphLogic *graphLogic); + RemoveNodeCommand(UndoContext context); void undo(); void redo(); private: - GraphLogic *m_graphLogic; + bool m_done; + UndoContext m_context; Node *m_activeNode; Node *m_hintNode; @@ -96,18 +91,18 @@ class AddEdgeCommand : public QUndoCommand public: - AddEdgeCommand(GraphLogic *graphLogic, Node *source, Node *destinaion); + AddEdgeCommand(UndoContext context); + ~AddEdgeCommand(); void undo(); void redo(); private: - GraphLogic *m_graphLogic; + bool m_done; + UndoContext m_context; Node *m_activeNode; - Node *m_source; - Node *m_destination; Edge *m_edge; }; @@ -116,18 +111,17 @@ class RemoveEdgeCommand : public QUndoCommand public: - RemoveEdgeCommand(GraphLogic *graphLogic, Node *source, Node *destinaion); + RemoveEdgeCommand(UndoContext context); void undo(); void redo(); private: - GraphLogic *m_graphLogic; + bool m_done; + UndoContext m_context; Node *m_activeNode; - Node *m_source; - Node *m_destination; Edge *m_edge; }; diff --git a/include/edge.h b/include/edge.h index 84cb77d..1bda57f 100644 --- a/include/edge.h +++ b/include/edge.h @@ -11,6 +11,7 @@ class Edge : public QGraphicsItem public: Edge(Node *sourceNode, Node *destNode); + ~Edge(); Node *sourceNode() const; Node *destNode() const; diff --git a/include/graphlogic.h b/include/graphlogic.h index 5acd7d8..a19b672 100644 --- a/include/graphlogic.h +++ b/include/graphlogic.h @@ -23,6 +23,8 @@ class GraphLogic : public QObject public: explicit GraphLogic(GraphWidget *parent = 0); + + GraphWidget *graphWidget() const; void setUndoStack(QUndoStack *stack); bool processKeyEvent(QKeyEvent *event); @@ -33,6 +35,11 @@ public: void writeContentToXmlFile(const QString &fileName); void writeContentToPngFile(const QString &fileName); + Node *nodeFactory(); + void setActiveNode(Node *node); + void setHintNode(Node *node); + void reShowNumbers(); + public slots: // commands from toolbars: @@ -74,9 +81,7 @@ private: void delNumber(); void applyNumber(); - Node *nodeFactory(); void selectNode(Node *node); - void setActiveNode(Node *node); // functions on the edges QList allEdges() const; @@ -104,10 +109,10 @@ private: QUndoStack *m_undoStack; - friend class InsertNodeCommand; - friend class RemoveNodeCommand; - friend class AddEdgeCommand; - friend class RemoveEdgeCommand; +// friend class InsertNodeCommand; +// friend class RemoveNodeCommand; +// friend class AddEdgeCommand; +// friend class RemoveEdgeCommand; }; #endif // GRAPHLOGIC_H diff --git a/src/commands.cpp b/src/commands.cpp index c1824a5..197bdc6 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -6,136 +6,83 @@ #include - -const char* NoActiveNodeException::what() const throw() -{ - return QObject::tr("No active node.").toStdString().c_str(); -} - -const char* CannotPlaceNewNodeException::what() const throw() -{ - return QObject::tr("New node would be placed outside of the scene."). - toStdString().c_str(); -} - -const char* CannotDeleteBaseNodeException::what() const throw() -{ - return QObject::tr("Base node cannot be deleted.").toStdString().c_str(); -} - -const char* BaseNodeCannotBeEdgeTargetException::what() const throw() -{ - return QObject::tr("Base node cannot be a target.").toStdString().c_str(); -} - -const char* EdgeExistsBetweenNodesException::what() const throw() +InsertNodeCommand::InsertNodeCommand(UndoContext context) + : m_done(false) + , m_context(context) + , m_activeNode(context.m_activeNode) { - return QObject::tr("There is already an edge between these two nodes."). - toStdString().c_str(); -} - -const char* EdgeDoesntExistsBetweenNodesException::what() const throw() -{ - return QObject::tr("There is no edge between these two nodes."). - toStdString().c_str(); -} - - -InsertNodeCommand::InsertNodeCommand(GraphLogic *graphLogic) - : m_graphLogic(graphLogic) - , m_node(0) - , m_activeNode(m_graphLogic->m_activeNode) - , m_edge(0) -{ - if (!m_activeNode) - throw NoActiveNodeException(); - - setText(QObject::tr("Node added to ").append( - m_activeNode == m_graphLogic->m_nodeList.first() ? + setText(QObject::tr("Node added to \"").append( + m_activeNode == m_context.m_nodeList->first() ? QObject::tr("Base node") : - QString("\"").append(m_activeNode->toPlainText().append("\"")))); - - m_graphLogic->nodeLostFocus(); - - // get the biggest angle between the edges of the Node. - double angle(m_activeNode->calculateBiggestAngle()); + m_activeNode->toPlainText()).append("\"")); - // let the distance between the current and new Node be 100 pixels - qreal length(100); - m_pos = m_activeNode->sceneBoundingRect().center() + - QPointF(length * cos(angle), length * sin(angle)) - - Node::newNodeCenter; + m_context.m_graphLogic->nodeLostFocus(); - QRectF rect (m_graphLogic->m_graphWidget->scene()->sceneRect().topLeft(), - m_graphLogic->m_graphWidget->scene()->sceneRect().bottomRight() - - Node::newNodeBottomRigth); - - if (!rect.contains(m_pos)) - throw CannotPlaceNewNodeException(); - - // add a new node which inherits the color and textColor - m_node = m_graphLogic->nodeFactory(); + // create new node which inherits the color and textColor + m_node = m_context.m_graphLogic->nodeFactory(); m_node->setColor(m_activeNode->color()); m_node->setTextColor(m_activeNode->textColor()); m_node->setHtml(QString("")); + // new edge inherits colors and size from target m_edge = new Edge(m_activeNode, m_node); m_edge->setColor(m_node->color()); m_edge->setWidth(m_node->scale()*2 + 1); m_edge->setSecondary(false); } +InsertNodeCommand::~InsertNodeCommand() +{ + if (!m_done) + { + delete m_edge; + delete m_node; + } +} + void InsertNodeCommand::undo() { - m_graphLogic->m_nodeList.removeAll(m_node); - m_graphLogic->m_graphWidget->scene()->removeItem(m_node); + // remove node + m_context.m_nodeList->removeAll(m_node); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(m_node); + m_context.m_graphLogic->setActiveNode(m_activeNode); -// m_node->deleteEdges(); + // remove edge m_edge->sourceNode()->removeEdge(m_edge); m_edge->destNode()->removeEdge(m_edge); - m_graphLogic->m_graphWidget->scene()->removeItem(m_edge); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(m_edge); - m_graphLogic->setActiveNode(m_activeNode); - - emit m_graphLogic->contentChanged(false); + m_context.m_graphLogic->reShowNumbers(); + m_done = false; } void InsertNodeCommand::redo() { - m_graphLogic->m_graphWidget->scene()->addItem(m_node); - m_graphLogic->m_nodeList.append(m_node); + // add node + m_context.m_graphLogic->graphWidget()->scene()->addItem(m_node); + m_context.m_nodeList->append(m_node); + m_node->setPos(m_context.m_pos); + m_context.m_graphLogic->setActiveNode(m_node); - m_node->setPos(m_pos); + if (m_context.m_graphLogic->graphWidget()->hasFocus()) + m_context.m_graphLogic->nodeEdited(); + // add edge m_edge->sourceNode()->addEdge(m_edge,true); m_edge->destNode()->addEdge(m_edge,false); - m_graphLogic->m_graphWidget->scene()->addItem(m_edge); - - m_graphLogic->setActiveNode(m_node); - - if (m_graphLogic->m_graphWidget->hasFocus()) - m_graphLogic->nodeEdited(); + m_context.m_graphLogic->graphWidget()->scene()->addItem(m_edge); - emit m_graphLogic->contentChanged(); - - // it we are in hint mode, the numbers shall be re-calculated - if (m_graphLogic->m_showingNodeNumbers) - m_graphLogic->showNodeNumbers(); + m_context.m_graphLogic->reShowNumbers(); + m_done = true; } -RemoveNodeCommand::RemoveNodeCommand(GraphLogic *graphLogic) - : m_graphLogic(graphLogic) - , m_activeNode(m_graphLogic->m_activeNode) - , m_hintNode(m_graphLogic->m_hintNode) +RemoveNodeCommand::RemoveNodeCommand(UndoContext context) + : m_context(context) + , m_activeNode(context.m_activeNode) + , m_hintNode(context.m_hintNode) { - if (!m_activeNode) - throw NoActiveNodeException(); - - if (m_activeNode == m_graphLogic->m_nodeList.first()) - throw CannotDeleteBaseNodeException(); - - setText(QObject::tr("Node removed \"").append( + setText(QObject::tr("Node deleted \"").append( m_activeNode->toPlainText().append("\""))); // remove just the active Node or it's subtree too? @@ -150,6 +97,7 @@ RemoveNodeCommand::RemoveNodeCommand(GraphLogic *graphLogic) m_nodeList.push_back(m_activeNode); } + // collect affected edges foreach(Node *node, m_nodeList) foreach(Edge *edge, node->edges()) if (m_edgeList.indexOf(edge) == -1) @@ -158,149 +106,131 @@ RemoveNodeCommand::RemoveNodeCommand(GraphLogic *graphLogic) void RemoveNodeCommand::undo() { + // add nodes foreach (Node *node, m_nodeList) { - m_graphLogic->m_graphWidget->scene()->addItem(node); - m_graphLogic->m_nodeList.append(node); + m_context.m_graphLogic->graphWidget()->scene()->addItem(node); + m_context.m_nodeList->append(node); } + // add edges foreach (Edge *edge, m_edgeList) { edge->sourceNode()->addEdge(edge,true); edge->destNode()->addEdge(edge,false); - m_graphLogic->m_graphWidget->scene()->addItem(edge); + m_context.m_graphLogic->graphWidget()->scene()->addItem(edge); } - emit m_graphLogic->contentChanged(false); - m_graphLogic->m_activeNode = m_activeNode; - m_graphLogic->m_hintNode = m_hintNode; + m_context.m_graphLogic->setActiveNode(m_activeNode); + m_context.m_graphLogic->setHintNode(m_hintNode); - - // it we are in hint mode, the numbers shall be re-calculated - if (m_graphLogic->m_showingNodeNumbers) - m_graphLogic->showNodeNumbers(); + m_context.m_graphLogic->reShowNumbers(); } void RemoveNodeCommand::redo() { foreach(Node *node, m_nodeList) { - if (m_graphLogic->m_hintNode==node) - m_graphLogic->m_hintNode=0; + if (m_context.m_hintNode==node) + m_context.m_graphLogic->setHintNode(0); - m_graphLogic->m_nodeList.removeAll(node); - m_graphLogic->m_graphWidget->scene()->removeItem(node); + m_context.m_nodeList->removeAll(node); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(node); } foreach(Edge *edge, m_edgeList) { edge->sourceNode()->removeEdge(edge); edge->destNode()->removeEdge(edge); - m_graphLogic->m_graphWidget->scene()->removeItem(edge); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(edge); } - m_graphLogic->m_activeNode = 0; - - emit m_graphLogic->contentChanged(); + m_context.m_graphLogic->setActiveNode(0); - // it we are in hint mode, the numbers shall be re-calculated - if (m_graphLogic->m_showingNodeNumbers) - m_graphLogic->showNodeNumbers(); + m_context.m_graphLogic->reShowNumbers(); } -AddEdgeCommand::AddEdgeCommand(GraphLogic *graphLogic, Node *source, Node *destinaion) - : m_graphLogic(graphLogic) - , m_activeNode(m_graphLogic->m_activeNode) - , m_source(source) - , m_destination(destinaion) +AddEdgeCommand::AddEdgeCommand(UndoContext context) + : m_done(false) + , m_context(context) + , m_activeNode(context.m_activeNode) { - if (m_destination == m_graphLogic->m_nodeList.first()) - throw BaseNodeCannotBeEdgeTargetException(); - - - if (m_source->isConnected(m_destination)) - throw EdgeExistsBetweenNodesException(); - setText(QObject::tr("Edge added between \"").append( - m_source->toPlainText()).append( - QObject::tr("\" and \"").append( - m_destination->toPlainText()).append("\""))); - - - // aviod the graph beeing acyclic. (ok, Nodes having multiple parents) - bool sec(false); - if (!m_destination->edgesToThis().empty()) - { - emit m_graphLogic->notification( - QObject::tr("The graph is acyclic, edge added as secondary edge.")); - sec = true; - } + m_context.m_source == m_context.m_nodeList->first() ? + QObject::tr("Base node") : + m_context.m_source->toPlainText()).append( + QObject::tr("\" and \"").append( + m_context.m_destination == m_context.m_nodeList->first() ? + QObject::tr("Base node") : + m_context.m_destination->toPlainText()).append("\""))); - m_edge = new Edge(m_source, m_destination); - m_edge->setColor(m_destination->color()); - m_edge->setWidth(m_destination->scale()*2 + 1); + m_edge = new Edge(m_context.m_source, m_context.m_destination); + m_edge->setColor(m_context.m_destination->color()); + m_edge->setWidth(m_context.m_destination->scale()*2 + 1); // The Edge is secondary, because the Node already has a parent // (it is already a destination of another Edge) - m_edge->setSecondary(sec); + m_edge->setSecondary(m_context.m_secondary); } void AddEdgeCommand::undo() { - m_source->removeEdge(m_edge); - m_destination->removeEdge(m_edge); - m_graphLogic->m_graphWidget->scene()->removeItem(m_edge); - - m_graphLogic->setActiveNode(m_activeNode); + m_context.m_source->removeEdge(m_edge); + m_context.m_destination->removeEdge(m_edge); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(m_edge); - emit m_graphLogic->contentChanged(false); + m_context.m_graphLogic->setActiveNode(m_activeNode); + m_done = false; } void AddEdgeCommand::redo() { - m_source->addEdge(m_edge, true); - m_destination->addEdge(m_edge, false); + m_context.m_source->addEdge(m_edge, true); + m_context.m_destination->addEdge(m_edge, false); - m_graphLogic->m_graphWidget->scene()->addItem(m_edge); + m_context.m_graphLogic->graphWidget()->scene()->addItem(m_edge); - m_graphLogic->setActiveNode(m_destination); - emit m_graphLogic->contentChanged(); + m_context.m_graphLogic->setActiveNode(m_context.m_destination); + m_done = true; } -RemoveEdgeCommand::RemoveEdgeCommand(GraphLogic *graphLogic, Node *source, Node *destinaion) - : m_graphLogic(graphLogic) - , m_activeNode(m_graphLogic->m_activeNode) - , m_source(source) - , m_destination(destinaion) - , m_edge(source->edgeTo(destinaion)) +AddEdgeCommand::~AddEdgeCommand() { - if (!m_source->isConnected(m_destination)) - throw EdgeDoesntExistsBetweenNodesException(); + if (!m_done) + delete m_edge; +} - setText(QObject::tr("Edge releted between \"").append( - m_source->toPlainText()).append( +RemoveEdgeCommand::RemoveEdgeCommand(UndoContext context) + : m_context(context) + , m_activeNode(context.m_activeNode) +{ + setText(QObject::tr("Edge deleted between \"").append( + m_context.m_source == m_context.m_nodeList->first() ? + QObject::tr("Base node") : + m_context.m_source->toPlainText()).append( QObject::tr("\" and \"").append( - m_destination->toPlainText()).append("\""))); + m_context.m_destination == m_context.m_nodeList->first() ? + QObject::tr("Base node") : + m_context.m_destination->toPlainText()).append("\""))); + + m_edge = m_context.m_source->edgeTo(m_context.m_destination); } void RemoveEdgeCommand::undo() { - m_source->addEdge(m_edge, true); - m_destination->addEdge(m_edge, false); + m_context.m_source->addEdge(m_edge, true); + m_context.m_destination->addEdge(m_edge, false); - m_graphLogic->m_graphWidget->scene()->addItem(m_edge); + m_context.m_graphLogic->graphWidget()->scene()->addItem(m_edge); - m_graphLogic->setActiveNode(m_destination); - emit m_graphLogic->contentChanged(false); + m_context.m_graphLogic->setActiveNode(m_activeNode); } void RemoveEdgeCommand::redo() { - m_source->removeEdge(m_edge); - m_destination->removeEdge(m_edge); - m_graphLogic->m_graphWidget->scene()->removeItem(m_edge); - - m_graphLogic->setActiveNode(m_activeNode); + m_context.m_source->removeEdge(m_edge); + m_context.m_destination->removeEdge(m_edge); + m_context.m_graphLogic->graphWidget()->scene()->removeItem(m_edge); - emit m_graphLogic->contentChanged(); + m_context.m_graphLogic->setActiveNode(m_context.m_activeNode); } diff --git a/src/edge.cpp b/src/edge.cpp index f1cd73a..a226ea8 100644 --- a/src/edge.cpp +++ b/src/edge.cpp @@ -26,6 +26,12 @@ Edge::Edge(Node *sourceNode, Node *destNode) adjust(); } +Edge::~Edge() +{ + m_sourceNode->removeEdge(this); + m_destNode->removeEdge(this); +} + Node * Edge::sourceNode() const { return m_sourceNode; diff --git a/src/graphlogic.cpp b/src/graphlogic.cpp index 03f07f4..87fcc7d 100644 --- a/src/graphlogic.cpp +++ b/src/graphlogic.cpp @@ -52,8 +52,11 @@ GraphLogic::GraphLogic(GraphWidget *parent) (Qt::Key_Return, &GraphLogic::applyNumber)); m_memberMap.insert(std::pair (Qt::Key_Enter, &GraphLogic::applyNumber)); - m_memberMap.insert(std::pair - (Qt::Key_Delete, &GraphLogic::removeNode)); +} + +GraphWidget *GraphLogic::graphWidget() const +{ + return m_graphWidget; } void GraphLogic::setUndoStack(QUndoStack *stack) @@ -293,32 +296,79 @@ void GraphLogic::writeContentToPngFile(const QString &fileName) emit notification(tr("MindMap exported as ") + fileName); } +void GraphLogic::reShowNumbers() +{ + if (m_showingNodeNumbers) + showNodeNumbers(); +} + +void GraphLogic::setHintNode(Node *node) +{ + m_hintNode = node; +} + void GraphLogic::insertNode() { - try + // checks + if (!m_activeNode) { - QUndoCommand *insertNodeCommand = new InsertNodeCommand(this); - m_undoStack->push(insertNodeCommand); + emit notification(tr("No active node.")); + return; } - catch (std::exception &e) + + // get the biggest angle between the edges of the Node. + double angle(m_activeNode->calculateBiggestAngle()); + + // let the distance between the current and new Node be 100 pixels + qreal length(100); + + QPointF pos(m_activeNode->sceneBoundingRect().center() + + QPointF(length * cos(angle), length * sin(angle)) - + Node::newNodeCenter); + + QRectF rect (m_graphWidget->scene()->sceneRect().topLeft(), + m_graphWidget->scene()->sceneRect().bottomRight() + - Node::newNodeBottomRigth); + + if (!rect.contains(pos)) { - emit notification(e.what()); + emit notification(tr("New node would be placed outside of the scene.")); return; } + + UndoContext context; + context.m_graphLogic = this; + context.m_nodeList = &m_nodeList; + context.m_activeNode = m_activeNode; + context.m_pos = pos; + + + QUndoCommand *insertNodeCommand = new InsertNodeCommand(context); + m_undoStack->push(insertNodeCommand); } void GraphLogic::removeNode() { - try + if (!m_activeNode) { - QUndoCommand *removeNodeCommand = new RemoveNodeCommand(this); - m_undoStack->push(removeNodeCommand); + emit notification(tr("No active node.")); + return; } - catch (std::exception &e) + + if (m_activeNode == m_nodeList.first()) { - emit notification(e.what()); + emit notification(tr("Base node cannot be deleted.")); return; } + + UndoContext context; + context.m_graphLogic = this; + context.m_nodeList = &m_nodeList; + context.m_activeNode = m_activeNode; + context.m_hintNode = m_hintNode; + + QUndoCommand *insertNodeCommand = new RemoveNodeCommand(context); + m_undoStack->push(insertNodeCommand); } void GraphLogic::nodeEdited() @@ -700,30 +750,57 @@ QList GraphLogic::allEdges() const void GraphLogic::addEdge(Node *source, Node *destination) { - try + if (destination == m_nodeList.first()) { - QUndoCommand *addEdgeCommand = new AddEdgeCommand(this, source, destination); - m_undoStack->push(addEdgeCommand); + emit notification(tr("Base node cannot be a target.")); + return; } - catch (std::exception &e) + + if (source->isConnected(destination)) { - emit notification(e.what()); + emit notification(tr("There is already an edge between these two nodes.")); return; } + + // aviod the graph beeing acyclic. (ok, Nodes having multiple parents) + bool sec(false); + if (!destination->edgesToThis().empty()) + { + emit notification( + QObject::tr("The graph is acyclic, edge added as secondary edge.")); + sec = true; + } + + UndoContext context; + context.m_graphLogic = this; + context.m_nodeList = &m_nodeList; + context.m_activeNode = m_activeNode; + context.m_source = source; + context.m_destination = destination; + context.m_secondary = sec; + + QUndoCommand *addEdgeCommand = new AddEdgeCommand(context); + m_undoStack->push(addEdgeCommand); } void GraphLogic::removeEdge(Node *source, Node *destination) { - try + if (!source->isConnected(destination)) { - QUndoCommand *addEdgeCommand = new RemoveEdgeCommand(this, source, destination); - m_undoStack->push(addEdgeCommand); - } - catch (std::exception &e) - { - emit notification(e.what()); + emit notification(tr("There is no edge between these two nodes.")); return; } + + UndoContext context; + context.m_graphLogic = this; + context.m_nodeList = &m_nodeList; + context.m_activeNode = m_activeNode; + context.m_source = source; + context.m_destination = destination; + + QUndoCommand *removeEdgeCommand = new RemoveEdgeCommand(context); + m_undoStack->push(removeEdgeCommand); + } // re-draw numbers diff --git a/src/graphwidget.cpp b/src/graphwidget.cpp index 6dd8f57..27550d0 100644 --- a/src/graphwidget.cpp +++ b/src/graphwidget.cpp @@ -28,8 +28,6 @@ GraphWidget::GraphWidget(MainWindow *parent) m_graphlogic = new GraphLogic(this); } - - void GraphWidget::newScene() { m_graphlogic->removeAllNodes(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e3d930c..98ee137 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -156,6 +156,8 @@ void MainWindow::saveFile(const bool &checkIfReadonly) m_graphicsView->graphLogic()->writeContentToXmlFile(m_fileName); contentChanged(false); + + m_undoStack->clear(); } bool MainWindow::saveFileAs() diff --git a/src/node.cpp b/src/node.cpp index 404e0e1..cde24f4 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -54,10 +54,7 @@ void Node::deleteEdge(Node *otherEnd) || (it->edge->sourceNode() == this && it->edge->destNode() == otherEnd)) { - Edge *tmp = it->edge; - tmp->sourceNode()->removeEdge(tmp); - tmp->destNode()->removeEdge(tmp); - delete tmp; + delete it->edge; return; } } @@ -66,14 +63,7 @@ void Node::deleteEdge(Node *otherEnd) void Node::deleteEdges() { foreach (EdgeElement element, m_edgeList) - { - Edge *tmp = element.edge; - tmp->sourceNode()->removeEdge(tmp); - tmp->destNode()->removeEdge(tmp); - - /// @bug crashes sometimes - delete tmp; - } + delete element.edge; } void Node::removeEdge(Edge *edge)