| 834 | } |
| 835 | |
| 836 | void RcxController::applyCommand(const Command& command, bool isUndo) { |
| 837 | auto& tree = m_doc->tree; |
| 838 | |
| 839 | std::visit([&](auto&& c) { |
| 840 | using T = std::decay_t<decltype(c)>; |
| 841 | if constexpr (std::is_same_v<T, cmd::ChangeKind>) { |
| 842 | int idx = tree.indexOfId(c.nodeId); |
| 843 | if (idx >= 0) |
| 844 | tree.nodes[idx].kind = isUndo ? c.oldKind : c.newKind; |
| 845 | for (const auto& adj : c.offAdjs) { |
| 846 | int ai = tree.indexOfId(adj.nodeId); |
| 847 | if (ai >= 0) |
| 848 | tree.nodes[ai].offset = isUndo ? adj.oldOffset : adj.newOffset; |
| 849 | } |
| 850 | } else if constexpr (std::is_same_v<T, cmd::Rename>) { |
| 851 | int idx = tree.indexOfId(c.nodeId); |
| 852 | if (idx >= 0) |
| 853 | tree.nodes[idx].name = isUndo ? c.oldName : c.newName; |
| 854 | } else if constexpr (std::is_same_v<T, cmd::Collapse>) { |
| 855 | int idx = tree.indexOfId(c.nodeId); |
| 856 | if (idx >= 0) |
| 857 | tree.nodes[idx].collapsed = isUndo ? c.oldState : c.newState; |
| 858 | } else if constexpr (std::is_same_v<T, cmd::Insert>) { |
| 859 | if (isUndo) { |
| 860 | // Revert offset adjustments |
| 861 | for (const auto& adj : c.offAdjs) { |
| 862 | int ai = tree.indexOfId(adj.nodeId); |
| 863 | if (ai >= 0) tree.nodes[ai].offset = adj.oldOffset; |
| 864 | } |
| 865 | int idx = tree.indexOfId(c.node.id); |
| 866 | if (idx >= 0) { |
| 867 | tree.nodes.remove(idx); |
| 868 | tree.invalidateIdCache(); |
| 869 | } |
| 870 | } else { |
| 871 | tree.addNode(c.node); |
| 872 | // Apply offset adjustments |
| 873 | for (const auto& adj : c.offAdjs) { |
| 874 | int ai = tree.indexOfId(adj.nodeId); |
| 875 | if (ai >= 0) tree.nodes[ai].offset = adj.newOffset; |
| 876 | } |
| 877 | } |
| 878 | } else if constexpr (std::is_same_v<T, cmd::Remove>) { |
| 879 | if (isUndo) { |
| 880 | // Restore nodes first |
| 881 | for (const Node& n : c.subtree) |
| 882 | tree.addNode(n); |
| 883 | // Revert offset adjustments |
| 884 | for (const auto& adj : c.offAdjs) { |
| 885 | int ai = tree.indexOfId(adj.nodeId); |
| 886 | if (ai >= 0) tree.nodes[ai].offset = adj.oldOffset; |
| 887 | } |
| 888 | } else { |
| 889 | // Apply offset adjustments first (before removing changes indices) |
| 890 | for (const auto& adj : c.offAdjs) { |
| 891 | int ai = tree.indexOfId(adj.nodeId); |
| 892 | if (ai >= 0) tree.nodes[ai].offset = adj.newOffset; |
| 893 | } |
no test coverage detected