UI: a reference box stops picking when a macro action starts, and debugging never fills one

A reference box that had focus kept picking from the grid while Check, Run or a debugger action
ran. The selections those make landed in the box and dirtied the draft, and a later Check could
save that draft. The pick now ends when an action starts, and while a debug run is active a
selection on the grid is never taken as a pick.

Also: the parity assessment said an .xlsm's VBA project is dropped on open; it is kept unchanged
on save and never run.
This commit is contained in:
prxnvt
2026-10-25 06:48:57 -04:00
parent b9a8fa304c
commit 3d6a09ec75
3 changed files with 42 additions and 3 deletions
+7 -2
View File
@@ -563,6 +563,8 @@ fn error_step(msg: &str) -> Option<(String, String)> {
/// Check: validates the inputs and dry-runs the macro; the grid shows what it would touch.
pub fn check(app: &mut SheetApp, ed: &mut Editor) {
// A reference box picking from the grid would take the selections the action makes.
ed.refs.pick = None;
if !ensure_saved(app, ed) {
return;
}
@@ -613,6 +615,7 @@ fn check_text(v: &Json) -> String {
/// Run: runs the saved macro as one undo step.
pub fn run(app: &mut SheetApp, ed: &mut Editor) {
ed.refs.pick = None;
if !ensure_saved(app, ed) {
return;
}
@@ -649,6 +652,7 @@ fn with(mut base: Json, extra: Json) -> Json {
/// Step, Continue or Run to Here: starts debugging if needed (paused before step 1), then acts.
pub fn debug_action(app: &mut SheetApp, ed: &mut Editor, action: &str) {
ed.refs.pick = None;
let debugging = app.session.macro_debug.is_some();
// Starting selects the first step: take Run to Here's target before that.
let target = ed.selected.clone().filter(|s| split_path(s).is_some());
@@ -840,8 +844,9 @@ fn ref_edit(app: &SheetApp, ui: &mut Ui, d: &mut Dialog, refs: &mut RefPick, key
let r = ui.add(egui::TextEdit::singleline(&mut s).desired_width(width - 30.0).id_salt(("refedit", key)));
if r.gained_focus() || (r.clicked() && !picking) {
begin_pick(app, refs, key);
} else if picking && !r.has_focus() && sel != refs.seen {
// A selection made on the grid becomes the reference.
} else if picking && !r.has_focus() && sel != refs.seen && app.session.macro_debug.is_none() {
// A selection made on the grid becomes the reference; while debugging, the selection
// follows the steps and is not a pick.
s = sel.clone();
refs.seen = sel;
}
+34
View File
@@ -162,6 +162,40 @@ fn run_to_here_then_stop_asks_whether_to_keep_the_changes() {
}
}
#[test]
fn debugging_never_writes_the_selection_into_a_reference_box() {
// A reference box that was picking from the grid stays out of it once an action starts, and
// the selections the debugger makes while it runs never land in a box or dirty the draft.
let mut h = harness();
three(&mut h);
click(&mut h, "Step 3: Set A3 to A3");
// The step's Cell box is picking, with the selection it last saw (A1).
let pick = |h: &mut Harness| {
let refs = &mut h.state_mut().macros.editor.as_mut().unwrap().refs;
refs.pick = Some("ref:3:cell".into());
refs.seen = "$A$1".into();
};
pick(&mut h);
h.run_steps(2);
assert_eq!(draft_cells(&h), ["A1", "A2", "A3"]);
click(&mut h, "Run to Here");
assert!(h.state().session.macro_debug.is_some());
let ed = h.state().macros.editor.as_ref().unwrap();
assert!(ed.refs.pick.is_none(), "the action ends the pick");
assert!(!ed.dirty);
// A box focused while debugging does not take the selection either.
pick(&mut h);
h.state_mut().run("selection.set", json!({"range": "F9"})).unwrap();
h.run_steps(3);
let ed = h.state().macros.editor.as_ref().unwrap();
assert!(!ed.dirty, "the draft stays clean");
assert_eq!(draft_cells(&h), ["A1", "A2", "A3"]);
h.state_mut().macros.editor.as_mut().unwrap().refs.pick = None;
click(&mut h, "Stop");
click(&mut h, "Undo Changes");
assert!(h.state().session.macro_debug.is_none());
}
#[test]
fn step_into_from_the_macros_dialog_pauses_before_the_first_step() {
let mut h = harness();
+1 -1
View File
@@ -93,7 +93,7 @@ performance 8, stability 8, localization 4, hardware 2, platforms 2, ecosystem 2
| Get & Transform, external data, data model | 5 | ~15% | ~10% | 60–100 | Import of CSV/TSV, JSON, HTML. No Power Query editor, no From Web, database or folder sources, no connections or refresh, no relationships or data model, no external workbook links (dropped with a warning) |
| Insert objects | 3 | ~55% | ~45% | 25–40 | Pictures, 8 shape kinds (Excel has ~170), text boxes, own icon set, ink with Ink to Shape, hyperlinks, checkboxes. Missing: SmartArt, WordArt, equations, signature line, objects, 3-D models, screenshot, pictures in cells (PR #105) |
| Review, comments, protection, collaboration | 4 | ~55% | ~40% | 35–55 | Threaded comments, notes, spelling (system dictionary), thesaurus, sheet and workbook protection, Allow Edit Ranges with Excel-compatible password hashes (#307). Missing: comment navigation, Show Changes, notes-to-comments conversion, accessibility checker, co-authoring, opening password-encrypted files (refused with a message since #17) |
| Automation | 4 | ~30% | ~20% | 12–20 | Recorded, editable GridCraft scripts (Automate tab). Typed macros in the engine (`macro.*`: recorder, runner with input checks and a footprint dry run, debugger; [macros.md](macros.md)), recorded from Automate › Macros, edited and debugged in a step editor, and run from the Macros dialog or a Ctrl+Shift shortcut. VBA is out of scope by owner decision and is **dropped** when an `.xlsm` is opened (warning shown). No Office Scripts compatibility |
| Automation | 4 | ~30% | ~20% | 12–20 | Recorded, editable GridCraft scripts (Automate tab). Typed macros in the engine (`macro.*`: recorder, runner with input checks and a footprint dry run, debugger; [macros.md](macros.md)), recorded from Automate › Macros, edited and debugged in a step editor, and run from the Macros dialog or a Ctrl+Shift shortcut. VBA is out of scope by owner decision: an `.xlsm` keeps its VBA project unchanged on save and never runs it. No Office Scripts compatibility |
| **Weighted** | 100 | **~75%** | **~59%** | **300–485** | |
## Dimensions