From e0b589e5cdaa96159d37118de347a80cde20ef41 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Thu, 6 Feb 2020 14:51:32 +0000 Subject: [PATCH] Sort by name and date in folder list view Ref: https://github.com/BestImageViewer/geeqie/issues/429 --- src/layout.c | 20 +++++++++++++-- src/layout.h | 2 ++ src/menu.c | 26 +++++++++++++++++++ src/menu.h | 3 +++ src/options.c | 2 ++ src/typedefs.h | 5 ++++ src/view_dir.c | 61 +++++++++++++++++++++++++++++++++++++++------ src/view_dir.h | 2 +- src/view_dir_list.c | 6 +++++ 9 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/layout.c b/src/layout.c index 8f6c51a5..6f5e209e 100644 --- a/src/layout.c +++ b/src/layout.c @@ -347,8 +347,8 @@ static GtkWidget *layout_tool_setup(LayoutWindow *lw) DEBUG_NAME(box_folders); gtk_box_pack_start(GTK_BOX(box), box_folders, TRUE, TRUE, 0); - lw->vd = vd_new(lw->options.dir_view_type, lw->dir_fd); - vd_set_layout(lw->vd, lw); + lw->vd = vd_new(lw); + vd_set_select_func(lw->vd, layout_vd_select_cb, lw); lw->dir_view = lw->vd->widget; @@ -1344,6 +1344,18 @@ void layout_views_set(LayoutWindow *lw, DirViewType dir_view_type, FileViewType layout_style_set(lw, -1, NULL); } +void layout_views_set_sort(LayoutWindow *lw, SortType method, gboolean ascend) +{ + if (!layout_valid(&lw)) return; + + if (lw->options.dir_view_list_sort.method == method && lw->options.dir_view_list_sort.ascend == ascend) return; + + lw->options.dir_view_list_sort.method = method; + lw->options.dir_view_list_sort.ascend = ascend; + + layout_style_set(lw, -1, NULL); +} + gboolean layout_views_get(LayoutWindow *lw, DirViewType *dir_view_type, FileViewType *file_view_type) { if (!layout_valid(&lw)) return FALSE; @@ -2564,6 +2576,8 @@ void layout_write_attributes(LayoutOptions *layout, GString *outstr, gint indent WRITE_NL(); WRITE_CHAR(*layout, order); WRITE_NL(); WRITE_UINT(*layout, dir_view_type); WRITE_NL(); WRITE_UINT(*layout, file_view_type); + WRITE_NL(); WRITE_UINT(*layout, dir_view_list_sort.method); + WRITE_NL(); WRITE_BOOL(*layout, dir_view_list_sort.ascend); WRITE_NL(); WRITE_BOOL(*layout, show_marks); WRITE_NL(); WRITE_BOOL(*layout, show_file_filter); WRITE_NL(); WRITE_BOOL(*layout, show_thumbnails); @@ -2663,6 +2677,8 @@ void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names if (READ_UINT(*layout, dir_view_type)) continue; if (READ_UINT(*layout, file_view_type)) continue; + if (READ_UINT(*layout, dir_view_list_sort.method)) continue; + if (READ_BOOL(*layout, dir_view_list_sort.ascend)) continue; if (READ_BOOL(*layout, show_marks)) continue; if (READ_BOOL(*layout, show_file_filter)) continue; if (READ_BOOL(*layout, show_thumbnails)) continue; diff --git a/src/layout.h b/src/layout.h index 2b338431..b78b6d67 100644 --- a/src/layout.h +++ b/src/layout.h @@ -100,6 +100,8 @@ gboolean layout_geometry_get_dividers(LayoutWindow *lw, gint *h, gint *v); void layout_views_set(LayoutWindow *lw, DirViewType dir_view_type, FileViewType file_view_type); gboolean layout_views_get(LayoutWindow *lw, DirViewType *dir_view_type, FileViewType *file_view_type); +void layout_views_set_sort(LayoutWindow *lw, SortType method, gboolean ascend); + void layout_status_update(LayoutWindow *lw, const gchar *text); void layout_style_set(LayoutWindow *lw, gint style, const gchar *order); diff --git a/src/menu.c b/src/menu.c index 7c2c7cd7..a83f08c6 100644 --- a/src/menu.c +++ b/src/menu.c @@ -234,6 +234,32 @@ GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data, return submenu; } +GtkWidget *submenu_add_dir_sort(GtkWidget *menu, GCallback func, gpointer data, + gboolean include_none, gboolean include_path, + gboolean show_current, SortType type) +{ + GtkWidget *submenu; + + submenu = gtk_menu_new(); + g_object_set_data(G_OBJECT(submenu), "submenu_data", data); + + submenu_add_sort_item(submenu, func, SORT_NAME, show_current, type); + submenu_add_sort_item(submenu, func, SORT_TIME, show_current, type); + if (include_path) submenu_add_sort_item(submenu, func, SORT_PATH, show_current, type); + if (include_none) submenu_add_sort_item(submenu, func, SORT_NONE, show_current, type); + + if (menu) + { + GtkWidget *item; + + item = menu_item_add(menu, _("Sort"), NULL, NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + return item; + } + + return submenu; +} + gchar *zoom_type_get_text(ZoomMode method) { switch (method) diff --git a/src/menu.h b/src/menu.h index 52f58c98..517c472a 100644 --- a/src/menu.h +++ b/src/menu.h @@ -31,6 +31,9 @@ gchar *sort_type_get_text(SortType method); GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data, gboolean include_none, gboolean include_path, gboolean show_current, SortType type); +GtkWidget *submenu_add_dir_sort(GtkWidget *menu, GCallback func, gpointer data, + gboolean include_none, gboolean include_path, + gboolean show_current, SortType type); GtkWidget *submenu_add_zoom(GtkWidget *menu, GCallback func, gpointer data, gboolean include_none, gboolean include_path, gboolean show_current, ZoomMode mode); diff --git a/src/options.c b/src/options.c index bab26acb..69dfe82f 100644 --- a/src/options.c +++ b/src/options.c @@ -279,6 +279,8 @@ LayoutOptions *init_layout_options(LayoutOptions *options) memset(options, 0, sizeof(LayoutOptions)); options->dir_view_type = DIRVIEW_LIST; + options->dir_view_list_sort.ascend = TRUE; + options->dir_view_list_sort.method = SORT_NAME; options->file_view_type = FILEVIEW_LIST; options->float_window.h = 450; options->float_window.vdivider_pos = -1; diff --git a/src/typedefs.h b/src/typedefs.h index 8cd55823..ce58f509 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -645,6 +645,11 @@ struct _LayoutOptions DirViewType dir_view_type; FileViewType file_view_type; + struct { + SortType method; + gboolean ascend; + } dir_view_list_sort; + gboolean show_thumbnails; gboolean show_marks; gboolean show_file_filter; diff --git a/src/view_dir.c b/src/view_dir.c index 7c2d192c..0fcdf27d 100644 --- a/src/view_dir.c +++ b/src/view_dir.c @@ -27,6 +27,7 @@ #include "filedata.h" #include "layout_image.h" #include "layout_util.h" +#include "menu.h" #include "pixbuf_util.h" #include "ui_fileops.h" #include "ui_tree_edit.h" @@ -107,7 +108,7 @@ static void vd_destroy_cb(GtkWidget *widget, gpointer data) g_free(vd); } -ViewDir *vd_new(DirViewType type, FileData *dir_fd) +ViewDir *vd_new(LayoutWindow *lw) { ViewDir *vd = g_new0(ViewDir, 1); @@ -116,13 +117,14 @@ ViewDir *vd_new(DirViewType type, FileData *dir_fd) gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vd->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + vd->layout = lw; vd->pf = folder_icons_new(vd->widget); - switch (type) - { - case DIRVIEW_LIST: vd = vdlist_new(vd, dir_fd); break; - case DIRVIEW_TREE: vd = vdtree_new(vd, dir_fd); break; - } + switch (lw->options.dir_view_type) + { + case DIRVIEW_LIST: vd = vdlist_new(vd, lw->dir_fd); break; + case DIRVIEW_TREE: vd = vdtree_new(vd, lw->dir_fd); break; + } gtk_container_add(GTK_CONTAINER(vd->widget), vd->view); @@ -142,7 +144,7 @@ ViewDir *vd_new(DirViewType type, FileData *dir_fd) file_data_register_notify_func(vd_notify_cb, vd, NOTIFY_PRIORITY_HIGH); /* vd_set_fd expects that vd_notify_cb is already registered */ - if (dir_fd) vd_set_fd(vd, dir_fd); + if (lw->dir_fd) vd_set_fd(vd, lw->dir_fd); gtk_widget_show(vd->view); @@ -623,12 +625,49 @@ static void vd_pop_menu_rename_cb(GtkWidget *widget, gpointer data) vd_rename_by_data(vd, vd->click_fd); } +static void vd_pop_menu_sort_ascend_cb(GtkWidget *widget, gpointer data) +{ + ViewDir *vd = data; + gboolean ascend; + + if (!vd) return; + + if (!vd->layout) return; + + ascend = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); + layout_views_set_sort(vd->layout, vd->layout->options.dir_view_list_sort.method, ascend); + + if (vd->layout) layout_refresh(vd->layout); +} + +static void vd_pop_menu_sort_cb(GtkWidget *widget, gpointer data) +{ + ViewDir *vd; + SortType type; + + vd = submenu_item_get_data(widget); + + if (!vd) return; + if (!vd->layout) return; + + type = (SortType)GPOINTER_TO_INT(data); + + if (type == SORT_NAME || type == SORT_TIME) + { + layout_views_set_sort(vd->layout, type, vd->layout->options.dir_view_list_sort.ascend); + + if (vd->layout) layout_refresh(vd->layout); + } +} + GtkWidget *vd_pop_menu(ViewDir *vd, FileData *fd) { GtkWidget *menu; gboolean active; gboolean rename_delete_active = FALSE; gboolean new_folder_active = FALSE; + GtkWidget *submenu; + GtkWidget *item; active = (fd != NULL); switch (vd->type) @@ -704,6 +743,14 @@ GtkWidget *vd_pop_menu(ViewDir *vd, FileData *fd) menu_item_add_radio(menu, _("View as _Tree"), GINT_TO_POINTER(DIRVIEW_TREE), vd->type == DIRVIEW_TREE, G_CALLBACK(vd_pop_submenu_dir_view_as_cb), vd); + if (vd->type == DIRVIEW_LIST) + { + submenu = submenu_add_dir_sort(NULL, G_CALLBACK(vd_pop_menu_sort_cb), vd, FALSE, FALSE, TRUE, vd->layout->options.dir_view_list_sort.method); + menu_item_add_check(submenu, _("Ascending"), vd->layout->options.dir_view_list_sort.ascend, G_CALLBACK(vd_pop_menu_sort_ascend_cb), (vd)); + item = menu_item_add(menu, _("_Sort"), NULL, NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + } + menu_item_add_divider(menu); menu_item_add_check(menu, _("Show _hidden files"), options->file_filter.show_hidden_files, diff --git a/src/view_dir.h b/src/view_dir.h index 724b11a1..d14ed3d8 100644 --- a/src/view_dir.h +++ b/src/view_dir.h @@ -31,7 +31,7 @@ enum { DIR_COLUMN_COUNT }; -ViewDir *vd_new(DirViewType type, FileData *dir_fd); +ViewDir *vd_new(LayoutWindow *lw); void vd_set_select_func(ViewDir *vdl, void (*func)(ViewDir *vdl, FileData *fd, gpointer data), gpointer data); diff --git a/src/view_dir_list.c b/src/view_dir_list.c index caa9cbfb..37211273 100644 --- a/src/view_dir_list.c +++ b/src/view_dir_list.c @@ -151,6 +151,12 @@ static gboolean vdlist_populate(ViewDir *vd, gboolean clear) gboolean sort_ascend = TRUE; gchar *link = NULL; + if (vd->layout) + { + sort_type = vd->layout->options.dir_view_list_sort.method; + sort_ascend = vd->layout->options.dir_view_list_sort.ascend; + } + old_list = VDLIST(vd)->list; ret = filelist_read(vd->dir_fd, NULL, &VDLIST(vd)->list); -- 2.20.1