From a75224617b8a8caa6f449b8a477396e4112c6e00 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sat, 24 Oct 2026 15:43:52 -0700 Subject: [PATCH] Status bar: Circular References names a cell only when a loop is on the active sheet The status bar named the first circular reference in the list, even when it was on another sheet. It now names the first one on the active sheet, and shows only Circular References when every loop is on other sheets, as Excel's status bar does. --- crates/ui-egui/src/tabs.rs | 11 +++++++--- crates/ui-egui/tests/it/interaction.rs | 28 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/crates/ui-egui/src/tabs.rs b/crates/ui-egui/src/tabs.rs index 10b0c3bc0..d6d462b80 100644 --- a/crates/ui-egui/src/tabs.rs +++ b/crates/ui-egui/src/tabs.rs @@ -281,9 +281,14 @@ pub fn status_bar(app: &mut SheetApp, ui: &mut Ui) { } if !d.calc.circular.is_empty() { ui.add_space(12.0); - let (si, c) = d.calc.circular[0]; - let name = d.wb.sheet(si).map(|s| gridcraft_engine::formula::quote_sheet(&s.name)).unwrap_or_default(); - ui.label(egui::RichText::new(format!("Circular References: {name}!{}", c.a1())).font(theme::ui_font(12.5)).color(t.danger)); + let label = match d.calc.circular.iter().find(|(si, _)| *si == d.wb.active_sheet) { + Some(&(si, c)) => { + let name = d.wb.sheet(si).map(|s| gridcraft_engine::formula::quote_sheet(&s.name)).unwrap_or_default(); + format!("Circular References: {name}!{}", c.a1()) + } + None => "Circular References".to_owned(), + }; + ui.label(egui::RichText::new(label).font(theme::ui_font(12.5)).color(t.danger)); } if app.session.clipboard.is_some() && app.editor.is_none() { ui.add_space(12.0); diff --git a/crates/ui-egui/tests/it/interaction.rs b/crates/ui-egui/tests/it/interaction.rs index fbe7089e6..71779aa26 100644 --- a/crates/ui-egui/tests/it/interaction.rs +++ b/crates/ui-egui/tests/it/interaction.rs @@ -931,6 +931,34 @@ fn status_bar_quotes_the_sheet_name_of_a_circular_reference() { assert!(h.query_by_label("Circular References: 'Bob''s Q1'!B2").is_some(), "the status bar names the cell as a reference"); } +#[test] +fn status_bar_names_no_cell_when_every_circular_reference_is_on_another_sheet() { + let mut s = blank(); + s.execute("home.insertSheet", json!({"name": "Data"})).unwrap(); + s.execute("cell.set", json!({"cell": "B2", "input": "=B2+1"})).unwrap(); + s.execute("sheet.activate", json!({"sheet": "Sheet1"})).unwrap(); + let mut h = harness(s); + assert!(h.query_by_label("Circular References").is_some(), "the status bar still reports circular references"); + assert!(h.query_by_label("Circular References: Data!B2").is_none(), "no cell address from another sheet"); + h.state_mut().session.execute("sheet.activate", json!({"sheet": "Data"})).unwrap(); + h.run_steps(2); + assert!(h.query_by_label("Circular References: Data!B2").is_some(), "the active sheet's loop is named"); +} + +#[test] +fn status_bar_names_a_circular_reference_on_the_active_sheet() { + let mut s = blank(); + s.execute("cell.set", json!({"cell": "A1", "input": "=A1+1"})).unwrap(); + s.execute("home.insertSheet", json!({"name": "Data"})).unwrap(); + s.execute("cell.set", json!({"cell": "B2", "input": "=B2+1"})).unwrap(); + s.execute("formulas.calculateNow", json!({})).unwrap(); + let circular = s.active().unwrap().calc.circular.clone(); + assert_eq!(circular, vec![(0, CellRef::new(0, 0)), (1, CellRef::new(1, 1))], "Sheet1's loop is listed first"); + let h = harness(s); + assert!(h.query_by_label("Circular References: Data!B2").is_some(), "the status bar names the loop on the active sheet"); + assert!(h.query_by_label("Circular References: Sheet1!A1").is_none(), "not the first loop listed"); +} + #[test] fn alt_f8_opens_the_macros_dialog() { let mut h = harness(blank());