From f9628f6e8ca416e12eb2d80e5b2cc0956eb7f323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Fri, 1 May 2026 22:50:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(undo):=20=E5=AE=9E=E7=8E=B0=E6=92=A4?= =?UTF-8?q?=E9=94=80/=E9=87=8D=E5=81=9A=E6=8C=89=E9=92=AE=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=8F=8A=20Ctrl+Z/Y=20=E5=BF=AB=E6=8D=B7=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- src/controller/callbacks_nav.c | 84 ++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/src/controller/callbacks_nav.c b/src/controller/callbacks_nav.c index 69d5d50..a4c43d8 100644 --- a/src/controller/callbacks_nav.c +++ b/src/controller/callbacks_nav.c @@ -145,17 +145,91 @@ int btn_clean_cb(Ihandle *self) return IUP_DEFAULT; } +// 刷新撤销/重做按钮的启用状态 +static void refresh_undo_redo_buttons(Ihandle *dlg) +{ + AppContext *ctx = get_app_context_from_dlg(dlg); + if (!ctx || !ctx->undo_redo_mgr) + return; + + Ihandle *btn_undo = IupGetDialogChild(dlg, CTRL_BTN_UNDO); + Ihandle *btn_redo = IupGetDialogChild(dlg, CTRL_BTN_REDO); + + if (btn_undo) + IupSetAttribute(btn_undo, "ACTIVE", can_undo(ctx->undo_redo_mgr) ? "YES" : "NO"); + if (btn_redo) + IupSetAttribute(btn_redo, "ACTIVE", can_redo(ctx->undo_redo_mgr) ? "YES" : "NO"); +} + +int btn_undo_cb(Ihandle *self) +{ + Ihandle *dlg = IupGetDialog(self); + AppContext *ctx = get_app_context_from_dlg(dlg); + if (!ctx || !ctx->undo_redo_mgr) + return IUP_DEFAULT; + + if (!can_undo(ctx->undo_redo_mgr)) + return IUP_DEFAULT; + + undo(ctx->undo_redo_mgr, &ctx->sys_paths, &ctx->user_paths); + + Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS); + Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER); + sync_string_list_to_ui(list_sys, &ctx->sys_paths); + sync_string_list_to_ui(list_user, &ctx->user_paths); + + Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS); + if (lbl_status) + IupSetAttribute(lbl_status, "TITLE", _("Undo completed")); + + refresh_undo_redo_buttons(dlg); + return IUP_DEFAULT; +} + +int btn_redo_cb(Ihandle *self) +{ + Ihandle *dlg = IupGetDialog(self); + AppContext *ctx = get_app_context_from_dlg(dlg); + if (!ctx || !ctx->undo_redo_mgr) + return IUP_DEFAULT; + + if (!can_redo(ctx->undo_redo_mgr)) + return IUP_DEFAULT; + + redo(ctx->undo_redo_mgr, &ctx->sys_paths, &ctx->user_paths); + + Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS); + Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER); + sync_string_list_to_ui(list_sys, &ctx->sys_paths); + sync_string_list_to_ui(list_user, &ctx->user_paths); + + Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS); + if (lbl_status) + IupSetAttribute(lbl_status, "TITLE", _("Redo completed")); + + refresh_undo_redo_buttons(dlg); + return IUP_DEFAULT; +} + // 键盘按键回调 int list_k_any_cb(Ihandle *self, int c) { - (void)c; // 暂时禁用键盘快捷键,避免兼容性问题 - // TODO: 实现 Ctrl+Z 撤销 / Ctrl+Y 重做的键盘快捷键 - // 需要根据具体 IUP 版本选择合适的方式检测 Ctrl 组合键 - if (IupGetInt(self, "ACTIVE") == 0) return IUP_DEFAULT; - if (IupGetInt(self, "K_DEL") == 1) // DEL 键 + if (c == K_cZ) // Ctrl+Z 撤销 + { + btn_undo_cb(self); + return IUP_IGNORE; + } + + if (c == K_cY) // Ctrl+Y 重做 + { + btn_redo_cb(self); + return IUP_IGNORE; + } + + if (c == K_DEL) // DEL 键 { btn_del_cb(self); return IUP_IGNORE;