Skip to content

Commit

Permalink
Fix GitHub Issue #25: Add a way to delete edges
Browse files Browse the repository at this point in the history
- Right-click on edge opens context menu with a delete option
  • Loading branch information
juzzlin committed Mar 19, 2019
1 parent 05a2d7c commit 45bd995
Show file tree
Hide file tree
Showing 16 changed files with 233 additions and 9 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
x.y.z
=====

New features:

* Fix GitHub Issue #25: Add a way to delete edges
* Right-click on edge opens context menu with a delete option

1.8.0 - "Mighty Move"
=====================

Expand Down
Binary file modified data/translations/heimer_fi.qm
Binary file not shown.
2 changes: 2 additions & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ static const int MAX_SIZE = 24;

namespace View {

static const int CLICK_TOLERANCE = 5;

static const double DRAG_NODE_OPACITY = 0.5;

static const int ZOOM_MAX = 200;
Expand Down
30 changes: 30 additions & 0 deletions src/editor_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ void EditorData::loadMindMapData(QString fileName)
{
clearSelectionGroup();

m_selectedEdge = nullptr;

m_selectedNode = nullptr;

#ifndef HEIMER_UNIT_TEST
Expand Down Expand Up @@ -82,6 +84,8 @@ void EditorData::undo()
{
clearSelectionGroup();

m_selectedEdge = nullptr;

m_selectedNode = nullptr;

m_dragAndDropNode = nullptr;
Expand All @@ -105,6 +109,8 @@ void EditorData::redo()
{
if (m_undoStack.isRedoable())
{
m_selectedEdge = nullptr;

m_selectedNode = nullptr;

m_dragAndDropNode = nullptr;
Expand Down Expand Up @@ -190,6 +196,20 @@ EdgePtr EditorData::addEdge(EdgePtr edge)
return edge;
}

void EditorData::deleteEdge(Edge & edge)
{
assert(m_mindMapData);

m_mindMapData->graph().deleteEdge(edge.sourceNode().index(), edge.targetNode().index());
}

void EditorData::deleteNode(Node & node)
{
assert(m_mindMapData);

m_mindMapData->graph().deleteNode(node.index());
}

NodePtr EditorData::addNodeAt(QPointF pos)
{
assert(m_mindMapData);
Expand Down Expand Up @@ -243,11 +263,21 @@ void EditorData::moveSelectionGroup(Node & reference, QPointF location)
}
}

void EditorData::setSelectedEdge(Edge * edge)
{
m_selectedEdge = edge;
}

void EditorData::setSelectedNode(Node * node)
{
m_selectedNode = node;
}

Edge * EditorData::selectedEdge() const
{
return m_selectedEdge;
}

Node * EditorData::selectedNode() const
{
return m_selectedNode;
Expand Down
10 changes: 10 additions & 0 deletions src/editor_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class EditorData : public QObject

EdgePtr addEdge(EdgePtr edge);

void deleteEdge(Edge & edge);

void deleteNode(Node & node);

NodePtr addNodeAt(QPointF pos);

void clearSelectionGroup();
Expand Down Expand Up @@ -82,8 +86,12 @@ class EditorData : public QObject

void setMindMapData(MindMapDataPtr newMindMapData);

void setSelectedEdge(Edge * edge);

void setSelectedNode(Node * node);

Edge * selectedEdge() const;

Node * selectedNode() const;

size_t selectionGroupSize() const;
Expand Down Expand Up @@ -117,6 +125,8 @@ class EditorData : public QObject

UndoStack m_undoStack;

Edge * m_selectedEdge = nullptr;

Node * m_selectedNode = nullptr;

std::set<Node *> m_selectionGroup;
Expand Down
44 changes: 42 additions & 2 deletions src/editor_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ EditorView::EditorView(Mediator & mediator)
: m_mediator(mediator)
{
createBackgroundContextMenuActions();
createEdgeContextMenuActions();
createNodeContextMenuActions();

setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
Expand Down Expand Up @@ -83,6 +84,19 @@ void EditorView::createBackgroundContextMenuActions()
m_backgroundContextMenu.addAction(createNode);
}

void EditorView::createEdgeContextMenuActions()
{
m_deleteEdgeAction = new QAction(tr("Delete edge"), &m_edgeContextMenu);
QObject::connect(m_deleteEdgeAction, &QAction::triggered, [=] {
assert(m_mediator.selectedEdge());
m_mediator.saveUndoPoint();
m_mediator.deleteEdge(*m_mediator.selectedEdge());
});

// Populate the menu
m_edgeContextMenu.addAction(m_deleteEdgeAction);
}

void EditorView::createNodeContextMenuActions()
{
m_setNodeColorAction = new QAction(tr("Set node color"), &m_nodeContextMenu);
Expand Down Expand Up @@ -139,6 +153,14 @@ void EditorView::handleMousePressEventOnBackground(QMouseEvent & event)
}
}

void EditorView::handleMousePressEventOnEdge(QMouseEvent & event, Edge & edge)
{
if (event.button() == Qt::RightButton)
{
handleRightButtonClickOnEdge(edge);
}
}

void EditorView::handleMousePressEventOnNode(QMouseEvent & event, Node & node)
{
if (node.index() != -1) // Prevent right-click on the drag node
Expand Down Expand Up @@ -209,6 +231,13 @@ void EditorView::handleLeftButtonClickOnNodeHandle(NodeHandle & nodeHandle)
}
}

void EditorView::handleRightButtonClickOnEdge(Edge & edge)
{
m_mediator.setSelectedEdge(&edge);

openEdgeContextMenu();
}

void EditorView::handleRightButtonClickOnNode(Node & node)
{
m_mediator.setSelectedNode(&node);
Expand Down Expand Up @@ -287,9 +316,11 @@ void EditorView::mousePressEvent(QMouseEvent * event)
m_clickedPos = event->pos();
m_clickedScenePos = mapToScene(m_clickedPos);

const int tolerance = Constants::View::CLICK_TOLERANCE;
QRectF clickRect(m_clickedScenePos.x() - tolerance, m_clickedScenePos.y() - tolerance, tolerance * 2, tolerance * 2);

// Fetch all items at the location
QList<QGraphicsItem *> items = scene()->items(
m_clickedScenePos, Qt::IntersectsItemShape, Qt::DescendingOrder);
QList<QGraphicsItem *> items = scene()->items(clickRect, Qt::IntersectsItemShape, Qt::DescendingOrder);

if (items.size())
{
Expand All @@ -298,6 +329,10 @@ void EditorView::mousePressEvent(QMouseEvent * event)
{
handleMousePressEventOnNode(*event, *node);
}
else if (auto edge = dynamic_cast<Edge *>(item))
{
handleMousePressEventOnEdge(*event, *edge);
}
else if (auto node = dynamic_cast<NodeHandle *>(item))
{
handleMousePressEventOnNodeHandle(*event, *node);
Expand Down Expand Up @@ -356,6 +391,11 @@ void EditorView::openBackgroundContextMenu()
m_backgroundContextMenu.exec(mapToGlobal(m_clickedPos));
}

void EditorView::openEdgeContextMenu()
{
m_edgeContextMenu.exec(mapToGlobal(m_clickedPos));
}

void EditorView::openNodeContextMenu()
{
// Allow deletion of leaf nodes or nodes between exactly two nodes.
Expand Down
12 changes: 12 additions & 0 deletions src/editor_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,14 @@ public slots:

void createBackgroundContextMenuActions();

void createEdgeContextMenuActions();

void createNodeContextMenuActions();

void handleMousePressEventOnBackground(QMouseEvent & event);

void handleMousePressEventOnEdge(QMouseEvent & event, Edge & edge);

void handleMousePressEventOnNode(QMouseEvent & event, Node & node);

void handleMousePressEventOnNodeHandle(QMouseEvent & event, NodeHandle & nodeHandle);
Expand All @@ -93,6 +97,8 @@ public slots:

void handleLeftButtonClickOnNodeHandle(NodeHandle & nodeHandle);

void handleRightButtonClickOnEdge(Edge & edge);

void handleRightButtonClickOnNode(Node & node);

void initiateNewNodeDrag(NodeHandle & nodeHandle);
Expand All @@ -101,6 +107,8 @@ public slots:

void openBackgroundContextMenu();

void openEdgeContextMenu();

void openNodeContextMenu();

void removeNodeFromSelectionGroup(Node & node);
Expand All @@ -115,6 +123,8 @@ public slots:

QMenu m_backgroundContextMenu;

QMenu m_edgeContextMenu;

QMenu m_nodeContextMenu;

QPoint m_clickedPos;
Expand All @@ -131,6 +141,8 @@ public slots:

QAction * m_setNodeTextColorAction = nullptr;

QAction * m_deleteEdgeAction = nullptr;

QAction * m_deleteNodeAction = nullptr;

QAction * m_deleteRow = nullptr;
Expand Down
18 changes: 18 additions & 0 deletions src/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ void Graph::addNode(NodeBasePtr node)
m_nodes.push_back(node);
}

void Graph::deleteEdge(int index0, int index1)
{
EdgeVector::iterator edgeIter;
bool edgeErased = false;
do
{
edgeIter = std::find_if(
m_edges.begin(), m_edges.end(), [=] (const EdgeBasePtr & edge){
return edge->sourceNodeBase().index() == index0 && edge->targetNodeBase().index() == index1;
});
edgeErased = edgeIter != m_edges.end();
if (edgeErased)
{
m_edges.erase(edgeIter);
}
} while (edgeErased);
}

void Graph::deleteNode(int index)
{
const auto iter = std::find_if(m_nodes.begin(), m_nodes.end(), [=] (const NodeBasePtr & node) {
Expand Down
2 changes: 2 additions & 0 deletions src/graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class Graph

void addEdge(EdgeBasePtr edge);

void deleteEdge(int index0, int index1);

bool areDirectlyConnected(NodeBasePtr node0, NodeBasePtr node1);

//! Warning: this should not be used outside unit tests as it creates a pure EdgeBase
Expand Down
17 changes: 16 additions & 1 deletion src/mediator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,15 @@ DragAndDropStore & Mediator::dadStore()
return m_editorData->dadStore();
}

void Mediator::deleteEdge(Edge & edge)
{
m_editorData->deleteEdge(edge);
}

void Mediator::deleteNode(Node & node)
{
m_editorView->resetDummyDragItems();
m_editorData->mindMapData()->graph().deleteNode(node.index());
m_editorData->deleteNode(node);
}

void Mediator::enableUndo(bool enable)
Expand Down Expand Up @@ -359,6 +364,11 @@ QSize Mediator::sceneRectSize() const
return m_editorScene->sceneRect().size().toSize();
}

Edge * Mediator::selectedEdge() const
{
return m_editorData->selectedEdge();
}

Node * Mediator::selectedNode() const
{
return m_editorData->selectedNode();
Expand Down Expand Up @@ -425,6 +435,11 @@ void Mediator::setEditorView(EditorView & editorView)
});
}

void Mediator::setSelectedEdge(Edge * edge)
{
m_editorData->setSelectedEdge(edge);
}

void Mediator::setSelectedNode(Node * node)
{
m_editorData->setSelectedNode(node);
Expand Down
6 changes: 6 additions & 0 deletions src/mediator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Mediator : public QObject

DragAndDropStore & dadStore();

void deleteEdge(Edge & edge);

void deleteNode(Node & node);

QString fileName() const;
Expand Down Expand Up @@ -108,6 +110,8 @@ class Mediator : public QObject

QSize sceneRectSize() const;

Edge * selectedEdge() const;

Node * selectedNode() const;

size_t selectionGroupSize() const;
Expand All @@ -118,6 +122,8 @@ class Mediator : public QObject

void setEditorView(EditorView & editorView);

void setSelectedEdge(Edge * edge);

void setSelectedNode(Node * node);

void setupMindMapAfterUndoOrRedo();
Expand Down
Loading

0 comments on commit 45bd995

Please sign in to comment.