diff options
author | Aleks Kissinger <aleks0@gmail.com> | 2019-01-19 18:13:51 +0100 |
---|---|---|
committer | Aleks Kissinger <aleks0@gmail.com> | 2019-01-19 18:13:51 +0100 |
commit | bd208d8b604dd7958152fdf4db188a0bd64146f5 (patch) | |
tree | 54e841b1dfab4a121364632067b461fd057747d5 /src/gui/tikzscene.cpp | |
parent | 15d97051f0b5105a2765fc068ae980e36195434c (diff) |
merge nodes
Diffstat (limited to 'src/gui/tikzscene.cpp')
-rw-r--r-- | src/gui/tikzscene.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp index 983cf18..4577981 100644 --- a/src/gui/tikzscene.cpp +++ b/src/gui/tikzscene.cpp @@ -186,6 +186,66 @@ void TikzScene::extendSelectionRight() } } +void TikzScene::mergeNodes() +{ + refreshZIndices(); + QSet<Node*> selNodes; + QSet<Edge*> selEdges; + getSelection(selNodes, selEdges); + + // build a map from locations to a chosen node at that location + QMap<QPair<int,int>,Node*> m; + foreach (Node *n, selNodes) { + // used fixed precision for hashing/comparing locations + QPair<int,int> fpPoint( + static_cast<int>(n->point().x() * 1000.0), + static_cast<int>(n->point().y() * 1000.0)); + if (!m.contains(fpPoint) || + _nodeItems[m[fpPoint]]->zValue() < _nodeItems[n]->zValue()) + { + m.insert(fpPoint, n); + } + } + + // build a second map from nodes to the node they will be merged with + QMap<Node*,Node*> m1; + foreach (Node *n, graph()->nodes()) { + QPair<int,int> fpPoint( + static_cast<int>(n->point().x() * 1000.0), + static_cast<int>(n->point().y() * 1000.0)); + Node *n1 = m[fpPoint]; + if (n1 != nullptr && n1 != n) m1.insert(n, n1); + } + + _tikzDocument->undoStack()->beginMacro("Merge nodes"); + + // copy adjacent edges from nodes that will be deleted + foreach (Edge *e, graph()->edges()) { + if (m1.contains(e->source()) || m1.contains(e->target())) { + Edge *e1 = e->copy(&m1); + AddEdgeCommand *cmd = new AddEdgeCommand(this, e1); + _tikzDocument->undoStack()->push(cmd); + } + } + + // delete nodes + QMap<int,Node*> delNodes; + QMap<int,Edge*> delEdges; + for (int i = 0; i < _tikzDocument->graph()->nodes().length(); ++i) { + Node *n = _tikzDocument->graph()->nodes()[i]; + if (m1.contains(n)) delNodes.insert(i, n); + } + for (int i = 0; i < _tikzDocument->graph()->edges().length(); ++i) { + Edge *e = _tikzDocument->graph()->edges()[i]; + if (m1.contains(e->source()) || m1.contains(e->target())) delEdges.insert(i, e); + } + DeleteCommand *cmd = new DeleteCommand(this, delNodes, delEdges, + selNodes, selEdges); + _tikzDocument->undoStack()->push(cmd); + + _tikzDocument->undoStack()->endMacro(); +} + void TikzScene::reorderSelection(bool toFront) { QVector<Node*> nodeOrd, nodeOrd1; @@ -911,7 +971,8 @@ void TikzScene::deleteSelectedItems() //qDebug() << "nodes:" << deleteNodes; //qDebug() << "edges:" << deleteEdges; - DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, selEdges); + DeleteCommand *cmd = new DeleteCommand(this, deleteNodes, deleteEdges, + selNodes, selEdges); _tikzDocument->undoStack()->push(cmd); } |