Skip to content

Commit be191d8

Browse files
da-liiiclaude
andauthored
[1292] 采用 QML 对话框重构增加宏包弹窗并增加存在性校验 (#4534)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 13e762d commit be191d8

15 files changed

Lines changed: 391 additions & 62 deletions

File tree

TeXmacs/plugins/lang/dic/en_US/zh_CN.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,8 @@
19461946
("overline" "上划线")
19471947
("overlined block" "上划线块")
19481948
("overview of the scheme extension language" "Scheme 扩展语言概览")
1949+
("package added: " "宏包已添加: ")
1950+
("package does not exist: " "宏包不存在: ")
19491951
("padded block" "补白块")
19501952
("padding" "补白")
19511953
("page bottom margin" "")

TeXmacs/progs/generic/document-menu.scm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
(-> "Add package"
8080
(link toggle-package-menu)
8181
---
82-
("Add other package" (interactive add-style-package))
82+
("Add other package" (open-add-package-dialog))
8383
) ;->
8484
) ;menu-bind
8585

@@ -1137,7 +1137,7 @@
11371137
(-> "Add style package"
11381138
(link add-package-menu)
11391139
---
1140-
("Other package" (interactive add-style-package))
1140+
("Other package" (open-add-package-dialog))
11411141
) ;->
11421142
) ;tm-menu
11431143

@@ -1225,7 +1225,7 @@
12251225
(=> (balloon (icon "tm_add.xpm") "Add style package")
12261226
(link add-package-menu)
12271227
---
1228-
("Other package" (interactive add-style-package))
1228+
("Other package" (open-add-package-dialog))
12291229
) ;=>
12301230
(assuming (tree-is-buffer? t)
12311231
((balloon (icon "tm_focus_help.xpm") "Describe tag") (focus-help))

TeXmacs/progs/generic/document-style.scm

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,32 @@
173173
(set-style-list (append (get-style-list) (list pack)))
174174
) ;tm-define
175175

176+
;; 从 cpp-add-package-dialog 的返回 tree 里取宏包名。
177+
;; OK 返回 (tuple (tuple "package" <name>)),Cancel / 关闭返回空 tuple。#f 表示无有效输入。
178+
(define-public (add-package-result result)
179+
(with kvs (cdr (tree->stree result)) (if (nnull? kvs) (caddr (car kvs)) #f))
180+
) ;define-public
181+
182+
;; 焦点 / 文档 → 增加宏包 → 其他宏包:专用 QML 弹窗(DialogShell + InputField,run_qml_dialog)。
183+
;; OK 时检查宏包是否存在:存在则 add-style-package 追加;不存在则弹 QML 确认弹窗提示并不予添加。空串 / Cancel / 关闭不追加。
184+
(tm-define (open-add-package-dialog)
185+
(:interactive #t)
186+
(with pack
187+
(add-package-result (cpp-add-package-dialog))
188+
(when (and (string? pack) (!= pack ""))
189+
(if (package-exists? pack)
190+
(begin
191+
(add-style-package pack)
192+
(set-message (string-append (translate "Package added: ") pack) "Package")
193+
) ;begin
194+
(cpp-confirm-question (string-append (translate "Package does not exist: ") pack)
195+
(list (translate "OK"))
196+
) ;cpp-confirm-question
197+
) ;if
198+
) ;when
199+
) ;with
200+
) ;tm-define
201+
176202
(tm-define (remove-style-package pack)
177203
(:argument pack "Remove package")
178204
(:proposals pack (with l (get-style-list) (if (null? l) l (cdr l))))
@@ -196,23 +222,32 @@
196222
) ;if
197223
) ;tm-define
198224

199-
(define (url-resolve-package name)
225+
(define-public (url-resolve-package name)
200226
(let* ((stem-name (string-append name ".stem"))
201227
(ts-name (string-append name ".ts"))
202228
(stem-url (url-append "$TEXMACS_STYLE_PATH" stem-name))
203-
(stem-local (url-relative (current-buffer) stem-name))
229+
(buf (current-buffer))
230+
(has-local? (and (url? buf) (not (url-scratch? buf)) (not (url-rooted-tmfs? buf)))
231+
) ;has-local?
232+
(stem-local (if has-local? (url-relative buf stem-name) (url-none)))
233+
(stem-pkg (url-append "$TEXMACS_PATH/packages" stem-name))
204234
(ts-url (url-append "$TEXMACS_STYLE_PATH" ts-name))
205-
(ts-local (url-relative (current-buffer) ts-name))
235+
(ts-local (if has-local? (url-relative buf ts-name) (url-none)))
236+
(ts-pkg (url-append "$TEXMACS_PATH/packages" ts-name))
206237
) ;
207238
(with stem-resolved
208-
(url-resolve (url-or stem-url stem-local) "r")
239+
(url-resolve (url-or stem-url (url-or stem-local stem-pkg)) "r")
209240
(if (url-none? stem-resolved)
210-
(url-resolve (url-or ts-url ts-local) "r")
241+
(url-resolve (url-or ts-url (url-or ts-local ts-pkg)) "r")
211242
stem-resolved
212243
) ;if
213244
) ;with
214245
) ;let*
215-
) ;define
246+
) ;define-public
247+
248+
(define-public (package-exists? name)
249+
(and (string? name) (!= name "") (not (url-none? (url-resolve-package name))))
250+
) ;define-public
216251

217252
(tm-define (edit-package-source name)
218253
(with file-name

TeXmacs/progs/prog/glue-symbols.scm

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -216,29 +216,29 @@
216216
"window-set-buffer" "window-focus" "switch-to-window" "new-buffer"
217217
"open-buffer-in-window" "open-window" "open-window-geometry" "clone-window"
218218
"cpp-buffer-close" "cpp-confirm-close" "cpp-confirm-restart"
219-
"cpp-form-dialog" "cpp-search-recent-dialog" "cpp-font-selector-dialog"
220-
"cpp-paragraph-format-dialog" "cpp-preferences-dialog"
221-
"cpp-print-to-file-dialog" "cpp-statistics-dialog" "cpp-version-dialog"
222-
"cpp-export-pdf-dialog" "cpp-updater-dialog-open" "cpp-updater-dialog-close"
223-
"cpp-wait-dialog-open" "cpp-wait-dialog-close" "cpp-rasterize-widget"
224-
"kill-window" "kill-current-window-and-buffer" "project-attach"
225-
"project-detach" "project-attached?" "project-get" "alt-window-handle"
226-
"alt-window-create-quit" "alt-window-create-plain" "alt-window-create-popup"
227-
"alt-window-create-tooltip" "alt-window-delete" "alt-window-show"
228-
"alt-window-hide" "alt-window-get-size" "alt-window-set-size"
229-
"alt-window-get-position" "alt-window-set-position" "alt-window-search"
230-
"supports-bibtex?" "bibtex-run" "bib-add-period" "bib-locase-first"
231-
"bib-upcase-first" "bib-locase" "bib-upcase" "bib-default-preserve-case"
232-
"bib-default-upcase-first" "bib-purify" "bib-text-length" "bib-prefix"
233-
"bib-empty?" "bib-field" "bib-abbreviate" "extract-attachments"
234-
"pdf-make-attachments" "pdf-get-linked-file-paths" "pdf-replace-linked-path"
235-
"pdf-get-attached-main-tm" "array-url-append" "insert-kbd-wildcard"
236-
"set-variant-keys" "kbd-pre-rewrite" "kbd-post-rewrite" "kbd-system-rewrite"
237-
"set-font-rules" "window-get-serial" "window-set-property"
238-
"window-get-property" "show-header" "show-icon-bar" "show-side-tools"
239-
"show-bottom-tools" "show-footer" "visible-header?" "visible-icon-bar?"
240-
"visible-side-tools?" "visible-bottom-tools?" "visible-footer?"
241-
"full-screen-mode" "full-screen?" "full-screen-edit?"
219+
"cpp-form-dialog" "cpp-search-recent-dialog" "cpp-add-package-dialog"
220+
"cpp-font-selector-dialog" "cpp-paragraph-format-dialog"
221+
"cpp-preferences-dialog" "cpp-print-to-file-dialog" "cpp-statistics-dialog"
222+
"cpp-version-dialog" "cpp-export-pdf-dialog" "cpp-updater-dialog-open"
223+
"cpp-updater-dialog-close" "cpp-wait-dialog-open" "cpp-wait-dialog-close"
224+
"cpp-rasterize-widget" "kill-window" "kill-current-window-and-buffer"
225+
"project-attach" "project-detach" "project-attached?" "project-get"
226+
"alt-window-handle" "alt-window-create-quit" "alt-window-create-plain"
227+
"alt-window-create-popup" "alt-window-create-tooltip" "alt-window-delete"
228+
"alt-window-show" "alt-window-hide" "alt-window-get-size"
229+
"alt-window-set-size" "alt-window-get-position" "alt-window-set-position"
230+
"alt-window-search" "supports-bibtex?" "bibtex-run" "bib-add-period"
231+
"bib-locase-first" "bib-upcase-first" "bib-locase" "bib-upcase"
232+
"bib-default-preserve-case" "bib-default-upcase-first" "bib-purify"
233+
"bib-text-length" "bib-prefix" "bib-empty?" "bib-field" "bib-abbreviate"
234+
"extract-attachments" "pdf-make-attachments" "pdf-get-linked-file-paths"
235+
"pdf-replace-linked-path" "pdf-get-attached-main-tm" "array-url-append"
236+
"insert-kbd-wildcard" "set-variant-keys" "kbd-pre-rewrite"
237+
"kbd-post-rewrite" "kbd-system-rewrite" "set-font-rules" "window-get-serial"
238+
"window-set-property" "window-get-property" "show-header" "show-icon-bar"
239+
"show-side-tools" "show-bottom-tools" "show-footer" "visible-header?"
240+
"visible-icon-bar?" "visible-side-tools?" "visible-bottom-tools?"
241+
"visible-footer?" "full-screen-mode" "full-screen?" "full-screen-edit?"
242242
"set-window-zoom-factor" "get-window-zoom-factor" "shell" "dialogue-end"
243243
"cpp-choose-file" "tm-interactive" "cpp-style-clear-cache"
244244
"set-script-status" "set-printing-command" "set-printer-paper-type"

TeXmacs/tests/1292.scm

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2+
;;
3+
;; MODULE : 1292.scm
4+
;; DESCRIPTION : 「焦点/文档 → 增加宏包 → 其他宏包」QML 迁移的数据契约测试。
5+
;; COPYRIGHT : (C) 2026 Mogan STEM
6+
;;
7+
;; PURPOSE
8+
;; [1292] 验证「其他宏包」改用专用 QML 弹窗后:
9+
;; - add-package-result 从 cpp-add-package-dialog 返回 tree 提取宏包名
10+
;; - 测试钩子 cancel 返回空 tuple;ok 返回空宏包名;指定包名返回相应包名
11+
;; - package-exists? 校验宏包是否存在
12+
;; - open-add-package-dialog 在宏包不存在时弹确认提示并不追加,存在时追加宏包
13+
;;
14+
;; USAGE
15+
;; xmake b stem
16+
;; xmake r 1292
17+
;;
18+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19+
20+
(import (liii check))
21+
22+
(load "./TeXmacs/progs/generic/document-style.scm")
23+
24+
(check-set-mode! 'report-failed)
25+
26+
(define (check-result-ok)
27+
(check (add-package-result (stree->tree '(tuple (tuple "package"
28+
"preview-ref"))))
29+
=>
30+
"preview-ref"
31+
) ;check
32+
) ;define
33+
34+
(define (check-result-cancel)
35+
(check (add-package-result (stree->tree '(tuple))) => #f)
36+
) ;define
37+
38+
(define (check-hook)
39+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "cancel")
40+
(check (add-package-result (cpp-add-package-dialog)) => #f)
41+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "ok")
42+
(check (add-package-result (cpp-add-package-dialog)) => "")
43+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "preview-ref")
44+
(check (add-package-result (cpp-add-package-dialog)) => "preview-ref")
45+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "")
46+
) ;define
47+
48+
(define (check-package-exists)
49+
(check (package-exists? "chinese") => #t)
50+
(check (package-exists? "preview-ref") => #t)
51+
(check (package-exists? "non-existent-pkg-xyz-12345") => #f)
52+
(check (package-exists? "") => #f)
53+
) ;define
54+
55+
(define (check-dialog-nonexistent-package)
56+
(let* ((orig-style (get-style-list)))
57+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "non-existent-pkg-xyz-12345")
58+
(system-setenv "MOGAN_TEST_CONFIRM_QUESTION" "0")
59+
(open-add-package-dialog)
60+
(check (get-style-list) => orig-style)
61+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "")
62+
(system-setenv "MOGAN_TEST_CONFIRM_QUESTION" "")
63+
) ;let*
64+
) ;define
65+
66+
(define (check-dialog-valid-package)
67+
(let* ((orig-style (get-style-list)))
68+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "preview-ref")
69+
(open-add-package-dialog)
70+
(check (has-style-package? "preview-ref") => #t)
71+
(system-setenv "MOGAN_TEST_ADD_PACKAGE" "")
72+
(set-style-list orig-style)
73+
) ;let*
74+
) ;define
75+
76+
(tm-define (test_1292)
77+
(check-result-ok)
78+
(check-result-cancel)
79+
(check-hook)
80+
(check-package-exists)
81+
(check-dialog-nonexistent-package)
82+
(check-dialog-valid-package)
83+
(check-report)
84+
) ;tm-define

ai-docs/qml/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ OK 时算与快照的 diff → `prefBridge.submit(diff)` 一次性应用;Cance
161161
| `FormDialog` | `run_qml_dialog`(exec) | 本地暂存 `values`,OK 一次性 submit(页面设置走此弹窗) |
162162
| `PrintToFile` | `run_qml_dialog`(exec) | 路径 + 页码一次提交;Browse 走原生保存框 |
163163
| `SearchRecent` | `run_qml_dialog`(exec) | 搜索词一次提交,scheme 走 `docgrep-in-recent` |
164+
| `AddPackage` | `run_qml_dialog`(exec) | 宏包名称一次提交,校验存在性后走 `add-style-package` |
164165
| `FontSelector` | `run_modal_qml_dialog`(setModal+show) | live 写回文档,OK 落定 / Cancel 快照撤销 / Reset 按 global? 分流(文档级系统默认、段落级回快照) |
165166
| `ParagraphFormat` | `run_modal_qml_dialog`(setModal+show) | live 写回(段落 with / 文档 initial),按 scope 撤销 |
166167
| `Statistics` | `run_qml_dialog`(exec) | 纯展示统计行(`statsItems` 注入 `{label,value}`),Close 即关,无返回值 |

devel/1292.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# [1292] 增加宏包弹窗 QML 重构
2+
3+
## 1 相关文档
4+
- [ai-docs/qml/README.md](../ai-docs/qml/README.md) — QML 弹窗体系(DialogShell + atoms + run_qml_dialog;新增成品弹窗/原子的登记流程)
5+
6+
## 2 任务相关的代码文件
7+
- `src/Plugins/Qt/qml/AddPackage.qml` — 「增加宏包」成品弹窗(DialogShell + InputField + DialogButtons,run_qml_dialog)
8+
- `src/Plugins/Qt/qml/atoms/InputField.qml` — 增加 `forceFocus()` 辅助方法供打开弹窗时光标自聚焦
9+
- `src/Plugins/Qt/QTMQmlDialog.cpp``cpp_add_package_dialog` glue 实现(run_qml_dialog + 注入 packageLabel/packageName;测试钩子 `MOGAN_TEST_ADD_PACKAGE`
10+
- `src/Plugins/Qt/QTMQmlDialog.hpp``cpp_add_package_dialog` 声明
11+
- `src/Plugins/Qt/moganqml.qrc` + `src/Plugins/Qt/qml/qmldir` — AddPackage 注册
12+
- `TeXmacs/progs/prog/glue-symbols.scm``cpp-add-package-dialog` glue 符号
13+
- `src/Scheme/L5/glue_qt.lua``cpp-add-package-dialog``cpp_add_package_dialog`
14+
- `TeXmacs/progs/generic/document-style.scm``add-package-result` + `package-exists?` + `open-add-package-dialog`(宏包存在时调 `add-style-package`,不存在时弹 QML 确认弹窗提示)
15+
- `TeXmacs/plugins/lang/dic/en_US/zh_CN.scm` — 增加「宏包不存在: 」翻译
16+
- `TeXmacs/progs/generic/document-menu.scm` — 菜单与工具栏中「其他宏包」/「增加其他宏包」改调 `(open-add-package-dialog)`
17+
- `tests/Plugins/Qt/qml_load_test.cpp``test_add_package_loads`(AddPackage.qml 加载断言)
18+
- `TeXmacs/tests/1292.scm` — 契约与集成测试(add-package-result 提取 + `MOGAN_TEST_ADD_PACKAGE` 钩子)
19+
- `ai-docs/qml/README.md` — 登记 AddPackage 成品弹窗
20+
21+
## 3 如何测试
22+
23+
### 3.1 确定性测试
24+
```bash
25+
# QML 加载回归:AddPackage.qml 仍能 Ready
26+
xmake b qml_load_test
27+
xmake r qml_load_test
28+
29+
# 纯逻辑与契约测试:add-package-result 提取 + 钩子 ok/cancel/<name>(headless)
30+
xmake b stem
31+
xmake r 1292
32+
```
33+
34+
### 3.2 手动 GUI 测试
35+
```bash
36+
MOGAN_TEST_GUI=1 xmake r 1292
37+
```
38+
或直接启动 Mogan:
39+
点击顶部菜单「文档 → 增加宏包 → 增加其他宏包」或焦点工具栏中的「增加宏包 → 其它宏包」,弹出 QML 对话框,输入宏包名称(如 `preview-ref`),回车或点击 OK,验证文档样式列表成功添加该宏包;按 Esc 或点击取消,验证宏包未被添加。
40+
41+
## 4 如何提交
42+
```bash
43+
gf fmt --changed-since=main
44+
```
45+
46+
## 5 What
47+
1. 使用专用 QML 弹窗(`DialogShell` + `InputField` + `DialogButtons` + `run_qml_dialog`)重构「增加宏包 -> 其他宏包...」弹窗,替换旧的 `(interactive add-style-package)` C++ 遗留对话框。
48+
2. 在 Scheme 侧新增 `(open-add-package-dialog)` 统一入口,解构返回值并调用 `(add-style-package pack)`
49+
3. 替换 `document-menu.scm` 中焦点菜单、焦点图标栏及文档菜单中的调用点。
50+
4. 校验输入的宏包是否存在:若不存在,弹出 QML 确认弹窗提示并不予添加。
51+
52+
## 6 Why
53+
- 原有 `(interactive add-style-package)` 依赖 C++ 遗留的 `qt_inputs_list_widget_rep` 对话框,风格陈旧且无法适配现代 UI 主题。
54+
- 与其他已迁移至 QML 的模态弹窗(如搜索最近打开的文档、打印到文件、页面设置等)保持一致的交互与视觉体验。
55+
56+
## 7 How
57+
- `AddPackage.qml` 基于 `DialogShell``InputField` 构建,提供宏包名称输入、回车提交及 Esc 取消。
58+
- C++ 层 `cpp_add_package_dialog` 通过 `run_qml_dialog` 启动模态对话框,注入已翻译文案,并提供 `MOGAN_TEST_ADD_PACKAGE` 测试钩子。
59+
- Scheme 侧 `open-add-package-dialog` 接收结果后验证包名非空,先调用 `package-exists?` 检测宏包是否存在;存在则触发 `add-style-package`,不存在则调用 `cpp-confirm-question` 弹窗告知用户。
60+
61+
## 8 简化清理(/simplify)
62+
- `QTMQmlDialog.cpp`:启用已有但从未被调用的 `kv_map_to_tree`,替换 form / 搜索最近文档 / 打印到文件 / 增加宏包四处逐键拷贝的 QVariantMap→tree 循环(导出 PDF 走 `from_qstring_utf8`,保持原样);合并 `MOGAN_TEST_ADD_PACKAGE` 钩子 ok 与 `<name>` 两个重复分支。
63+
- `document-style.scm``open-add-package-dialog` 去掉只消费一次的外层 `with result`
64+
- `InputField.qml`:删除无消费者的 `isComposing` 只读属性。

0 commit comments

Comments
 (0)