fs_file_list: integration of double-linked in file lists

This commit is contained in:
2026-08-07 18:02:58 +03:00
parent 6b20f2f179
commit c563c71b5f
4 changed files with 76 additions and 39 deletions
+3 -1
View File
@@ -4,7 +4,9 @@
- [ ] Sorting in the file list (local files):
- [x] Testing env
- [x] Test dlist
- [ ] Dlist sort
- [x] Dlist sort
- [ ] Bug: when returning back from the link
- [ ] Better compatibility with Cyrillic symbols (use wchar_t everywhere)
## Global tasks:
- [ ] Testing
+12 -12
View File
@@ -179,22 +179,22 @@ void *dlist_it_next(dlist_t *dlist) {
return NULL;
}
dlist_node_t *dlist_wind_fwd(dlist_t *dlist, int count) {
dlist_node_t *cur_ptr = dlist->work_pointer;
dlist_node_t *dlist_wind_fwd(dlist_t *dlist, dlist_node_t *start, int count) {
dlist_node_t *new_ptr = start;
for (int i = 0; i < count && cur_ptr != NULL; i++) {
cur_ptr = cur_ptr->next;
for (int i = 0; i <= count && new_ptr != NULL; i++) {
new_ptr = new_ptr->next;
}
dlist->work_pointer = cur_ptr;
return cur_ptr;
dlist->work_pointer = new_ptr;
return new_ptr;
}
dlist_node_t *dlist_wind_bwd(dlist_t *dlist, int count) {
dlist_node_t *cur_ptr = dlist->work_pointer;
dlist_node_t *dlist_wind_bwd(dlist_t *dlist, dlist_node_t *start, int count) {
dlist_node_t *new_ptr = start;
for (int i = 0; i < count && cur_ptr != NULL; i++) {
cur_ptr = cur_ptr->previous;
for (int i = 0; i <= count && new_ptr != NULL; i++) {
new_ptr = new_ptr->previous;
}
dlist->work_pointer = cur_ptr;
return cur_ptr;
dlist->work_pointer = new_ptr;
return new_ptr;
}
+7 -7
View File
@@ -30,11 +30,11 @@ void _dlist_add(dlist_t *dlist, void *el_ptr, int el_siz,
void *dlist_it_prev(dlist_t *dlist);
void *dlist_it_next(dlist_t *dlist);
void _dlist_add_sort(dlist_t *dlist, void *el_ptr, int el_siz,
dblist_sort_cb_t cb, dblist_add_cb_t add_cb);
int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t cb);
int dlist_clear_list(dlist_t *dlist, dblist_rm_cb_t cb);
dlist_node_t *dlist_wind_fwd(dlist_t *dlist, int count);
dlist_node_t *dlist_wind_bwd(dlist_t *dlist, int count);
dblist_sort_cb_t cb, dblist_add_cb_t add_cb);
int dlist_remove_by_ptr(dlist_t *dlist, void *el_ptr, dblist_rm_cb_t cb);
int dlist_clear_list(dlist_t *dlist, dblist_rm_cb_t cb);
dlist_node_t *dlist_wind_fwd(dlist_t *dlist, dlist_node_t *start, int count);
dlist_node_t *dlist_wind_bwd(dlist_t *dlist, dlist_node_t *start, int count);
#define dlist_init(el_ptr, el_def, add_cb) \
_dlist_init(el_ptr, sizeof(el_def), add_cb)
@@ -42,9 +42,9 @@ dlist_node_t *dlist_wind_bwd(dlist_t *dlist, int count);
_dlist_add(dlist, el_ptr, sizeof(el_def), add_cb, prepend)
#define dlist_get_current(dlist) dlist->current->el_ptr
#define dlist_get_working_point(dlist) dlist->current->el_ptr
#define dlist_add_sort(dlist, el_ptr, el_typ, sort_cb, add_cb) \
#define dlist_add_sort(dlist, el_ptr, el_typ, sort_cb, add_cb) \
_dlist_add_sort(dlist, el_ptr, sizeof(el_typ), sort_cb, add_cb)
#define dlist_get_ptr(node_ptr) node_ptr->el_ptr
#define dlist_get_ptr(node_ptr) node_ptr == NULL ? NULL : node_ptr->el_ptr
#define dlist_set_wp(dlist, node_ptr) dlist->work_pointer = node_ptr
#define dlist_get_wp(dlist) dlist->work_pointer
+54 -19
View File
@@ -22,6 +22,7 @@
#include "alert.h"
#include "dlist.h"
#include "file_list.h"
#include "fs_file_list.h"
#include "main_window.h"
#include "widget_core.h"
@@ -34,8 +35,6 @@
// void w_fl_reset(w_lfl_ui_t *fl_ui);
/* TODO: solve problem with selection */
static size_t get_file_size(char *path) {
int fd = open(path, O_RDONLY);
if (fd == -1) {
@@ -63,7 +62,7 @@ static bool fl_add_cb(void *_dst, void *_src) {
strcpy(dst->name, src->name);
if (src->d_name != NULL) {
dst->d_name = malloc(strlen (src->d_name) + 1);
dst->d_name = malloc(strlen(src->d_name) + 1);
strcpy(dst->d_name, src->d_name);
}
@@ -76,11 +75,36 @@ static bool fl_add_cb(void *_dst, void *_src) {
return 1;
}
static int _strcmp(char *a, char *b) {
char abuf[256];
char bbuf[256];
int c = 0;
for (int i = 0; a[i] != '\0'; i++) {
abuf[i] = a[i] & ~32; /* case non-sensitive for Latin characters */
}
for (int i = 0; b[i] != '\0'; i++) {
bbuf[i] = b[i] & ~32;
}
return strcmp(abuf, bbuf);
}
static bool fl_add_sort_cb(void *_a, void *_b) {
w_lfl_item_t *a = _a;
w_lfl_item_t *b = _b;
/* TODO: do real comparison */
return true;
int res = 0;
if ((a->d_type == b->d_type) && a->d_type == DT_DIR) {
res = _strcmp(a->d_name, b->d_name);
} else if (a->d_type == DT_DIR) {
return false;
} else if (b->d_type == DT_DIR) {
return true;
} else {
res = _strcmp(a->name, b->name);
}
return res > 0 ? true : false;
}
static bool fl_clear_cb(void *el_ptr) {
@@ -195,9 +219,9 @@ static void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
char *selection = NULL;
size_t dp_current;
char n_path[INBUFSIZE];
w_lfl_item_t *current_item = dlist_get_current(fui->f_list);
if (current_item->d_type == DT_DIR) {
if (!strcmp("/..", current_item->name)) {
w_lfl_item_t *selected_item = fui->fl_selected->el_ptr;
if (selected_item->d_type == DT_DIR) {
if (!strcmp("/..", selected_item->name)) {
strcpy(n_path, fui->d_path);
bash_case = strrchr(n_path, '/');
if (bash_case != NULL) {
@@ -209,7 +233,7 @@ static void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
}
} else {
dp_current = strlen(fui->d_path);
selection = current_item->name + 1;
selection = selected_item->name + 1;
sprintf(n_path, "%s/%s", fui->d_path, selection);
if (get_files_from_fs(fui, n_path)) {
w_alert("Can't open the folder!");
@@ -219,12 +243,12 @@ static void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
fui->current_idx = 0;
resp_data->code = cbrc_none;
w_lfl_draw(fui);
} else if (current_item->d_type == DT_REG) {
} else if (selected_item->d_type == DT_REG) {
resp_data->code = cbrp_val;
resp_data->val.type = val_num;
resp_data->val.val.num = 1;
} else if (current_item->d_type == DT_LNK) {
strcpy(n_path, current_item->path);
} else if (selected_item->d_type == DT_LNK) {
strcpy(n_path, selected_item->path);
if (get_files_from_fs(fui, n_path)) {
w_alert("Can't open the link!");
return;
@@ -237,17 +261,22 @@ static void open_selected_item(w_lfl_ui_t *fui, w_cbrp_data *resp_data) {
static void page_next(w_lfl_ui_t *fui) {
if (fui->cur_page < fui->pages_num) {
dlist_node_t *n_page_item = dlist_wind_fwd(fui->f_list, fui->max_lines);
dlist_node_t *n_page_item =
dlist_wind_fwd(fui->f_list, fui->page_start, fui->max_lines);
fui->cur_page++;
fui->page_start = n_page_item;
fui->fl_selected = n_page_item;
fui->current_idx = 0;
}
}
static void page_previous(w_lfl_ui_t *fui) {
dlist_node_t *last_node = fui->page_start->previous;
if (fui->cur_page > 1) {
dlist_node_t *n_page_item = dlist_wind_bwd(fui->f_list, fui->max_lines);
dlist_node_t *n_page_item =
dlist_wind_bwd(fui->f_list, fui->page_start, fui->max_lines);
fui->cur_page--;
fui->page_start = n_page_item;
fui->fl_selected = last_node;
fui->current_idx = fui->max_lines;
}
}
@@ -263,7 +292,10 @@ static void w_lfl_cb(w_cb_args_t *args) {
case KEY_DOWN:
is_cur_p = (fui->current_idx % fui->max_lines || fui->current_idx == 0);
if (is_cur_p) {
fui->fl_selected = dlist_it_next(fui->f_list);
if (fui->fl_selected->next != NULL) {
fui->fl_selected = fui->fl_selected->next;
fui->current_idx++;
}
} else { /* is_cur_p */
page_next(fui);
}
@@ -271,9 +303,12 @@ static void w_lfl_cb(w_cb_args_t *args) {
break;
case KEY_UP:
if (fui->current_idx > 0) {
fui->fl_selected = dlist_it_prev(fui->f_list);
if (fui->fl_selected->previous != NULL) {
fui->fl_selected = fui->fl_selected->previous;
fui->current_idx--;
}
} else {
page_next(fui);
page_previous(fui);
}
w_lfl_draw(fui);
break;
@@ -350,8 +385,8 @@ static int32_t process_user_input(app_t *app, w_cb_args_t *d_args) {
if (d_args->resp_data.code == cbrp_val &&
d_args->resp_data.val.type == val_num &&
d_args->resp_data.val.val.num == 1) {
file_upload_open(fui->d_path, fui->f_list->work_pointer->el_ptr,
app->query_args);
w_lfl_item_t *file = dlist_get_ptr(fui->fl_selected);
file_upload_open(fui->d_path, file->name, app->query_args);
app->query_args->state = S_UPLOAD_PARAMS;
}
return OK;