Sort by name and date in folder list view
authorColin Clark <cclark@carbon>
Thu, 6 Feb 2020 14:51:32 +0000 (14:51 +0000)
committerColin Clark <cclark@carbon>
Thu, 6 Feb 2020 14:51:32 +0000 (14:51 +0000)
Ref: https://github.com/BestImageViewer/geeqie/issues/429

src/layout.c
src/layout.h
src/menu.c
src/menu.h
src/options.c
src/typedefs.h
src/view_dir.c
src/view_dir.h
src/view_dir_list.c

index 8f6c51a..6f5e209 100644 (file)
@@ -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;
index 2b33843..b78b6d6 100644 (file)
@@ -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);
index 7c2c7cd..a83f08c 100644 (file)
@@ -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)
index 52f58c9..517c472 100644 (file)
@@ -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);
index bab26ac..69dfe82 100644 (file)
@@ -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;
index 8cd5582..ce58f50 100644 (file)
@@ -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;
index 7c2d192..0fcdf27 100644 (file)
@@ -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,
index 724b11a..d14ed3d 100644 (file)
@@ -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);
 
index caa9cbf..3721127 100644 (file)
@@ -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);