diff --git a/ROADMAP.md b/ROADMAP.md index 1189fd7..1bbae9a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -131,6 +131,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in | Date | What landed | |---|---| +| 2026-10-11 | Selected charts, pictures and shapes can be deleted from the keyboard (#213) | | 2026-10-10 | Ribbon translated into Japanese, Chinese, Korean, Brazilian Portuguese and Russian with system-language default (#31, #104, #82); CJK/Thai/Hebrew font fallback (#38); clear messages for encrypted and `.xls` files (#17); smooth line charts (#62). Progress docs restructured to the craftrules standard; full re-measure (this page). Initial ribbon key tips (#43), in-place text box editing (#84), copy as HTML table (#36). ODS and XLSB data import (#100, #101); recalc linear in the number of range formulas (#66); RISC-V Linux build; Flatpak repository on Pages; web cell-commit trap fixed | | 2026-10-09 | Community fixes: spill range operator `A1#`, sheet-scoped names, protection refuses locked-cell edits, Insert/Delete Cells adjust references, `DATE(1900,2,29)`, SUMIF sizing, `ROUND` at 15 digits, `_xlpm.` LAMBDA parameters in XLSX, vertical scrollbar, system appearance, border previews; v0.4.0 | | 2026-10-08 | v0.2.0 and v0.3.0 releases; Flatpak, AppImage zsync, branded DMG; desktop log file; DirectX 12 default on Windows | @@ -142,6 +143,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | Selected objects can be deleted from the keyboard (#213) | | 2026-10-10 | minor | Readiness-by-audience table with hours to ~95% per audience; full number unchanged (additive weighted sum) | | 2026-10-10 | minor | Added Mainstream practitioner (~50%) and Essentials user (~63%); languages updated for the 10-10 merges (ribbon in ja, zh, ko, pt-BR, ru); localization 5%→10%; full number re-checked (51.6, unchanged) | | 2026-10-10 | minor | Checked against the alpha gate (six core workflows pass): stays alpha | diff --git a/crates/ui-egui/src/grid.rs b/crates/ui-egui/src/grid.rs index 72d33e2..6b7530d 100644 --- a/crates/ui-egui/src/grid.rs +++ b/crates/ui-egui/src/grid.rs @@ -1608,6 +1608,22 @@ fn object_anchor(sh: &Sheet, kind: &str, id: u32) -> Option bool { + let Some(id) = app.selected_chart else { return false }; + let kind = if sh.charts.iter().any(|object| object.id == id) { + "chart" + } else if sh.images.iter().any(|object| object.id == id) { + "image" + } else if sh.shapes.iter().any(|object| object.id == id) { + "shape" + } else { + return false; + }; + app.run_or_alert("object.delete", json!({"kind": kind, "id": id})); + app.selected_chart = None; + true +} + pub fn follow_link(app: &mut SheetApp, target: &str) { if target.contains("://") || target.starts_with("mailto:") { if let Some(f) = &app.services.open_url { @@ -1708,7 +1724,9 @@ fn keyboard(app: &mut SheetApp, ctx: &egui::Context, resp: &egui::Response, geo: } Key::Tab => app.move_after_enter(0, if shift { -1 } else { 1 }), Key::F2 => app.begin_edit(None, false), + Key::Delete if delete_selected_object(app, sh) => {} Key::Delete => app.run_or_alert("edit.clearContents", json!({})), + Key::Backspace if delete_selected_object(app, sh) => {} Key::Backspace => { // Excel for Mac: Delete clears the cell and starts editing it. app.run_or_alert("edit.clearContents", json!({})); diff --git a/crates/ui-egui/tests/interaction.rs b/crates/ui-egui/tests/interaction.rs index 84f20a6..7558771 100644 --- a/crates/ui-egui/tests/interaction.rs +++ b/crates/ui-egui/tests/interaction.rs @@ -85,6 +85,21 @@ fn click_cell(h: &mut egui_kittest::Harness<'static, SheetApp>, cell: &str) { h.run_steps(2); } +fn click_chart(h: &mut egui_kittest::Harness<'static, SheetApp>, id: u32) { + let app = h.state(); + let sheet = app.session.active().unwrap().wb.active().unwrap(); + let geo = Geo::new(sheet, app.grid.rect.unwrap(), app.view().scroll); + let anchor = sheet.charts.iter().find(|chart| chart.id == id).unwrap().anchor; + let pos = egui::pos2(geo.x(sheet, anchor.cell.col) + anchor.dx * geo.z, geo.y(sheet, anchor.cell.row) + anchor.dy * geo.z) + + egui::vec2(anchor.width, anchor.height) * geo.z / 2.0; + h.input_mut().events.extend([ + Event::PointerMoved(pos), + Event::PointerButton { pos, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE }, + Event::PointerButton { pos, button: PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE }, + ]); + h.run_steps(2); +} + #[test] fn keyboard_navigation_does_not_replay_the_last_pointer_click() { let mut h = harness(blank()); @@ -170,6 +185,24 @@ fn shortcuts_format_and_extend() { assert_eq!(value(&h, "A1"), Value::Empty); } +#[test] +fn delete_key_removes_the_selected_chart() { + let mut session = blank(); + session.execute("range.setValues", json!({"range": "A1:B2", "values": [[1, 2], [3, 4]]})).unwrap(); + let id = session.execute("insert.chart", json!({"range": "A1:B2", "at": "D2"})).unwrap()["chart"].as_u64().unwrap() as u32; + let mut h = harness(session); + + click_cell(&mut h, "C10"); + click_chart(&mut h, id); + assert_eq!(h.state().selected_chart, Some(id)); + + key(&mut h, Key::Delete, Modifiers::NONE); + + assert!(h.state().session.active().unwrap().wb.active().unwrap().charts.is_empty()); + assert_eq!(h.state().selected_chart, None); + assert_eq!(value(&h, "A1"), Value::Number(1.0)); +} + #[test] fn renders_every_ribbon_tab_without_panicking() { let mut s = Session::new(); diff --git a/docs/ui-parity.md b/docs/ui-parity.md index e85bca1..6c341de 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (created from a source audit and the issue tracker) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (selected objects can be deleted from the keyboard) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 Interaction, controls and feel, against Excel. Part of [target-app-parity.md](target-app-parity.md). **UI/UX fidelity: ~55% ready, 50–80 h** (estimated). Ribbon command coverage is measured @@ -56,6 +56,7 @@ Sources: `crates/ui-egui/src` (ribbon, grid, editor, formula bar, dialogs, panes | Ctrl+1, Ctrl+; and Ctrl+Shift+; , Ctrl+D/R, Ctrl+E, Ctrl+T, Ctrl+K, Ctrl+Shift+L | yes | most done; audit pending | | F2, F4, F5, F9 family, Shift+F3, F11 | yes | most; F11 chart sheet missing (no chart sheets) | | Mac-specific (Cmd variants, Fn keys) | yes | Cmd mapping done | +| Delete selected charts, pictures and shapes | yes | done (#213) | | Requests | — | #110 (more shortcuts and hot keys), #33 (sequential Alt; initial support landed in #43) | Work: a shortcut table generated from the command catalog checked against Microsoft's published @@ -91,5 +92,6 @@ scrollbar bugs 2–4 · pixel/feel pass against observed Excel 7–12. | Date | Change | Summary | |---|---|---| +| 2026-10-11 | minor | Delete and Backspace now remove the selected chart, picture or shape (#213) | | 2026-10-10 | minor | Chart resize bug (#190) | | 2026-10-10 | major | Created: chrome, grid, keyboard, dialogs, accessibility; key tips, Page Layout view and accessibility tree flagged |