mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-05-09 18:02:52 +08:00
feat(multi-select): 支持列表多选及批量删除
- 列表控件启用 MULTIPLE=YES 属性 - btn_del_cb 支持批量删除:解析分号分隔的多选索引,从大到小删除 - 批量删除推送一条合并的 undo record,支持一步撤销 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -180,39 +180,77 @@ int btn_browse_cb(Ihandle *self)
|
||||
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)
|
||||
// 解析多选索引(VALUE 为 "1;3;5" 格式)
|
||||
char *value_str = IupGetAttribute(current_list, "VALUE");
|
||||
if (!value_str || value_str[0] == '\0')
|
||||
{
|
||||
IupMessage(_("Info"), _("Please select an item to delete first"));
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
StringList *raw_data = get_current_raw_data(dlg);
|
||||
int del_index = selected - 1;
|
||||
if (!raw_data || raw_data->count == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
// 记录撤销信息(被删除的路径)
|
||||
char *del_path = _strdup(string_list_get(raw_data, del_index));
|
||||
char *paths[1] = {del_path};
|
||||
push_record(dlg, OP_DELETE, del_index, 1, paths, NULL);
|
||||
free(del_path);
|
||||
|
||||
ErrorCode result = path_manager_remove_at(raw_data, del_index);
|
||||
if (result != ERR_OK)
|
||||
// 解析选中索引并排序(从大到小,方便从尾部删除避免索引偏移)
|
||||
int indices[256];
|
||||
int sel_count = 0;
|
||||
char *token = strtok(value_str, ";");
|
||||
while (token && sel_count < 256)
|
||||
{
|
||||
log_error("Failed to remove path at index %d", del_index);
|
||||
int idx = atoi(token) - 1; // 转为 0-based
|
||||
if (idx >= 0 && idx < raw_data->count)
|
||||
indices[sel_count++] = idx;
|
||||
token = strtok(NULL, ";");
|
||||
}
|
||||
|
||||
if (sel_count == 0)
|
||||
return IUP_DEFAULT;
|
||||
|
||||
// 从大到小排序
|
||||
for (int i = 0; i < sel_count - 1; i++)
|
||||
{
|
||||
for (int j = i + 1; j < sel_count; j++)
|
||||
{
|
||||
if (indices[i] < indices[j])
|
||||
{
|
||||
int tmp = indices[i];
|
||||
indices[i] = indices[j];
|
||||
indices[j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录撤销信息(所有被删除的路径)
|
||||
char **old_paths = (char **)malloc(sel_count * sizeof(char *));
|
||||
for (int i = 0; i < sel_count; i++)
|
||||
old_paths[i] = _strdup(string_list_get(raw_data, indices[i]));
|
||||
|
||||
push_record(dlg, OP_DELETE, indices[sel_count - 1], sel_count, old_paths, NULL);
|
||||
|
||||
for (int i = 0; i < sel_count; i++)
|
||||
free(old_paths[i]);
|
||||
free(old_paths);
|
||||
|
||||
// 从大到小删除(避免索引偏移)
|
||||
for (int i = 0; i < sel_count; i++)
|
||||
path_manager_remove_at(raw_data, indices[i]);
|
||||
|
||||
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"));
|
||||
{
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), _("Deleted %d items"), sel_count);
|
||||
IupSetAttribute(lbl_status, "TITLE", msg);
|
||||
}
|
||||
|
||||
refresh_undo_redo_buttons(dlg);
|
||||
return IUP_DEFAULT;
|
||||
|
||||
@@ -17,6 +17,7 @@ static Ihandle *create_path_list(const char *name)
|
||||
IupSetAttribute(list, "BORDER", "YES");
|
||||
IupSetAttribute(list, "CANFOCUS", "YES");
|
||||
IupSetAttribute(list, "HLINE", "NO");
|
||||
IupSetAttribute(list, "MULTIPLE", "YES");
|
||||
IupSetCallback(list, "DBLCLICK_CB", (Icallback)list_dblclick_cb);
|
||||
IupSetCallback(list, "DROPFILES_CB", (Icallback)list_dropfiles_cb);
|
||||
IupSetCallback(list, "K_ANY", (Icallback)list_k_any_cb);
|
||||
|
||||
Reference in New Issue
Block a user