From e6529052b36addddb5d66828865b8a6b11b88962 Mon Sep 17 00:00:00 2001 From: IChooseYou Date: Mon, 2 Mar 2026 15:34:37 -0700 Subject: [PATCH] fix: clear value history clears subtree, add Copy Line and Search to context menu - Clear Value History now removes history for all descendant nodes too - Add "Copy Line" right-click menu item - Add "Search..." right-click menu item (opens Ctrl+F find bar) - Move showFindBar() to public in editor.h --- src/controller.cpp | 28 ++++++++++++++++++++++++---- src/editor.h | 2 +- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 087f82a..4c36567 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1637,9 +1637,11 @@ void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, connect(act, &QAction::triggered, this, [this, ids]() { for (uint64_t id : ids) { m_valueHistory.remove(id); - for (auto& lm : m_lastResult.meta) - if (lm.nodeId == id) lm.heatLevel = 0; + for (int ci : m_doc->tree.subtreeIndices(id)) + m_valueHistory.remove(m_doc->tree.nodes[ci].id); } + for (auto& lm : m_lastResult.meta) + if (!m_valueHistory.contains(lm.nodeId)) lm.heatLevel = 0; refresh(); }); } @@ -1833,11 +1835,12 @@ void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, { auto* act = menu.addAction("Clear Value History"); act->setToolTip(QStringLiteral("Reset change tracking for this node")); - act->setEnabled(m_valueHistory.contains(nodeId) && m_valueHistory[nodeId].uniqueCount() > 0); connect(act, &QAction::triggered, this, [this, nodeId]() { m_valueHistory.remove(nodeId); + for (int ci : m_doc->tree.subtreeIndices(nodeId)) + m_valueHistory.remove(m_doc->tree.nodes[ci].id); for (auto& lm : m_lastResult.meta) - if (lm.nodeId == nodeId) lm.heatLevel = 0; + if (!m_valueHistory.contains(lm.nodeId)) lm.heatLevel = 0; refresh(); }); } @@ -2091,6 +2094,23 @@ void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, menu.addAction(icon("clippy.svg"), "Copy All as Text", [editor]() { QApplication::clipboard()->setText(editor->textWithMargins()); }); + menu.addAction(icon("clippy.svg"), "Copy Line", [editor, line]() { + auto* sci = editor->scintilla(); + int len = (int)sci->SendScintilla(QsciScintillaBase::SCI_LINELENGTH, (unsigned long)line); + if (len > 0) { + QByteArray buf(len + 1, '\0'); + sci->SendScintilla(QsciScintillaBase::SCI_GETLINE, (unsigned long)line, (void*)buf.data()); + QString text = QString::fromUtf8(buf.data(), len).trimmed(); + if (!text.isEmpty()) + QApplication::clipboard()->setText(text); + } + }); + + menu.addSeparator(); + + menu.addAction(icon("search.svg"), "Search...", [editor]() { + editor->showFindBar(); + }); menu.exec(globalPos); } diff --git a/src/editor.h b/src/editor.h index 36a750a..5392e5e 100644 --- a/src/editor.h +++ b/src/editor.h @@ -33,6 +33,7 @@ public: const LineMeta* metaForLine(int line) const; int currentNodeIndex() const; void scrollToNodeId(uint64_t nodeId); + void showFindBar(); // ── Column span computation ── static ColumnSpan typeSpan(const LineMeta& lm, int typeW = kColType); @@ -159,7 +160,6 @@ private: QWidget* m_findBarContainer = nullptr; QLineEdit* m_findBar = nullptr; long m_findPos = 0; - void showFindBar(); void hideFindBar(); // ── Reentrancy guards ──