From 759d84e20ba9d2763c15b301727692dad277d658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Fri, 9 Oct 2026 19:12:08 -0400 Subject: [PATCH] ElyTable: closing a tab closes its dialog too (T-11) --- apps/ely-table/src/book.rs | 11 +++++++++++ apps/ely-table/src/dialog.rs | 29 +++++++++++++++++++++++++++++ apps/ely-table/src/rules/aids.rs | 2 +- apps/ely-table/src/tests/output.rs | 23 +++++++++++++++++++++++ tasks/BUGS.md | 2 +- tasks/reviews/T-11-r1.md | 1 + 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 tasks/reviews/T-11-r1.md diff --git a/apps/ely-table/src/book.rs b/apps/ely-table/src/book.rs index 8a22e2c..164dbe8 100644 --- a/apps/ely-table/src/book.rs +++ b/apps/ely-table/src/book.rs @@ -101,6 +101,17 @@ impl Host for Book { self.sync_bars(view, cx); } } + + /// A closed tab's dialog and list go with it. + fn tab_closed(&mut self, tab: &ely_office::Tab, cx: &mut Context) { + if self.dialog.as_ref().and_then(crate::dialog::Dialog::tab) == Some(tab.id) { + self.dialog = None; + } + if self.choices.as_ref().is_some_and(|choices| choices.tab == tab.id) { + self.choices = None; + } + cx.notify(); + } } /// The window root with a blank workbook. diff --git a/apps/ely-table/src/dialog.rs b/apps/ely-table/src/dialog.rs index 4aa0d88..9b8cfac 100644 --- a/apps/ely-table/src/dialog.rs +++ b/apps/ely-table/src/dialog.rs @@ -152,6 +152,35 @@ pub enum Dialog { }, } +impl Dialog { + /// The workbook it asks about; imports have none yet. + pub fn tab(&self) -> Option { + match self { + Dialog::Rename { tab, .. } + | Dialog::Show { tab, .. } + | Dialog::Delete { tab, .. } + | Dialog::Size { tab, .. } + | Dialog::Merge { tab, .. } + | Dialog::Define { tab, .. } + | Dialog::Names { tab, .. } + | Dialog::Sort { tab, .. } + | Dialog::Filter { tab, .. } + | Dialog::Dedupe { tab, .. } + | Dialog::Columns { tab, .. } + | Dialog::Column { tab, .. } + | Dialog::Validation { tab, .. } + | Dialog::Conditional { tab, .. } + | Dialog::Formats { tab, .. } + | Dialog::Pivot { tab, .. } + | Dialog::Chart { tab, .. } + | Dialog::Export { tab, .. } + | Dialog::Page { tab, .. } + | Dialog::Protect { tab, .. } => Some(*tab), + Dialog::Import(_) => None, + } + } +} + impl Book { /// The define dialog's sheets: its own workbook's. pub(crate) fn define_scopes(&self) -> Option> { diff --git a/apps/ely-table/src/rules/aids.rs b/apps/ely-table/src/rules/aids.rs index 9bfe9c9..caeb879 100644 --- a/apps/ely-table/src/rules/aids.rs +++ b/apps/ely-table/src/rules/aids.rs @@ -17,7 +17,7 @@ use crate::book::Book; /// The open choices menu: tab, values, request. pub struct Choices { - tab: u64, + pub(crate) tab: u64, pub(crate) values: Vec, request: (u64, Point), } diff --git a/apps/ely-table/src/tests/output.rs b/apps/ely-table/src/tests/output.rs index ad07500..6df3abc 100644 --- a/apps/ely-table/src/tests/output.rs +++ b/apps/ely-table/src/tests/output.rs @@ -413,3 +413,26 @@ fn an_import_waits_behind_a_dialog_that_displaces_it() { // Text keeps `1E3`; the skipped column stays empty. assert_eq!(cells(&mut cx, &book, "A2:B2").trim_end(), "1E3"); } + +#[test] +fn closing_a_tab_takes_its_dialog_and_frees_the_import() { + let dir = tempfile::tempdir().expect("a temp dir"); + let mut cx = TestAppContext::single(); + let Some((window, book)) = book(&mut cx, dir.path()) else { + eprintln!("SKIP: no LOK build"); + return; + }; + blank(&mut cx, &book); + window + .update(&mut cx, |_, window, cx| { + book.update(cx, |book, cx| book.on_export(&ely_ui::commands::Export, window, cx)) + }) + .expect("the window"); + asked(&cx, &book, |dialog| matches!(dialog, Dialog::Export { .. })); + let id = cx.update(|app| book.read(app).core.tabs[0].id); + update(&mut cx, &book, |book, cx| book.close_tab(id, cx)); + let path = dir.path().join("after.csv"); + std::fs::write(&path, "Name\nx\n").expect("writes"); + update(&mut cx, &book, |book, cx| book.ask_import(path.clone(), cx)); + asked(&cx, &book, |dialog| matches!(dialog, Dialog::Import(_))); +} diff --git a/tasks/BUGS.md b/tasks/BUGS.md index 69361f7..e3f335e 100644 --- a/tasks/BUGS.md +++ b/tasks/BUGS.md @@ -18,7 +18,7 @@ - [x] T-08 自动筛选的列菜单对光标所在的表而不是按钮所在的表筛选、排序 — 先把光标移到按钮所在格再排序或筛选;R1 PASS - [x] T-09 导入文本文件时整文件的 UTF-8 校验在界面线程跑 — 编码与分隔符的猜测随读文件在后台;R1 PASS - [x] T-10 CSV 导入对话框开着时打开任何别的对话框,待导入的文件静默消失 — 被挤开的导入回到队头,已读完的保留列类型;R2 PASS -- [ ] T-11 对话框比其标签活得久:导出、定义名称、重命名不可见却“开着”,挡住导入;名称表的“转到”激活已关闭的标签 +- [x] T-11 对话框比其标签活得久:导出、定义名称、重命名不可见却“开着”,挡住导入;名称表的“转到”激活已关闭的标签 — 关标签时一并关掉其对话框与选项列表;R1 PASS - [ ] T-12 打印区域是整列或整行时页面设置无法应用 - [ ] T-13 打印失败报成“导出失败”(非 macOS 必现) - [ ] T-14 导入扫描把整个文件的每个字段都建成字符串 diff --git a/tasks/reviews/T-11-r1.md b/tasks/reviews/T-11-r1.md new file mode 100644 index 0000000..7ef22e9 --- /dev/null +++ b/tasks/reviews/T-11-r1.md @@ -0,0 +1 @@ +PASS