diff --git a/src/boxes.c b/src/boxes.c index 54ee2bc78..05a4e4686 100644 --- a/src/boxes.c +++ b/src/boxes.c @@ -264,15 +264,17 @@ display_box (WPanel *panel, char **userp, char **minip, int *use_msformat, int n return result; } -sortfn * -sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) +const panel_format_t * +sort_box (const panel_format_t *sort_format, int *reverse, int *case_sensitive, int *exec_first) { int dlg_width = 40, dlg_height = 15; - char *sort_orders_names [SORT_TYPES]; + const char **sort_orders_names; + gsize sort_names_num; + int sort_idx = 0; - sortfn *result = sort_fn; + const panel_format_t *result = sort_format; { int max_radio = 0, max_check = 0; @@ -293,7 +295,7 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) QUICK_CHECKBOX (0, dlg_width, 3, dlg_height, N_("Executable &first"), exec_first), /* 5 */ QUICK_RADIO (4, dlg_width, 3, dlg_height, SORT_TYPES, - (const char **) sort_orders_names, &sort_idx), + NULL, &sort_idx), QUICK_END }; @@ -304,8 +306,11 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) quick_widgets, TRUE }; - for (i = 0; i < SORT_TYPES; i++) - if ((sortfn *) (sort_orders[i].sort_fn) == sort_fn) { + sort_orders_names = panel_get_sortable_formats(&sort_names_num); + quick_widgets[5].u.radio.items = sort_orders_names; + + for (i = 0; i < sort_names_num; i++) + if (strcmp (sort_orders_names[i], _(sort_format->title_hotkey)) == 0 ) { sort_idx = i; break; } @@ -318,13 +323,6 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) /* checkboxes */ for (i = 2; i < 5; i++) quick_widgets[i].u.checkbox.text = _(quick_widgets[i].u.checkbox.text); - /* radiobuttons */ - for (i = 0; i < SORT_TYPES; i++) - sort_orders_names[i] = _(sort_orders[i].sort_name); -#else - /* radiobuttons */ - for (i = 0; i < SORT_TYPES; i++) - sort_orders_names[i] = sort_orders[i].sort_name; #endif /* ENABLE_NlS */ /* buttons */ @@ -356,9 +354,12 @@ sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first) quick_widgets[i].relative_x = dlg_width/2 + 2; if (quick_dialog (&quick_dlg) != B_CANCEL) - result = (sortfn *) sort_orders[sort_idx].sort_fn; - } + result = panel_get_format_by_title_hotkey(sort_orders_names[sort_idx]); + if (result == NULL) + result = sort_format; + } + g_strfreev((gchar **)sort_orders_names); return result; } diff --git a/src/boxes.h b/src/boxes.h index 4c73ab176..1813d00e5 100644 --- a/src/boxes.h +++ b/src/boxes.h @@ -11,7 +11,7 @@ int display_box (WPanel *p, char **user, char **mini, int *use_msformat, int num); -sortfn *sort_box (sortfn *sort_fn, int *reverse, +const panel_format_t *sort_box (const panel_format_t *, int *reverse, int *case_sensitive, int *exec_first); void confirm_box (void); void display_bits_box (void); diff --git a/src/cmd.c b/src/cmd.c index 58a22dfaa..5b61194a6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1261,7 +1261,7 @@ single_dirsize_cmd (void) recalculate_panel_summary (panel); - if ( current_panel->sort_type == (sortfn *) sort_size ) + if ( current_panel->current_sort_field->sort_routine == (sortfn *) sort_size ) panel_re_sort (panel); panel->dirty = 1; @@ -1298,7 +1298,7 @@ dirsizes_cmd (void) recalculate_panel_summary (panel); - if ( current_panel->sort_type == (sortfn *) sort_size ) + if ( current_panel->current_sort_field->sort_routine == (sortfn *) sort_size ) panel_re_sort (panel); panel->dirty = 1; diff --git a/src/dir.c b/src/dir.c index 181140ca4..b4b448fa4 100644 --- a/src/dir.c +++ b/src/dir.c @@ -62,7 +62,7 @@ static int case_sensitive = OS_SORT_CASE_SENSITIVE_DEFAULT; static int exec_first = 1; #define MY_ISDIR(x) ( (is_exe (x->st.st_mode) && !(S_ISDIR (x->st.st_mode) || x->f.link_to_dir) && (exec_first == 1)) ? 1 : ( (S_ISDIR (x->st.st_mode) || x->f.link_to_dir) ? 2 : 0) ) - +/* sort_orders_t sort_orders [SORT_TYPES_TOTAL] = { { N_("&Unsorted"), unsorted }, { N_("&Name"), sort_name }, @@ -73,7 +73,7 @@ sort_orders_t sort_orders [SORT_TYPES_TOTAL] = { { N_("&Size"), sort_size }, { N_("&Inode"), sort_inode }, }; - +*/ int unsorted (file_entry *a, file_entry *b) diff --git a/src/dir.h b/src/dir.h index 9ee009642..29c42b364 100644 --- a/src/dir.h +++ b/src/dir.h @@ -75,7 +75,7 @@ typedef struct { int (*sort_fn)(file_entry *, file_entry *); } sort_orders_t; -extern sort_orders_t sort_orders [SORT_TYPES_TOTAL]; +// extern sort_orders_t sort_orders [SORT_TYPES_TOTAL]; int link_isdir (const file_entry *); int if_link_is_exe (const char *full_name, const file_entry *file); diff --git a/src/main.c b/src/main.c index 721c017f9..f76dd4db4 100644 --- a/src/main.c +++ b/src/main.c @@ -490,7 +490,7 @@ _do_panel_cd (WPanel *panel, const char *new_dir, enum cd_enum cd_type) /* Reload current panel */ panel_clean_dir (panel); panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->sort_type, + do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); try_to_select (panel, get_parent_dir_name (panel->cwd, olddir)); @@ -616,13 +616,13 @@ static void sort_cmd (void) { WPanel *p; - sortfn *sort_order; + const panel_format_t *sort_order; if (!SELECTED_IS_PANEL) return; p = MENU_PANEL; - sort_order = sort_box (p->sort_type, &p->reverse, + sort_order = sort_box (p->current_sort_field, &p->reverse, &p->case_sensitive, &p->exec_first); diff --git a/src/panel.h b/src/panel.h index 2effded0e..6c6ea3f9d 100644 --- a/src/panel.h +++ b/src/panel.h @@ -9,6 +9,7 @@ #include "dir.h" /* dir_list */ #include "dialog.h" /* Widget */ #include "fs.h" /* MC_MAXPATHLEN */ +#include "strutil.h" #define selection(p) (&(p->dir.list[p->selected])) #define DEFAULT_USER_FORMAT "half type name | size | perm" @@ -37,6 +38,20 @@ enum panel_display_enum { struct format_e; +typedef struct panel_format_struct { + const char *id; + int min_size; + int expands; + align_crt_t default_just; + const char *title; + const char *title_hotkey; + int use_in_gui; + const char *(*string_fn)(file_entry *, int); + sortfn *sort_routine; /* used by mouse_sort_col() */ +} panel_format_t; + +extern panel_format_t panel_formats []; + typedef struct WPanel { Widget widget; dir_list dir; /* Directory contents */ @@ -59,7 +74,7 @@ typedef struct WPanel { int split; /* Split panel to allow two columns */ int is_panelized; /* Flag: special filelisting, can't reload */ int frame_size; /* half or full frame */ - sortfn *sort_type; /* Sort type */ + const panel_format_t *current_sort_field; char *filter; /* File name filter */ int dirty; /* Should we redisplay the panel? */ @@ -94,7 +109,7 @@ extern int panel_scroll_pages; extern int fast_reload; void panel_reload (WPanel *panel); -void panel_set_sort_order (WPanel *panel, sortfn *sort_order); +void panel_set_sort_order (WPanel *panel, const panel_format_t *sort_order); void panel_re_sort (WPanel *panel); void set_panel_encoding (WPanel *); @@ -130,4 +145,9 @@ void directory_history_next (WPanel *panel); void directory_history_prev (WPanel *panel); void directory_history_list (WPanel *panel); +gsize panel_get_num_of_sortable_formats(void); +const char **panel_get_sortable_formats(gsize *); +const panel_format_t *panel_get_format_by_id(const char *); +const panel_format_t *panel_get_format_by_title_hotkey(const char *); + #endif diff --git a/src/screen.c b/src/screen.c index 183f91a38..d0fa02b9c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -59,7 +59,6 @@ #include "mountlist.h" /* my_statfs */ #include "selcodepage.h" /* select_charset () */ #include "charsets.h" /* get_codepage_id () */ -#include "strutil.h" #include "cmddef.h" /* CK_ cmd name const */ #include "keybind.h" /* global_key_map_t */ @@ -428,35 +427,135 @@ string_dot (file_entry *fe, int len) #define GT 1 -static struct { - const char *id; - int min_size; - int expands; - align_crt_t default_just; - const char *title; - int use_in_gui; - const char *(*string_fn)(file_entry *, int); - sortfn *sort_routine; /* used by mouse_sort_col() */ -} formats [] = { -{ "name", 12, 1, J_LEFT_FIT, N_("Name"), 1, string_file_name, (sortfn *) sort_name }, -{ "size", 7, 0, J_RIGHT, N_("Size"), 1, string_file_size, (sortfn *) sort_size }, -{ "bsize", 7, 0, J_RIGHT, N_("Size"), 1, string_file_size_brief, (sortfn *) sort_size }, -{ "type", GT, 0, J_LEFT, "", 2, string_file_type, NULL }, -{ "mtime", 12, 0, J_RIGHT, N_("MTime"), 1, string_file_mtime, (sortfn *) sort_time }, -{ "atime", 12, 0, J_RIGHT, N_("ATime"), 1, string_file_atime, (sortfn *) sort_atime }, -{ "ctime", 12, 0, J_RIGHT, N_("CTime"), 1, string_file_ctime, (sortfn *) sort_ctime }, -{ "perm", 10, 0, J_LEFT, N_("Permission"),1,string_file_permission, NULL }, -{ "mode", 6, 0, J_RIGHT, N_("Perm"), 1, string_file_perm_octal, NULL }, -{ "nlink", 2, 0, J_RIGHT, N_("Nl"), 1, string_file_nlinks, NULL }, -{ "inode", 5, 0, J_RIGHT, N_("Inode"), 1, string_inode, (sortfn *) sort_inode }, -{ "nuid", 5, 0, J_RIGHT, N_("UID"), 1, string_file_nuid, NULL }, -{ "ngid", 5, 0, J_RIGHT, N_("GID"), 1, string_file_ngid, NULL }, -{ "owner", 8, 0, J_LEFT_FIT, N_("Owner"), 1, string_file_owner, NULL }, -{ "group", 8, 0, J_LEFT_FIT, N_("Group"), 1, string_file_group, NULL }, -{ "mark", 1, 0, J_RIGHT, " ", 1, string_marked, NULL }, -{ "|", 1, 0, J_RIGHT, " ", 0, NULL, NULL }, -{ "space", 1, 0, J_RIGHT, " ", 0, string_space, NULL }, -{ "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, +panel_format_t panel_formats [] = { + { + "unsorted", 12, 1, J_LEFT_FIT, + N_("Unsorted"), N_("&Unsorted"), 1, + string_file_name, + (sortfn *) unsorted + }, + { + "name", 12, 1, J_LEFT_FIT, + N_("Name"), N_("&Name"), 1, + string_file_name, + (sortfn *) sort_name + }, + { + "extension", 12, 1, J_LEFT_FIT, + N_("Extension"), N_("&Extension"), 1, + string_file_name, /* TODO: string_file_ext*/ + (sortfn *) sort_ext + }, + { + "size", 7, 0, J_RIGHT, + N_("Size"), N_("&Size"), 1, + string_file_size, + (sortfn *) sort_size + }, + { + "bsize", 7, 0, J_RIGHT, + N_("Block Size"), NULL, 1, + string_file_size_brief, + (sortfn *) sort_size + }, + { + "type", GT, 0, J_LEFT, + "", NULL, 2, + string_file_type, + NULL + }, + { + "mtime", 12, 0, J_RIGHT, + N_("MTime"), N_("&Modify time"), 1, + string_file_mtime, + (sortfn *) sort_time + }, + { + "atime", 12, 0, J_RIGHT, + N_("ATime"), N_("&Access time"), 1, + string_file_atime, + (sortfn *) sort_atime + }, + { + "ctime", 12, 0, J_RIGHT, + N_("CTime"), N_("C&Hange time"), 1, + string_file_ctime, + (sortfn *) sort_ctime + }, + { + "perm", 10, 0, J_LEFT, + N_("Permission"), NULL, 1, + string_file_permission, + NULL + }, + { + "mode", 6, 0, J_RIGHT, + N_("Perm"), NULL, 1, + string_file_perm_octal, + NULL + }, + { + "nlink", 2, 0, J_RIGHT, + N_("Nl"), NULL, 1, + string_file_nlinks, NULL + }, + { + "inode", 5, 0, J_RIGHT, + N_("Inode"), N_("&Inode"), 1, + string_inode, + (sortfn *) sort_inode + }, + { + "nuid", 5, 0, J_RIGHT, + N_("UID"), NULL, 1, + string_file_nuid, + NULL + }, + { + "ngid", 5, 0, J_RIGHT, + N_("GID"), NULL, 1, + string_file_ngid, + NULL + }, + { + "owner", 8, 0, J_LEFT_FIT, + N_("Owner"), NULL, 1, + string_file_owner, + NULL + }, + { + "group", 8,0, J_LEFT_FIT, + N_("Group"), NULL, 1, + string_file_group, + NULL + }, + { + "mark", 1, 0, J_RIGHT, + " ", NULL, 1, + string_marked, + NULL + }, + { + "|", 1, 0, J_RIGHT, + " ", NULL, 0, + NULL, + NULL + }, + { + "space", 1, 0, J_RIGHT, + " ", NULL, 0, + string_space, + NULL + }, + { + "dot", 1, 0, J_RIGHT, + " ", NULL, 0, + string_dot, + NULL + }, + { + NULL, 0, 0, J_RIGHT, NULL, NULL, 0, NULL, NULL + }, }; static int @@ -1158,7 +1257,7 @@ panel_new_with_dir (const char *panel_name, const char *wpath) /* Load the default format */ panel->count = - do_load_dir (panel->cwd, &panel->dir, panel->sort_type, + do_load_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); @@ -1197,7 +1296,7 @@ panel_reload (WPanel *panel) } panel->count = - do_reload_dir (panel->cwd, &panel->dir, panel->sort_type, + do_reload_dir (panel->cwd, &panel->dir, panel->current_sort_field->sort_routine, panel->count, panel->reverse, panel->case_sensitive, panel->exec_first, panel->filter); @@ -1325,9 +1424,9 @@ parse_display_format (WPanel *panel, const char *format, char **error, int issta if (i18n_timelength == 0) { i18n_timelength = i18n_checktimelength (); /* Musn't be 0 */ - for (i = 0; i < ELEMENTS(formats); i++) - if (strcmp ("time", formats [i].id+1) == 0) - formats [i].min_size = i18n_timelength; + for (i = 0; panel_formats[i].id != NULL; i++) + if (strcmp ("time", panel_formats[i].id + 1) == 0) + panel_formats [i].min_size = i18n_timelength; } /* @@ -1370,26 +1469,26 @@ parse_display_format (WPanel *panel, const char *format, char **error, int issta } else set_justify = 0; - for (i = 0; i < ELEMENTS(formats); i++){ - size_t klen = strlen (formats [i].id); + for (i = 0; panel_formats[i].id != NULL; i++) { + size_t klen = strlen (panel_formats [i].id); - if (strncmp (format, formats [i].id, klen) != 0) + if (strncmp (format, panel_formats [i].id, klen) != 0) continue; format += klen; - if (formats [i].use_in_gui) + if (panel_formats [i].use_in_gui) items++; - darr->requested_field_len = formats [i].min_size; - darr->string_fn = formats [i].string_fn; - if (formats [i].title [0]) - darr->title = _(formats [i].title); + darr->requested_field_len = panel_formats [i].min_size; + darr->string_fn = panel_formats [i].string_fn; + if (panel_formats [i].title [0]) + darr->title = _(panel_formats [i].title); else darr->title = ""; - darr->id = formats [i].id; - darr->expand = formats [i].expands; - darr->just_mode = formats [i].default_just; + darr->id = panel_formats [i].id; + darr->expand = panel_formats [i].expands; + darr->just_mode = panel_formats [i].default_just; if (set_justify) { if (IS_FIT(darr->just_mode)) @@ -2554,7 +2653,7 @@ mouse_sort_col(Gpm_Event *event, WPanel *panel) { int i; const char *sort_name = NULL; - sortfn *col_sort_type = NULL; + panel_format_t *col_sort_format = NULL; format_e *format; @@ -2569,23 +2668,23 @@ mouse_sort_col(Gpm_Event *event, WPanel *panel) if (sort_name == NULL) return; - for (i=0; i < ELEMENTS(formats); i++) { - if ( !strcmp(sort_name,_(formats[i].title)) && formats[i].sort_routine ) { - col_sort_type = formats[i].sort_routine; + for(i=0; panel_formats[i].id != NULL; i ++) { + if ( !strcmp(sort_name,_(panel_formats[i].title)) && panel_formats[i].sort_routine ) { + col_sort_format = &panel_formats[i]; break; } } - if (! col_sort_type) + if (! col_sort_format) return; - if (panel->sort_type == col_sort_type) { + if (panel->current_sort_field == col_sort_format) { /* reverse the sort if clicked column is already the sorted column */ panel->reverse = ! panel->reverse; } else { panel->reverse = 0; /* new sort is forced to be ascending */ } - panel_set_sort_order(panel, col_sort_type); + panel_set_sort_order(panel, col_sort_format); } @@ -2738,7 +2837,7 @@ panel_re_sort (WPanel *panel) filename = g_strdup (selection (panel)->fname); unselect_item (panel); - do_sort (&panel->dir, panel->sort_type, panel->count-1, panel->reverse, + do_sort (&panel->dir, panel->current_sort_field->sort_routine, panel->count-1, panel->reverse, panel->case_sensitive, panel->exec_first); panel->selected = -1; for (i = panel->count; i; i--){ @@ -2756,15 +2855,15 @@ panel_re_sort (WPanel *panel) } void -panel_set_sort_order (WPanel *panel, sortfn *sort_order) +panel_set_sort_order (WPanel *panel, const panel_format_t *sort_order) { if (sort_order == 0) return; - panel->sort_type = sort_order; + panel->current_sort_field = sort_order; /* The directory is already sorted, we have to load the unsorted stuff */ - if (sort_order == (sortfn *) unsorted){ + if (sort_order->sort_routine == (sortfn *) unsorted){ char *current_file; current_file = g_strdup (panel->dir.list [panel->selected].fname); @@ -2933,3 +3032,64 @@ update_panels (int force_update, const char *current_file) mc_chdir (panel->cwd); } + +gsize +panel_get_num_of_sortable_formats(void) +{ + gsize ret = 0, index; + + for(index=0; panel_formats[index].id != NULL; index ++) + if (panel_formats[index].title_hotkey != NULL) + ret++; + return ret; +} + + +const char ** +panel_get_sortable_formats(gsize *array_size) +{ + char **ret; + gsize index, i; + + index = panel_get_num_of_sortable_formats(); + + ret = g_new0 (char *, index + 1); + if (ret == NULL) + return NULL; + + if (array_size != NULL) + *array_size = index; + + index=0; + + for(i=0; panel_formats[i].id != NULL; i ++) + if (panel_formats[i].title_hotkey != NULL) + ret[index++] = g_strdup(_(panel_formats[i].title_hotkey)); + return (const char**) ret; +} + +const panel_format_t * +panel_get_format_by_id(const char *name) +{ + gsize index; + for(index=0; panel_formats[index].id != NULL; index ++) + if ( + panel_formats[index].id != NULL && + strcmp(name, panel_formats[index].id) == 0 + ) + return &panel_formats[index]; + return NULL; +} + +const panel_format_t * +panel_get_format_by_title_hotkey(const char *name) +{ + gsize index; + for(index=0; panel_formats[index].id != NULL; index ++) + if ( + panel_formats[index].title_hotkey != NULL && + strcmp(name, _(panel_formats[index].title_hotkey)) == 0 + ) + return &panel_formats[index]; + return NULL; +} diff --git a/src/setup.c b/src/setup.c index 8571b7632..6d5e803ae 100644 --- a/src/setup.c +++ b/src/setup.c @@ -90,21 +90,6 @@ int startup_right_mode; /* default panel values */ int saving_setup; -static const struct { - const char *key; - sortfn *sort_type; -} sort_names [] = { - { "name", (sortfn *) sort_name }, - { "extension", (sortfn *) sort_ext }, - { "time", (sortfn *) sort_time }, - { "atime", (sortfn *) sort_atime }, - { "ctime", (sortfn *) sort_ctime }, - { "size", (sortfn *) sort_size }, - { "inode", (sortfn *) sort_inode }, - { "unsorted", (sortfn *) unsorted }, - { 0, 0 } -}; - static const struct { const char *key; int list_type; @@ -265,11 +250,7 @@ panel_save_setup (struct WPanel *panel, const char *section) mc_config_set_int(mc_panels_config, section, "exec_first", panel->exec_first); - for (i = 0; sort_names [i].key; i++) - if (sort_names [i].sort_type == (sortfn *) panel->sort_type){ - mc_config_set_string(mc_panels_config, section, "sort_order", sort_names [i].key); - break; - } + mc_config_set_string(mc_panels_config, section, "sort_order", panel->current_sort_field->id); for (i = 0; list_types [i].key; i++) if (list_types [i].list_type == panel->list_type){ @@ -417,14 +398,9 @@ panel_load_setup (WPanel *panel, const char *section) /* Load sort order */ buffer = mc_config_get_string(mc_panels_config, section, "sort_order", "name"); - - panel->sort_type = (sortfn *) sort_name; - for (i = 0; sort_names [i].key; i++) - if ( g_strcasecmp (sort_names [i].key, buffer) == 0){ - panel->sort_type = sort_names [i].sort_type; - break; - } + panel->current_sort_field = panel_get_format_by_id(buffer); g_free(buffer); + /* Load the listing mode */ buffer = mc_config_get_string(mc_panels_config, section, "list_mode", "full"); panel->list_type = list_full;