jfileselect: add a programmable filter

This commit is contained in:
Lephenixnoir 2022-11-05 18:50:40 +01:00
parent 34ee43d67f
commit a588c24f59
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
2 changed files with 40 additions and 19 deletions

View file

@ -39,6 +39,8 @@ typedef struct {
bool saveas; bool saveas;
/* Whether we are currently using the input field */ /* Whether we are currently using the input field */
bool input_mode; bool input_mode;
/* File filter; NULL accepts everything */
bool (*filter_function)(struct dirent const *entry);
/* Current cursor position (0 .. folder_entries-1) */ /* Current cursor position (0 .. folder_entries-1) */
int16_t cursor; int16_t cursor;
@ -96,6 +98,18 @@ char const *jfileselect_selected_file(jfileselect *fs);
/* jfileselect_current_folder(): Get the path to the current folder */ /* jfileselect_current_folder(): Get the path to the current folder */
char const *jfileselect_current_folder(jfileselect *fs); char const *jfileselect_current_folder(jfileselect *fs);
/* jfileselect_set_filter(): Set a filter function
The function is called on each directory entry read when scanning a folder.
It should return true to show the entry, false to ignore it. By default,
jfileselect_default_filter is used. Note filters in general should really
accept folders. */
void jfileselect_set_filter(jfileselect *fs,
bool (*filter)(struct dirent const *entry));
/* Default filter. Rejects "@MainMem", "SAVE-F", "." and "..". */
bool jfileselect_default_filter(struct dirent const *entry);
/* Trivial properties */ /* Trivial properties */
void jfileselect_set_font(jfileselect *fs, font_t const *font); void jfileselect_set_font(jfileselect *fs, font_t const *font);
void jfileselect_set_line_spacing(jfileselect *fs, int line_spacing); void jfileselect_set_line_spacing(jfileselect *fs, int line_spacing);

View file

@ -56,6 +56,8 @@ jfileselect *jfileselect_create(void *parent)
fs->selected_file = NULL; fs->selected_file = NULL;
fs->saveas_input = input; fs->saveas_input = input;
fs->saveas = false; fs->saveas = false;
fs->input_mode = false;
fs->filter_function = jfileselect_default_filter;
fs->cursor = -1; fs->cursor = -1;
fs->scroll = 0; fs->scroll = 0;
@ -166,28 +168,14 @@ static char *path_up(char const *path)
return parent; return parent;
} }
static bool accept_entry(struct dirent *ent) static int count_accepted_entries(jfileselect *fs, DIR *dp)
{
/* TODO: jfileselect: Programmable filter */
if(!strcmp(ent->d_name, "@MainMem"))
return false;
if(!strcmp(ent->d_name, "SAVE-F"))
return false;
if(!strcmp(ent->d_name, "."))
return false;
if(!strcmp(ent->d_name, ".."))
return false;
return true;
}
static int count_accepted_entries(DIR *dp)
{ {
int n = 0; int n = 0;
struct dirent *ent; struct dirent *ent;
rewinddir(dp); rewinddir(dp);
while((ent = readdir(dp))) while((ent = readdir(dp)))
n += accept_entry(ent); n += (fs->filter_function ? fs->filter_function(ent) : 1);
return n; return n;
} }
@ -222,7 +210,7 @@ static bool load_folder_switch(jfileselect *fs, char *path)
return false; return false;
/* Count entries */ /* Count entries */
int n = count_accepted_entries(dp) + fs->saveas; int n = count_accepted_entries(fs, dp) + fs->saveas;
/* Allocate memory for the fileinfo structures */ /* Allocate memory for the fileinfo structures */
struct fileinfo *finfo = malloc(n * sizeof *finfo); struct fileinfo *finfo = malloc(n * sizeof *finfo);
@ -234,7 +222,7 @@ static bool load_folder_switch(jfileselect *fs, char *path)
/* Read the fileinfo structures */ /* Read the fileinfo structures */
rewinddir(dp); rewinddir(dp);
for(int i = 0; i < n && (ent = readdir(dp));) { for(int i = 0; i < n && (ent = readdir(dp));) {
if(!accept_entry(ent)) if(fs->filter_function && !fs->filter_function(ent))
continue; continue;
finfo[i].name = strdup(ent->d_name); finfo[i].name = strdup(ent->d_name);
@ -254,7 +242,7 @@ static bool load_folder_switch(jfileselect *fs, char *path)
if(ent->d_type == DT_DIR) { if(ent->d_type == DT_DIR) {
DIR *sub = opendir(full_path); DIR *sub = opendir(full_path);
if(sub) { if(sub) {
finfo[i].size = count_accepted_entries(sub); finfo[i].size = count_accepted_entries(fs, sub);
closedir(sub); closedir(sub);
} }
} }
@ -320,6 +308,25 @@ char const *jfileselect_current_folder(jfileselect *fs)
return fs->path; return fs->path;
} }
void jfileselect_set_filter(jfileselect *fs,
bool (*filter)(struct dirent const *entry))
{
fs->filter_function = filter;
}
bool jfileselect_default_filter(struct dirent const *ent)
{
if(!strcmp(ent->d_name, "@MainMem"))
return false;
if(!strcmp(ent->d_name, "SAVE-F"))
return false;
if(!strcmp(ent->d_name, "."))
return false;
if(!strcmp(ent->d_name, ".."))
return false;
return true;
}
//--- //---
// Polymorphic widget operations // Polymorphic widget operations
//--- //---