| 1003 | } |
| 1004 | |
| 1005 | void RcxController::duplicateNode(int nodeIdx) { |
| 1006 | if (nodeIdx < 0 || nodeIdx >= m_doc->tree.nodes.size()) return; |
| 1007 | const Node& src = m_doc->tree.nodes[nodeIdx]; |
| 1008 | if (src.kind == NodeKind::Struct || src.kind == NodeKind::Array) return; |
| 1009 | |
| 1010 | int copySize = src.byteSize(); |
| 1011 | int copyOffset = src.offset + copySize; |
| 1012 | |
| 1013 | // Shift later siblings down to make room for the copy |
| 1014 | QVector<cmd::OffsetAdj> adjs; |
| 1015 | if (src.parentId != 0) { |
| 1016 | auto siblings = m_doc->tree.childrenOf(src.parentId); |
| 1017 | for (int si : siblings) { |
| 1018 | if (si == nodeIdx) continue; |
| 1019 | auto& sib = m_doc->tree.nodes[si]; |
| 1020 | if (sib.offset >= copyOffset) |
| 1021 | adjs.append({sib.id, sib.offset, sib.offset + copySize}); |
| 1022 | } |
| 1023 | } |
| 1024 | |
| 1025 | Node n; |
| 1026 | n.kind = src.kind; |
| 1027 | n.name = src.name + "_copy"; |
| 1028 | n.parentId = src.parentId; |
| 1029 | n.offset = copyOffset; |
| 1030 | n.id = m_doc->tree.reserveId(); |
| 1031 | |
| 1032 | m_doc->undoStack.push(new RcxCommand(this, cmd::Insert{n, adjs})); |
| 1033 | } |
| 1034 | |
| 1035 | void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, |
| 1036 | int subLine, const QPoint& globalPos) { |