From ec0ca5a3f6cbed7f9e46a573a137a3188814c849 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 23:12:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(undo):=20=E4=BF=AE=E5=A4=8D=E6=92=A4?= =?UTF-8?q?=E9=94=80=E6=8C=89=E9=92=AE=E7=8A=B6=E6=80=81=E4=B8=8D=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E5=8F=8A=E7=A9=BA=E6=8C=87=E9=92=88=E9=98=B2=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 refresh_undo_redo_buttons 提升为公共函数(声明在 callbacks_internal.h,实现在 callbacks.c) - 在所有 push_record 的操作回调末尾调用 refresh_undo_redo_buttons,确保按钮状态实时更新 - 修复 redo() 中 OP_CLEAN/OP_IMPORT 的 new_paths 空指针风险 - 移除 undo_redo.c 中废弃的 apply_record 函数 Co-Authored-By: Claude Opus 4.7 --- include/controller/callbacks_internal.h | 3 +++ src/controller/callbacks.c | 17 +++++++++++++++++ src/controller/callbacks_basic.c | 7 +++++++ src/controller/callbacks_nav.c | 20 ++++---------------- src/core/undo_redo.c | 17 ++++++----------- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/include/controller/callbacks_internal.h b/include/controller/callbacks_internal.h index 2735b67..1438c6e 100644 --- a/include/controller/callbacks_internal.h +++ b/include/controller/callbacks_internal.h @@ -20,4 +20,7 @@ StringList *get_current_raw_data(Ihandle *dlg); // 获取当前活动的列表 UI 控件 Ihandle *get_current_list(Ihandle *dlg); +// 刷新撤销/重做按钮的启用状态 +void refresh_undo_redo_buttons(Ihandle *dlg); + #endif // CALLBACKS_INTERNAL_H diff --git a/src/controller/callbacks.c b/src/controller/callbacks.c index cafb36e..fc8fa35 100644 --- a/src/controller/callbacks.c +++ b/src/controller/callbacks.c @@ -1,6 +1,7 @@ #include "controller/callbacks.h" #include "controller/callbacks_internal.h" #include "core/app_context.h" +#include "core/undo_redo.h" #include "utils/ui_constants.h" #include @@ -45,3 +46,19 @@ Ihandle *get_current_list(Ihandle *dlg) return IupGetDialogChild(dlg, CTRL_LIST_USER); return IupGetDialogChild(dlg, CTRL_LIST_SYS); } + +// 刷新撤销/重做按钮的启用状态 +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"); +} diff --git a/src/controller/callbacks_basic.c b/src/controller/callbacks_basic.c index f09db6d..9bc40cd 100644 --- a/src/controller/callbacks_basic.c +++ b/src/controller/callbacks_basic.c @@ -76,6 +76,8 @@ int btn_new_cb(Ihandle *self) int count = IupGetInt(current_list, "COUNT"); IupSetInt(current_list, "VALUE", count); + + refresh_undo_redo_buttons(dlg); } } return IUP_DEFAULT; @@ -114,6 +116,8 @@ int btn_edit_cb(Ihandle *self) sync_string_list_to_ui(current_list, raw_data); IupSetInt(current_list, "VALUE", selected); + + refresh_undo_redo_buttons(dlg); } } return IUP_DEFAULT; @@ -168,6 +172,8 @@ int btn_browse_cb(Ihandle *self) int count = IupGetInt(current_list, "COUNT"); IupSetInt(current_list, "VALUE", count); + + refresh_undo_redo_buttons(dlg); } } IupDestroy(filedlg); @@ -208,5 +214,6 @@ int btn_del_cb(Ihandle *self) if (lbl_status) IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "deleted")); + refresh_undo_redo_buttons(dlg); return IUP_DEFAULT; } diff --git a/src/controller/callbacks_nav.c b/src/controller/callbacks_nav.c index a4c43d8..6f7cfd0 100644 --- a/src/controller/callbacks_nav.c +++ b/src/controller/callbacks_nav.c @@ -71,6 +71,7 @@ int btn_up_cb(Ihandle *self) sync_string_list_to_ui(current_list, raw_data); IupSetInt(current_list, "VALUE", selected - 1); + refresh_undo_redo_buttons(dlg); return IUP_DEFAULT; } @@ -104,6 +105,7 @@ int btn_down_cb(Ihandle *self) sync_string_list_to_ui(current_list, raw_data); IupSetInt(current_list, "VALUE", selected + 1); + refresh_undo_redo_buttons(dlg); return IUP_DEFAULT; } @@ -142,25 +144,11 @@ int btn_clean_cb(Ihandle *self) char msg[128]; snprintf(msg, sizeof(msg), _("Cleanup completed! Removed %d invalid or duplicate paths."), removed); IupMessage(_("Info"), msg); + + refresh_undo_redo_buttons(dlg); 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); diff --git a/src/core/undo_redo.c b/src/core/undo_redo.c index 3d69796..686b4b8 100644 --- a/src/core/undo_redo.c +++ b/src/core/undo_redo.c @@ -128,14 +128,6 @@ int push_undo_record(UndoRedoManager *mgr, const OpRecord *record) return 0; } -static void apply_record(UndoRedoManager *mgr, int record_index, int is_undo) -{ - (void)mgr; - (void)record_index; - (void)is_undo; - // 此函数已废弃,撤销/重做逻辑在 undo() 和 redo() 中直接实现 -} - int undo(UndoRedoManager *mgr, StringList *sys_paths, StringList *user_paths) { if (!mgr || !can_undo(mgr)) @@ -268,10 +260,13 @@ int redo(UndoRedoManager *mgr, StringList *sys_paths, StringList *user_paths) case OP_IMPORT: // 重做清理/导入:应用新列表 clear_string_list(target); - for (int i = 0; i < rec->count; i++) + if (rec->new_paths) { - if (rec->new_paths[i]) - add_string_list(target, rec->new_paths[i]); + for (int i = 0; i < rec->count; i++) + { + if (rec->new_paths[i]) + add_string_list(target, rec->new_paths[i]); + } } break;