ElyTable: page setup applies with whole-column or whole-row print areas (T-12)

This commit is contained in:
ZacharyZhang-NY committed 2026-10-09 19:24:50 -04:00
1 parent 759d84e20b
commit 18158a8282
5 files changed
+55 -2

No files matched your search

+17 -1
View File
@@ -82,6 +82,15 @@ fn cell_ok(cell: &str) -> bool {
&& row_number(digits).is_some()
}
/// Whole columns or rows, like `$A:$D`; one `$` each.
fn whole(from: &str, to: &str, number: fn(&str) -> Option<u32>) -> bool {
let end = |end: &str| {
let end = end.strip_prefix('$').unwrap_or(end);
end.bytes().all(|byte| byte.is_ascii_alphanumeric()).then(|| number(&end.to_ascii_uppercase()))?
};
matches!((end(from), end(to)), (Some(first), Some(last)) if first <= last)
}
/// Areas as the kernel takes them, or None.
fn areas(text: &str) -> Option<String> {
let tokens: Vec<&str> = text
@@ -90,7 +99,9 @@ fn areas(text: &str) -> Option<String> {
.filter(|token| !token.is_empty())
.collect();
let ok = |token: &&str| match token.split_once(':') {
Some((from, to)) => cell_ok(from) && cell_ok(to),
Some((from, to)) => {
cell_ok(from) && cell_ok(to) || whole(from, to, column_number) || whole(from, to, row_number)
}
None => cell_ok(token),
};
tokens.iter().all(ok).then(|| tokens.join(","))
@@ -228,6 +239,11 @@ mod tests {
assert_eq!(areas("A1:B"), None);
assert_eq!(areas("XFE1"), None);
assert_eq!(areas("S!A1"), None);
assert_eq!(areas("$A:$D, 1:3").as_deref(), Some("$A:$D,1:3"));
assert_eq!(areas("A:3"), None);
for bad in ["$$A:$$D", "$$1:$$3", "$A:$$D", "A:D,$$E:$$F", "+1:2", "D:A"] {
assert_eq!(areas(bad), None, "{bad}");
}
assert_eq!(span("$1:$3", row_number), Some(Some((1, 3))));
assert_eq!(span("2", row_number), Some(Some((2, 2))));
assert_eq!(span("3:1", row_number), None);
+33
View File
@@ -436,3 +436,36 @@ fn closing_a_tab_takes_its_dialog_and_frees_the_import() {
update(&mut cx, &book, |book, cx| book.ask_import(path.clone(), cx));
asked(&cx, &book, |dialog| matches!(dialog, Dialog::Import(_)));
}
#[test]
fn a_whole_column_print_area_still_applies() {
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);
update(&mut cx, &book, |book, cx| book.ask_page(cx));
asked(&cx, &book, |dialog| matches!(dialog, Dialog::Page { .. }));
type_in(&mut cx, &book, area, "A:D");
update(&mut cx, &book, |book, cx| book.page_asked(cx));
let layout = read(&mut cx, &book, sheet::print_layout, sheet::LAYOUT);
assert_eq!(layout.areas.len(), 1, "set: {:?}", layout.areas);
// The kernel's own text comes back into the dialog.
update(&mut cx, &book, |book, cx| book.ask_page(cx));
asked(&cx, &book, |dialog| matches!(dialog, Dialog::Page { .. }));
let shown = cx.update(|app| match book.read(app).dialog.as_ref() {
Some(dialog) => area(dialog).read(app).text().to_string(),
None => unreachable!("a page dialog"),
});
assert_eq!(shown, layout.areas[0]);
update(&mut cx, &book, |book, cx| {
if let Some(Dialog::Page { landscape, .. }) = &mut book.dialog {
*landscape = true;
}
book.page_asked(cx)
});
let layout = read(&mut cx, &book, sheet::print_layout, sheet::LAYOUT);
assert!(layout.landscape, "applied with {shown}");
}
+1 -1
View File
@@ -19,7 +19,7 @@
- [x] T-09 导入文本文件时整文件的 UTF-8 校验在界面线程跑 — 编码与分隔符的猜测随读文件在后台;R1 PASS
- [x] T-10 CSV 导入对话框开着时打开任何别的对话框,待导入的文件静默消失 — 被挤开的导入回到队头,已读完的保留列类型;R2 PASS
- [x] T-11 对话框比其标签活得久:导出、定义名称、重命名不可见却“开着”,挡住导入;名称表的“转到”激活已关闭的标签 — 关标签时一并关掉其对话框与选项列表;R1 PASS
- [ ] T-12 打印区域是整列或整行时页面设置无法应用
- [x] T-12 打印区域是整列或整行时页面设置无法应用 — 打印区域可为整列、整行(每端至多一个 $);R2 PASS
- [ ] T-13 打印失败报成“导出失败”(非 macOS 必现)
- [ ] T-14 导入扫描把整个文件的每个字段都建成字符串
- [ ] T-15 非 UTF-8 文本的默认编码跟系统区域而不是界面语言
+3
View File
@@ -0,0 +1,3 @@
FAIL
apps/ely-table/src/page.rs:96 — 新增整列、整行分支复用 `span()`,其中 `trim_start_matches('$')` 会剥掉重复的 `$`,校验通过后却发送未经规范化的原字符串。具体场景:已有打印区域 `A1:B2`,在页面设置输入 `$$A:$$D`、`$$1:$$3` 或 `$A:$$D` 后应用;`areas()` 接受输入,实际内核的 `print.area` 返回 `Ok(())`,重读 `.uno:PrintLayout` 得到 `areas=[]`,原打印区域被静默清空,打印范围恢复为已用区域。输入 `A:D,$$E:$$F` 也会静默丢弃第二段。独立内核探针已复现;针对重复 `$` 的拒绝断言在改动前通过、当前版本失败,现有 47 个 ElyTable 测试仍全部通过。修复方向:整列、整行的端点仅接受至多一个前导 `$`,将非法输入保留在对话框并报引用错误,补充重复 `$` 的校验和原打印区域保持测试。证据:`/tmp/ely-t12-r1-probe.log`、`/tmp/ely-t12-r1-original-invalid.log`、`/tmp/ely-t12-r1-current-invalid.log`。
+1
View File
@@ -0,0 +1 @@
PASS