Use FileCluster from view_file_icon to enable clustering of images.
authorOmari Stephens <xsdg@google.com>
Sat, 8 Jul 2017 21:56:55 +0000 (21:56 +0000)
committerOmari Stephens <xsdg@google.com>
Mon, 10 Jul 2017 08:00:55 +0000 (08:00 +0000)
(Also adds minimal support to view_file_list, but it's not usable yet)

src/filecluster.c
src/filecluster.h
src/view_file/view_file.c
src/view_file/view_file_icon.c
src/view_file/view_file_list.c

index f2fbc3e..a8cb22d 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "filecluster.h"
 
+#include "filedata.h"
+
 static gboolean check_list_contains_sublist(GList *haystack, GList *needle)
 {
        // TODO(xsdg): Optimize this!  Sort, then scan?
@@ -66,18 +68,32 @@ void filecluster_free(FileCluster *fc)
 FileCluster *fileclusterlist_create_cluster(FileClusterList *fcl, GList *fd_items)
 {
        GList *work;
+
+       // Check preconditions.
        if (!fd_items) return NULL;
-       if (!check_list_contains_sublist(fcl->fd_list, fd_items)) return NULL;
+       // TODO(xsdg): Is this actually necessary?
+       // if (!check_list_contains_sublist(fcl->fd_list, fd_items)) return NULL;
        for (work = fd_items; work; work = work->next)
-       {
+               {
                FileData *fd = work->data;
-               if (g_hash_table_contains(fcl->clusters, fd)) return NULL;
-       }
+               if (g_hash_table_contains(fcl->clusters, fd))
+                       {
+                       // TODO(xsdg): Show this warning in the UI.
+                       g_warning("Tried to create a cluster with a file that is already clustered.");
+                       return NULL;
+                       }
+               }
 
        FileCluster *new_fc = filecluster_new();
        new_fc->items = g_list_copy(fd_items);
        new_fc->head = new_fc->items;
 
+       for (GList *item = new_fc->items; item; item = item->next)
+               {
+               FileData *fd = item->data;
+               g_hash_table_insert(fcl->clusters, fd, new_fc);
+               }
+
        return new_fc;
 }
 
@@ -94,3 +110,25 @@ gboolean fileclusterlist_has_child(FileClusterList *fcl, FileData *fd)
        if (!fc) return FALSE;
        return fc->head->data != fd;
 }
+
+GList *filecluster_remove_children_from_list(FileClusterList *fcl, GList *list)
+{
+       GList *work = list;
+
+       while (work)
+       {
+               FileData *fd = work->data;
+               GList *link = work;
+               // Advance early in case link needs to be removed/freed.
+               work = work->next;
+
+               if (fileclusterlist_has_child(fcl, fd))
+               {
+                       list = g_list_remove_link(list, link);
+                       file_data_unref(fd);
+                       g_list_free(link);
+               }
+       }
+
+       return list;
+}
index 3b002dc..3b2956d 100644 (file)
@@ -34,5 +34,6 @@ FileCluster *fileclusterlist_create_cluster(FileClusterList *fcl, GList *fd_item
 gboolean fileclusterlist_has_head(FileClusterList *fcl, FileData *fd);
 gboolean fileclusterlist_has_child(FileClusterList *fcl, FileData *fd);
 
+GList *filecluster_remove_children_from_list(FileClusterList *fcl, GList *list);
 
 #endif  // FILECLUSTER_H
index c9dbdef..97fafae 100644 (file)
@@ -25,6 +25,7 @@
 #include "collect.h"
 #include "collect-table.h"
 #include "editors.h"
+#include "filecluster.h"
 #include "layout.h"
 #include "menu.h"
 #include "thumb.h"
@@ -673,6 +674,7 @@ static void vf_destroy_cb(GtkWidget *widget, gpointer data)
                gtk_widget_destroy(vf->popup);
                }
 
+       fileclusterlist_free(vf->cluster_list);
        file_data_unref(vf->dir_fd);
        g_free(vf->info);
        g_free(vf);
@@ -729,6 +731,7 @@ ViewFile *vf_new(FileViewType type, FileData *dir_fd)
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vf->scrolled),
                                       GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
+       vf->cluster_list = fileclusterlist_new();
        vf->filter = vf_marks_filter_init(vf);
 
        vf->widget = gtk_vbox_new(FALSE, 0);
index b60074c..e3ab038 100644 (file)
@@ -30,6 +30,7 @@
 #include "dnd.h"
 #include "editors.h"
 #include "img-view.h"
+#include "filecluster.h"
 #include "filedata.h"
 #include "layout.h"
 #include "layout_image.h"
@@ -1250,6 +1251,33 @@ gboolean vficon_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer dat
                        vf->popup = vf_pop_menu(vf);
                        gtk_menu_popup(GTK_MENU(vf->popup), NULL, NULL, vfi_menu_position_cb, vf, 0, GDK_CURRENT_TIME);
                        break;
+               case GDK_KEY_Insert:
+                       // DO NOT SUBMIT
+                       // TODO(xsdg): make an actual UX for this.
+                       g_warning("Starting a cluster!");
+                       fd = vficon_find_data(vf, VFICON(vf)->focus_row, VFICON(vf)->focus_column, NULL);
+                       if (fd)
+                               {
+                               // Make a cluster out of the entire selection
+                               if (VFICON(vf)->selection && VFICON(vf)->selection->next)
+                                       {
+                                       // At least two items selected; go for it.
+                                       g_warning("Had requisite number of selection items; going for it!");
+                                       fileclusterlist_create_cluster(vf->cluster_list, VFICON(vf)->selection);
+                                       }
+                               else
+                                       {
+                                       if (VFICON(vf)->selection)
+                                               {
+                                               g_warning("Only one item selected; need at least two.");
+                                               }
+                                       else
+                                               {
+                                               g_warning("No items selected; need at least two.");
+                                               }
+                                       }
+                               }
+                       break;
                default:
                        stop_signal = FALSE;
                        break;
@@ -1796,9 +1824,11 @@ static gboolean vficon_refresh_real(ViewFile *vf, gboolean keep_position)
                {
                ret = filelist_read(vf->dir_fd, &new_filelist, NULL);
                new_filelist = file_data_filter_marks_list(new_filelist, vf_marks_get_filter(vf));
+               new_filelist = filecluster_remove_children_from_list(vf->cluster_list, new_filelist);
                }
 
-       vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */
+       /* the list might not be sorted if there were renames */
+       vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend);
        new_filelist = filelist_sort(new_filelist, vf->sort_method, vf->sort_ascend);
 
        if (VFICON(vf)->selection)
index b56a025..15a71c5 100644 (file)
@@ -27,6 +27,7 @@
 #include "dnd.h"
 #include "editors.h"
 #include "img-view.h"
+#include "filecluster.h"
 #include "layout.h"
 #include "layout_image.h"
 #include "menu.h"
@@ -1668,6 +1669,7 @@ gboolean vflist_refresh(ViewFile *vf)
                        }
 
                vf->list = file_data_filter_marks_list(vf->list, vf_marks_get_filter(vf));
+               vf->list = filecluster_remove_children_from_list(vf->cluster_list, vf->list);
                file_data_register_notify_func(vf_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
                DEBUG_1("%s vflist_refresh: sort", get_exec_time());