mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-05-09 18:02:52 +08:00
refactor(controller): 拆分回调函数到模块化文件并添加字符串列表访问器
- 将 callbacks.c 拆分为多个按功能分类的文件(callbacks_basic.c、callbacks_nav.c、callbacks_search.c、callbacks_io.c、callbacks_sys.c) - 新增 callbacks_internal.h 提供内部辅助函数声明,减少代码重复 - 在 string_ext 模块中添加 string_list_get 和 string_list_set 安全访问器函数 - 更新 CMakeLists.txt 和 ui_utils.c 以使用新的模块结构和访问器 - 重构旨在提高代码可维护性和可读性,便于后续功能扩展
This commit is contained in:
@@ -27,6 +27,11 @@ set(SOURCES
|
||||
src/core/lua_config.c
|
||||
src/core/import_export.c
|
||||
src/controller/callbacks.c
|
||||
src/controller/callbacks_basic.c
|
||||
src/controller/callbacks_nav.c
|
||||
src/controller/callbacks_search.c
|
||||
src/controller/callbacks_io.c
|
||||
src/controller/callbacks_sys.c
|
||||
ico/resources.rc
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CALLBACKS_INTERNAL_H
|
||||
#define CALLBACKS_INTERNAL_H
|
||||
|
||||
#include <iup.h>
|
||||
#include "core/app_context.h"
|
||||
|
||||
// 内部辅助函数声明(供各 callbacks_*.c 文件共享)
|
||||
// 这些函数不对外暴露,仅在 controller 层内部使用
|
||||
|
||||
// 获取主对话框句柄
|
||||
Ihandle *get_main_dlg(void);
|
||||
|
||||
// 从对话框获取应用上下文
|
||||
AppContext *get_app_context_from_dlg(Ihandle *dlg);
|
||||
|
||||
// 获取当前活动的数据列表(根据 Tab 页切换)
|
||||
StringList *get_current_raw_data(Ihandle *dlg);
|
||||
|
||||
// 获取当前活动的列表 UI 控件
|
||||
Ihandle *get_current_list(Ihandle *dlg);
|
||||
|
||||
#endif // CALLBACKS_INTERNAL_H
|
||||
@@ -16,6 +16,12 @@ void init_string_list(StringList *list);
|
||||
void add_string_list(StringList *list, const char *str);
|
||||
void clear_string_list(StringList *list);
|
||||
|
||||
// 访问器函数 - 安全访问内部数据
|
||||
// 获取指定索引的字符串(只读),越界返回 NULL
|
||||
const char *string_list_get(const StringList *list, int index);
|
||||
// 设置指定索引的字符串(会复制新字符串并释放旧字符串),越界返回 -1,成功返回 0
|
||||
int string_list_set(StringList *list, int index, const char *str);
|
||||
|
||||
// 字符串转换函数
|
||||
char *wide_to_utf8(const wchar_t *wstr);
|
||||
wchar_t *utf8_to_wide(const char *str);
|
||||
|
||||
+6
-576
@@ -1,32 +1,17 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/app_context.h"
|
||||
#include "core/registry_service.h"
|
||||
#include "core/path_manager.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "core/import_export.h"
|
||||
#include "utils/string_ext.h"
|
||||
#include "utils/os_env.h"
|
||||
#include "utils/error_code.h"
|
||||
#include "utils/safe_string.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/i18n.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include "ui/dialogs.h"
|
||||
#include "ui/main_window.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <iup.h>
|
||||
|
||||
// 辅助函数:获取主对话框
|
||||
static Ihandle *get_main_dlg()
|
||||
Ihandle *get_main_dlg(void)
|
||||
{
|
||||
return IupGetHandle("MAIN_DIALOG");
|
||||
}
|
||||
|
||||
// 辅助函数:从对话框获取应用上下文(core层不依赖IUP,因此在此实现)
|
||||
static AppContext *get_app_context_from_dlg(Ihandle *dlg)
|
||||
AppContext *get_app_context_from_dlg(Ihandle *dlg)
|
||||
{
|
||||
if (!dlg)
|
||||
return NULL;
|
||||
@@ -34,7 +19,7 @@ static AppContext *get_app_context_from_dlg(Ihandle *dlg)
|
||||
}
|
||||
|
||||
// 获取当前的缓存数据列表
|
||||
static StringList *get_current_raw_data(Ihandle *dlg)
|
||||
StringList *get_current_raw_data(Ihandle *dlg)
|
||||
{
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
@@ -50,7 +35,7 @@ static StringList *get_current_raw_data(Ihandle *dlg)
|
||||
}
|
||||
|
||||
// 辅助函数:获取当前选中的列表UI控件
|
||||
static Ihandle *get_current_list(Ihandle *dlg)
|
||||
Ihandle *get_current_list(Ihandle *dlg)
|
||||
{
|
||||
Ihandle *tabs_main = IupGetDialogChild(dlg, CTRL_TABS_MAIN);
|
||||
int pos = IupGetInt(tabs_main, "VALUEPOS");
|
||||
@@ -60,558 +45,3 @@ static Ihandle *get_current_list(Ihandle *dlg)
|
||||
return IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
return IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
}
|
||||
|
||||
// 按钮回调:新建
|
||||
int btn_new_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
char buffer[PATH_BUFFER_SIZE] = "";
|
||||
if (custom_input_dialog("新建环境变量", "请输入路径:", buffer, sizeof(buffer)))
|
||||
{
|
||||
if (strlen(buffer) > 0)
|
||||
{
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
add_string_list(raw_data, buffer);
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
int count = IupGetInt(current_list, "COUNT");
|
||||
IupSetInt(current_list, "VALUE", count);
|
||||
}
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:编辑
|
||||
int btn_edit_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
if (selected == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
if (selected - 1 >= raw_data->count)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
char buffer[PATH_BUFFER_SIZE];
|
||||
safe_strcpy(buffer, sizeof(buffer), raw_data->items[selected - 1]);
|
||||
|
||||
if (custom_input_dialog("编辑环境变量", "编辑路径:", buffer, sizeof(buffer)))
|
||||
{
|
||||
if (strlen(buffer) > 0)
|
||||
{
|
||||
free(raw_data->items[selected - 1]);
|
||||
raw_data->items[selected - 1] = _strdup(buffer);
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected);
|
||||
}
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 双击回调
|
||||
int list_dblclick_cb(Ihandle *self, int item, char *text)
|
||||
{
|
||||
if (item > 0)
|
||||
{
|
||||
IupSetInt(self, "VALUE", item);
|
||||
btn_edit_cb(self);
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:浏览
|
||||
int btn_browse_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "DIR");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("dialog", "select_dir"));
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *value = IupGetAttribute(filedlg, "VALUE");
|
||||
if (value)
|
||||
{
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
add_string_list(raw_data, value);
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
int count = IupGetInt(current_list, "COUNT");
|
||||
IupSetInt(current_list, "VALUE", count);
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:删除
|
||||
int btn_del_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
|
||||
if (selected == 0)
|
||||
{
|
||||
IupMessage("提示", "请先选择要删除的项");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
ErrorCode result = path_manager_remove_at(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to remove path at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "deleted"));
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:上移
|
||||
int btn_up_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
if (selected <= 1)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
ErrorCode result = path_manager_move_up(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to move path up at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected - 1);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:下移
|
||||
int btn_down_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
|
||||
if (selected == 0 || selected >= raw_data->count)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
ErrorCode result = path_manager_move_down(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to move path down at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected + 1);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:一键清理
|
||||
int btn_clean_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
if (!raw_data || raw_data->count == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (IupAlarm("确认清理", "此操作将移除当前列表中所有【无效路径】和【重复路径】。\n确定要继续吗?", "确定", "取消", NULL) != 1)
|
||||
{
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
int before_count = raw_data->count;
|
||||
path_manager_clean(raw_data);
|
||||
int removed = before_count - raw_data->count;
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
char msg[128];
|
||||
snprintf(msg, sizeof(msg), "清理完成!共移除了 %d 个无效或重复路径。", removed);
|
||||
IupMessage("提示", msg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 搜索回调
|
||||
int txt_search_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
char *filter = IupGetAttribute(self, "VALUE");
|
||||
if (!filter)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
|
||||
IupSetAttribute(current_list, "REMOVEITEM", "ALL");
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < raw_data->count; i++)
|
||||
{
|
||||
if (strlen(filter) == 0 || stristr(raw_data->items[i], filter) != NULL)
|
||||
{
|
||||
count++;
|
||||
IupSetAttributeId(current_list, "", count, raw_data->items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
IupSetInt(current_list, "COUNT", count);
|
||||
refresh_single_list_style(current_list);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 拖拽回调
|
||||
int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = self;
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = NULL;
|
||||
if (self == IupGetDialogChild(dlg, CTRL_LIST_SYS))
|
||||
raw_data = &ctx->sys_paths;
|
||||
else if (self == IupGetDialogChild(dlg, CTRL_LIST_USER))
|
||||
raw_data = &ctx->user_paths;
|
||||
else
|
||||
return IUP_DEFAULT;
|
||||
|
||||
DWORD attr = GetFileAttributesA(filename);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
Ihandle *txt_search = IupGetDialogChild(dlg, CTRL_TXT_SEARCH);
|
||||
if (txt_search)
|
||||
IupSetAttribute(txt_search, "VALUE", "");
|
||||
|
||||
add_string_list(raw_data, filename);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
IupSetInt(current_list, "VALUE", raw_data->count);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "drag_folder_only"));
|
||||
}
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 键盘按键回调
|
||||
int list_k_any_cb(Ihandle *self, int c)
|
||||
{
|
||||
if (c == K_DEL)
|
||||
{
|
||||
btn_del_cb(self);
|
||||
return IUP_IGNORE;
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:确定 (保存所有)
|
||||
int btn_ok_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (!check_admin())
|
||||
{
|
||||
IupMessage("错误", "需要管理员权限才能保存更改!");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
backup_registry();
|
||||
|
||||
ErrorCode sys_ok = save_system_paths(&ctx->sys_paths);
|
||||
ErrorCode user_ok = save_user_paths(&ctx->user_paths);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
|
||||
if (sys_ok == ERR_OK && user_ok == ERR_OK)
|
||||
{
|
||||
log_info("Saved system paths: %d, user paths: %d", ctx->sys_paths.count, ctx->user_paths.count);
|
||||
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, NULL);
|
||||
IupMessage("成功", "系统和用户 PATH 环境变量均已更新!");
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "saved"));
|
||||
}
|
||||
else if (sys_ok == ERR_OK)
|
||||
{
|
||||
IupMessage("提示", "系统变量保存成功,但用户变量保存失败。");
|
||||
}
|
||||
else if (user_ok == ERR_OK)
|
||||
{
|
||||
IupMessage("提示", "用户变量保存成功,但系统变量保存失败。");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Failed to save paths: sys=%d, user=%d", sys_ok, user_ok);
|
||||
IupMessage("错误", "保存失败!");
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "error"));
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:取消
|
||||
int btn_cancel_cb(Ihandle *self)
|
||||
{
|
||||
IupExitLoop();
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:导入
|
||||
int btn_import_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (!check_admin())
|
||||
{
|
||||
IupMessage("错误", "需要管理员权限才能导入 PATH!");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "OPEN");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("label", "import_title"));
|
||||
IupSetAttribute(filedlg, "FILTER", "json");
|
||||
IupSetAttribute(filedlg, "EXTFILTER", "JSON 文件 (*.json)|*.json|文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*");
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *filepath = IupGetAttribute(filedlg, "VALUE");
|
||||
if (filepath)
|
||||
{
|
||||
ExportData imported;
|
||||
ErrorCode import_result = import_paths_from_file(filepath, &imported);
|
||||
if (import_result == ERR_OK)
|
||||
{
|
||||
int has_system = imported.system.count > 0;
|
||||
int has_user = imported.user.count > 0;
|
||||
|
||||
if (!has_system && !has_user)
|
||||
{
|
||||
IupMessage("错误", "文件中没有找到有效的路径!");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
int choice = 0;
|
||||
if (has_system && has_user)
|
||||
{
|
||||
choice = IupAlarm("导入选项", "请选择导入目标:",
|
||||
"仅系统变量", "仅用户变量", "全部导入");
|
||||
}
|
||||
else if (has_system)
|
||||
{
|
||||
choice = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
choice = 2;
|
||||
}
|
||||
|
||||
int total_imported = 0;
|
||||
|
||||
if (choice == 1 || choice == 3)
|
||||
{
|
||||
clear_string_list(&ctx->sys_paths);
|
||||
for (int i = 0; i < imported.system.count; i++)
|
||||
{
|
||||
add_string_list(&ctx->sys_paths, imported.system.items[i]);
|
||||
}
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
sync_string_list_to_ui(list_sys, &ctx->sys_paths);
|
||||
total_imported += imported.system.count;
|
||||
}
|
||||
|
||||
if (choice == 2 || choice == 3)
|
||||
{
|
||||
clear_string_list(&ctx->user_paths);
|
||||
for (int i = 0; i < imported.user.count; i++)
|
||||
{
|
||||
add_string_list(&ctx->user_paths, imported.user.items[i]);
|
||||
}
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
sync_string_list_to_ui(list_user, &ctx->user_paths);
|
||||
total_imported += imported.user.count;
|
||||
}
|
||||
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "成功导入 %d 个路径!", total_imported);
|
||||
IupMessage("导入成功", msg);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Import failed: error code %d", import_result);
|
||||
IupMessage("错误", "导入失败,请检查文件格式是否正确!");
|
||||
}
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:导出
|
||||
int btn_export_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
ExportData data;
|
||||
data.system = ctx->sys_paths;
|
||||
data.user = ctx->user_paths;
|
||||
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "SAVE");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("label", "export_title"));
|
||||
IupSetAttribute(filedlg, "FILTER", "json");
|
||||
IupSetAttribute(filedlg, "EXTFILTER", "JSON 文件 (*.json)|*.json");
|
||||
IupSetAttribute(filedlg, "DEFAULTEXT", "json");
|
||||
|
||||
char default_name[64];
|
||||
snprintf(default_name, sizeof(default_name), "path_all.json");
|
||||
IupSetAttribute(filedlg, "VALUE", default_name);
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *filepath = IupGetAttribute(filedlg, "VALUE");
|
||||
if (filepath)
|
||||
{
|
||||
char final_path[MAX_PATH];
|
||||
if (strchr(filepath, '.') == NULL)
|
||||
{
|
||||
snprintf(final_path, sizeof(final_path), "%s.json", filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
safe_strcpy(final_path, sizeof(final_path), filepath);
|
||||
}
|
||||
filepath = final_path;
|
||||
|
||||
ErrorCode export_result = export_paths_to_file(&data, filepath);
|
||||
if (export_result == ERR_OK)
|
||||
{
|
||||
char msg[512];
|
||||
snprintf(msg, sizeof(msg), "成功导出!\n系统变量: %d 个\n用户变量: %d 个\n\n保存位置: %s",
|
||||
data.system.count, data.user.count, filepath);
|
||||
IupMessage("导出成功", msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Export failed: error code %d", export_result);
|
||||
IupMessage("错误", "导出失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 载入所有路径
|
||||
void load_all_paths(void)
|
||||
{
|
||||
Ihandle *dlg = get_main_dlg();
|
||||
if (!dlg)
|
||||
return;
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (load_system_paths(&ctx->sys_paths) != ERR_OK)
|
||||
{
|
||||
log_error("Failed to load system paths");
|
||||
IupMessage("错误", "无法打开系统环境变量注册表键,请尝试以管理员身份运行。");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("Loaded system paths: %d", ctx->sys_paths.count);
|
||||
}
|
||||
|
||||
ErrorCode user_result = load_user_paths(&ctx->user_paths);
|
||||
if (user_result == ERR_OK)
|
||||
{
|
||||
log_info("Loaded user paths: %d", ctx->user_paths.count);
|
||||
}
|
||||
|
||||
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", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
|
||||
// 按钮回调:语言切换
|
||||
int btn_lang_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
language_select_dialog();
|
||||
refresh_main_window_ui(dlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:帮助
|
||||
int btn_help_cb(Ihandle *self)
|
||||
{
|
||||
IupMessage("使用说明",
|
||||
"1. 本程序用于编辑系统环境变量 PATH。\n"
|
||||
"2. 必须以【管理员身份】运行才能保存更改。\n"
|
||||
"3. 操作说明:\n"
|
||||
" - 新建:添加新路径到列表末尾。\n"
|
||||
" - 编辑:修改选中的路径。\n"
|
||||
" - 浏览:从文件系统选择目录添加。\n"
|
||||
" - 删除:移除选中的路径。\n"
|
||||
" - 上移/下移:调整路径优先级。\n"
|
||||
" - 导入/导出:备份和恢复 PATH 配置。\n"
|
||||
"4. 点击【确定】保存更改并生效。\n"
|
||||
"5. 注意:某些正在运行的程序可能需要重启才能识别新的环境变量。\n\n"
|
||||
"--------------------------------------------------\n"
|
||||
"作者:LHY\n"
|
||||
"邮箱:3364451258@qq.com\n"
|
||||
"GitHub:https://github.com/LHY0125/PathEditor\n"
|
||||
"记得给我的项目点个star!");
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/path_manager.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/string_ext.h"
|
||||
#include "utils/safe_string.h"
|
||||
#include "utils/error_code.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include "ui/dialogs.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 按钮回调:新建
|
||||
int btn_new_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
char buffer[PATH_BUFFER_SIZE] = "";
|
||||
if (custom_input_dialog("新建环境变量", "请输入路径:", buffer, sizeof(buffer)))
|
||||
{
|
||||
if (strlen(buffer) > 0)
|
||||
{
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
add_string_list(raw_data, buffer);
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
int count = IupGetInt(current_list, "COUNT");
|
||||
IupSetInt(current_list, "VALUE", count);
|
||||
}
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:编辑
|
||||
int btn_edit_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
if (selected == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
if (selected - 1 >= raw_data->count)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
char buffer[PATH_BUFFER_SIZE];
|
||||
safe_strcpy(buffer, sizeof(buffer), string_list_get(raw_data, selected - 1));
|
||||
|
||||
if (custom_input_dialog("编辑环境变量", "编辑路径:", buffer, sizeof(buffer)))
|
||||
{
|
||||
if (strlen(buffer) > 0)
|
||||
{
|
||||
string_list_set(raw_data, selected - 1, buffer);
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected);
|
||||
}
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 双击回调
|
||||
int list_dblclick_cb(Ihandle *self, int item, char *text)
|
||||
{
|
||||
if (item > 0)
|
||||
{
|
||||
IupSetInt(self, "VALUE", item);
|
||||
btn_edit_cb(self);
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:浏览
|
||||
int btn_browse_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "DIR");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("dialog", "select_dir"));
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *value = IupGetAttribute(filedlg, "VALUE");
|
||||
if (value)
|
||||
{
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
add_string_list(raw_data, value);
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
int count = IupGetInt(current_list, "COUNT");
|
||||
IupSetInt(current_list, "VALUE", count);
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:删除
|
||||
int btn_del_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
|
||||
if (selected == 0)
|
||||
{
|
||||
IupMessage("提示", "请先选择要删除的项");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
ErrorCode result = path_manager_remove_at(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to remove path at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "deleted"));
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/app_context.h"
|
||||
#include "core/import_export.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/string_ext.h"
|
||||
#include "utils/safe_string.h"
|
||||
#include "utils/error_code.h"
|
||||
#include "utils/os_env.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
// 按钮回调:导入
|
||||
int btn_import_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (!check_admin())
|
||||
{
|
||||
IupMessage("错误", "需要管理员权限才能导入 PATH!");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "OPEN");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("label", "import_title"));
|
||||
IupSetAttribute(filedlg, "FILTER", "json");
|
||||
IupSetAttribute(filedlg, "EXTFILTER", "JSON 文件 (*.json)|*.json|文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*");
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *filepath = IupGetAttribute(filedlg, "VALUE");
|
||||
if (filepath)
|
||||
{
|
||||
ExportData imported;
|
||||
ErrorCode import_result = import_paths_from_file(filepath, &imported);
|
||||
if (import_result == ERR_OK)
|
||||
{
|
||||
int has_system = imported.system.count > 0;
|
||||
int has_user = imported.user.count > 0;
|
||||
|
||||
if (!has_system && !has_user)
|
||||
{
|
||||
IupMessage("错误", "文件中没有找到有效的路径!");
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
int choice = 0;
|
||||
if (has_system && has_user)
|
||||
{
|
||||
choice = IupAlarm("导入选项", "请选择导入目标:",
|
||||
"仅系统变量", "仅用户变量", "全部导入");
|
||||
}
|
||||
else if (has_system)
|
||||
{
|
||||
choice = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
choice = 2;
|
||||
}
|
||||
|
||||
int total_imported = 0;
|
||||
|
||||
if (choice == 1 || choice == 3)
|
||||
{
|
||||
clear_string_list(&ctx->sys_paths);
|
||||
for (int i = 0; i < imported.system.count; i++)
|
||||
{
|
||||
add_string_list(&ctx->sys_paths, imported.system.items[i]);
|
||||
}
|
||||
Ihandle *list_sys = IupGetDialogChild(dlg, CTRL_LIST_SYS);
|
||||
sync_string_list_to_ui(list_sys, &ctx->sys_paths);
|
||||
total_imported += imported.system.count;
|
||||
}
|
||||
|
||||
if (choice == 2 || choice == 3)
|
||||
{
|
||||
clear_string_list(&ctx->user_paths);
|
||||
for (int i = 0; i < imported.user.count; i++)
|
||||
{
|
||||
add_string_list(&ctx->user_paths, imported.user.items[i]);
|
||||
}
|
||||
Ihandle *list_user = IupGetDialogChild(dlg, CTRL_LIST_USER);
|
||||
sync_string_list_to_ui(list_user, &ctx->user_paths);
|
||||
total_imported += imported.user.count;
|
||||
}
|
||||
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "成功导入 %d 个路径!", total_imported);
|
||||
IupMessage("导入成功", msg);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Import failed: error code %d", import_result);
|
||||
IupMessage("错误", "导入失败,请检查文件格式是否正确!");
|
||||
}
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:导出
|
||||
int btn_export_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
ExportData data;
|
||||
data.system = ctx->sys_paths;
|
||||
data.user = ctx->user_paths;
|
||||
|
||||
Ihandle *filedlg = IupFileDlg();
|
||||
IupSetAttribute(filedlg, "DIALOGTYPE", "SAVE");
|
||||
IupSetAttribute(filedlg, "TITLE", lua_config_get_string("label", "export_title"));
|
||||
IupSetAttribute(filedlg, "FILTER", "json");
|
||||
IupSetAttribute(filedlg, "EXTFILTER", "JSON 文件 (*.json)|*.json");
|
||||
IupSetAttribute(filedlg, "DEFAULTEXT", "json");
|
||||
|
||||
char default_name[64];
|
||||
snprintf(default_name, sizeof(default_name), "path_all.json");
|
||||
IupSetAttribute(filedlg, "VALUE", default_name);
|
||||
|
||||
IupPopup(filedlg, IUP_CENTER, IUP_CENTER);
|
||||
|
||||
if (IupGetInt(filedlg, "STATUS") != -1)
|
||||
{
|
||||
char *filepath = IupGetAttribute(filedlg, "VALUE");
|
||||
if (filepath)
|
||||
{
|
||||
char final_path[MAX_PATH];
|
||||
if (strchr(filepath, '.') == NULL)
|
||||
{
|
||||
snprintf(final_path, sizeof(final_path), "%s.json", filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
safe_strcpy(final_path, sizeof(final_path), filepath);
|
||||
}
|
||||
filepath = final_path;
|
||||
|
||||
ErrorCode export_result = export_paths_to_file(&data, filepath);
|
||||
if (export_result == ERR_OK)
|
||||
{
|
||||
char msg[512];
|
||||
snprintf(msg, sizeof(msg), "成功导出!\n系统变量: %d 个\n用户变量: %d 个\n\n保存位置: %s",
|
||||
data.system.count, data.user.count, filepath);
|
||||
IupMessage("导出成功", msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Export failed: error code %d", export_result);
|
||||
IupMessage("错误", "导出失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
IupDestroy(filedlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/path_manager.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/error_code.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// 按钮回调:上移
|
||||
int btn_up_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
if (selected <= 1)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
ErrorCode result = path_manager_move_up(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to move path up at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected - 1);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:下移
|
||||
int btn_down_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
int selected = IupGetInt(current_list, "VALUE");
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
|
||||
if (selected == 0 || selected >= raw_data->count)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
ErrorCode result = path_manager_move_down(raw_data, selected - 1);
|
||||
if (result != ERR_OK)
|
||||
{
|
||||
log_error("Failed to move path down at index %d", selected - 1);
|
||||
}
|
||||
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
IupSetInt(current_list, "VALUE", selected + 1);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:一键清理
|
||||
int btn_clean_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
if (!raw_data || raw_data->count == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (IupAlarm("确认清理", "此操作将移除当前列表中所有【无效路径】和【重复路径】。\n确定要继续吗?", "确定", "取消", NULL) != 1)
|
||||
{
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
int before_count = raw_data->count;
|
||||
path_manager_clean(raw_data);
|
||||
int removed = before_count - raw_data->count;
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
char msg[128];
|
||||
snprintf(msg, sizeof(msg), "清理完成!共移除了 %d 个无效或重复路径。", removed);
|
||||
IupMessage("提示", msg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 键盘按键回调
|
||||
int list_k_any_cb(Ihandle *self, int c)
|
||||
{
|
||||
if (c == K_DEL)
|
||||
{
|
||||
btn_del_cb(self);
|
||||
return IUP_IGNORE;
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/app_context.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/string_ext.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
// 搜索回调
|
||||
int txt_search_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
char *filter = IupGetAttribute(self, "VALUE");
|
||||
if (!filter)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
Ihandle *current_list = get_current_list(dlg);
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
|
||||
IupSetAttribute(current_list, "REMOVEITEM", "ALL");
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < raw_data->count; i++)
|
||||
{
|
||||
const char *item = string_list_get(raw_data, i);
|
||||
if (strlen(filter) == 0 || stristr(item, filter) != NULL)
|
||||
{
|
||||
count++;
|
||||
IupSetAttributeId(current_list, "", count, item);
|
||||
}
|
||||
}
|
||||
|
||||
IupSetInt(current_list, "COUNT", count);
|
||||
refresh_single_list_style(current_list);
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 拖拽回调
|
||||
int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
Ihandle *current_list = self;
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
StringList *raw_data = NULL;
|
||||
if (self == IupGetDialogChild(dlg, CTRL_LIST_SYS))
|
||||
raw_data = &ctx->sys_paths;
|
||||
else if (self == IupGetDialogChild(dlg, CTRL_LIST_USER))
|
||||
raw_data = &ctx->user_paths;
|
||||
else
|
||||
return IUP_DEFAULT;
|
||||
|
||||
DWORD attr = GetFileAttributesA(filename);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
Ihandle *txt_search = IupGetDialogChild(dlg, CTRL_TXT_SEARCH);
|
||||
if (txt_search)
|
||||
IupSetAttribute(txt_search, "VALUE", "");
|
||||
|
||||
add_string_list(raw_data, filename);
|
||||
sync_string_list_to_ui(current_list, raw_data);
|
||||
|
||||
IupSetInt(current_list, "VALUE", raw_data->count);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "drag_folder_only"));
|
||||
}
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/app_context.h"
|
||||
#include "core/registry_service.h"
|
||||
#include "core/lua_config.h"
|
||||
#include "utils/error_code.h"
|
||||
#include "utils/os_env.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/i18n.h"
|
||||
#include "utils/ui_constants.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include "ui/dialogs.h"
|
||||
#include "ui/main_window.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
// 按钮回调:确定 (保存所有)
|
||||
int btn_ok_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
if (!check_admin())
|
||||
{
|
||||
IupMessage("错误", "需要管理员权限才能保存更改!");
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
backup_registry();
|
||||
|
||||
ErrorCode sys_ok = save_system_paths(&ctx->sys_paths);
|
||||
ErrorCode user_ok = save_user_paths(&ctx->user_paths);
|
||||
|
||||
Ihandle *lbl_status = IupGetDialogChild(dlg, CTRL_LBL_STATUS);
|
||||
|
||||
if (sys_ok == ERR_OK && user_ok == ERR_OK)
|
||||
{
|
||||
log_info("Saved system paths: %d, user paths: %d", ctx->sys_paths.count, ctx->user_paths.count);
|
||||
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, NULL);
|
||||
IupMessage("成功", "系统和用户 PATH 环境变量均已更新!");
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "saved"));
|
||||
}
|
||||
else if (sys_ok == ERR_OK)
|
||||
{
|
||||
IupMessage("提示", "系统变量保存成功,但用户变量保存失败。");
|
||||
}
|
||||
else if (user_ok == ERR_OK)
|
||||
{
|
||||
IupMessage("提示", "用户变量保存成功,但系统变量保存失败。");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("Failed to save paths: sys=%d, user=%d", sys_ok, user_ok);
|
||||
IupMessage("错误", "保存失败!");
|
||||
if (lbl_status)
|
||||
IupSetAttribute(lbl_status, "TITLE", lua_config_get_string("status", "error"));
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:取消
|
||||
int btn_cancel_cb(Ihandle *self)
|
||||
{
|
||||
IupExitLoop();
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 载入所有路径
|
||||
void load_all_paths(void)
|
||||
{
|
||||
Ihandle *dlg = get_main_dlg();
|
||||
if (!dlg)
|
||||
return;
|
||||
AppContext *ctx = get_app_context_from_dlg(dlg);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (load_system_paths(&ctx->sys_paths) != ERR_OK)
|
||||
{
|
||||
log_error("Failed to load system paths");
|
||||
IupMessage("错误", "无法打开系统环境变量注册表键,请尝试以管理员身份运行。");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("Loaded system paths: %d", ctx->sys_paths.count);
|
||||
}
|
||||
|
||||
ErrorCode user_result = load_user_paths(&ctx->user_paths);
|
||||
if (user_result == ERR_OK)
|
||||
{
|
||||
log_info("Loaded user paths: %d", ctx->user_paths.count);
|
||||
}
|
||||
|
||||
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", lua_config_get_string("status", "loaded"));
|
||||
}
|
||||
|
||||
// 按钮回调:语言切换
|
||||
int btn_lang_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
language_select_dialog();
|
||||
refresh_main_window_ui(dlg);
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 按钮回调:帮助
|
||||
int btn_help_cb(Ihandle *self)
|
||||
{
|
||||
IupMessage("使用说明",
|
||||
"1. 本程序用于编辑系统环境变量 PATH。\n"
|
||||
"2. 必须以【管理员身份】运行才能保存更改。\n"
|
||||
"3. 操作说明:\n"
|
||||
" - 新建:添加新路径到列表末尾。\n"
|
||||
" - 编辑:修改选中的路径。\n"
|
||||
" - 浏览:从文件系统选择目录添加。\n"
|
||||
" - 删除:移除选中的路径。\n"
|
||||
" - 上移/下移:调整路径优先级。\n"
|
||||
" - 导入/导出:备份和恢复 PATH 配置。\n"
|
||||
"4. 点击【确定】保存更改并生效。\n"
|
||||
"5. 注意:某些正在运行的程序可能需要重启才能识别新的环境变量。\n\n"
|
||||
"--------------------------------------------------\n"
|
||||
"作者:LHY\n"
|
||||
"邮箱:3364451258@qq.com\n"
|
||||
"GitHub:https://github.com/LHY0125/PathEditor\n"
|
||||
"记得给我的项目点个star!");
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
+1
-1
@@ -61,7 +61,7 @@ void sync_string_list_to_ui(Ihandle *list_ui, const StringList *str_list)
|
||||
|
||||
for (int i = 0; i < str_list->count; i++)
|
||||
{
|
||||
IupSetAttributeId(list_ui, "", i + 1, str_list->items[i]);
|
||||
IupSetAttributeId(list_ui, "", i + 1, string_list_get(str_list, i));
|
||||
}
|
||||
IupSetInt(list_ui, "COUNT", str_list->count);
|
||||
|
||||
|
||||
@@ -85,6 +85,24 @@ void add_string_list(StringList *list, const char *str)
|
||||
list->count++;
|
||||
}
|
||||
|
||||
// 获取指定索引的字符串(只读)
|
||||
const char *string_list_get(const StringList *list, int index)
|
||||
{
|
||||
if (!list || index < 0 || index >= list->count)
|
||||
return NULL;
|
||||
return list->items[index];
|
||||
}
|
||||
|
||||
// 设置指定索引的字符串(复制新字符串并释放旧字符串)
|
||||
int string_list_set(StringList *list, int index, const char *str)
|
||||
{
|
||||
if (!list || index < 0 || index >= list->count || !str)
|
||||
return -1;
|
||||
free(list->items[index]);
|
||||
list->items[index] = _strdup(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 清空字符串列表
|
||||
void clear_string_list(StringList *list)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user