[gthumb] selections: save at exit and restore at start



commit 69dd3e391be613342d821b16b7165a36506a81de
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Tue Jul 4 13:40:32 2017 +0200

    selections: save at exit and restore at start

 extensions/selections/callbacks.c              |   33 +++++-
 extensions/selections/callbacks.h              |    3 +
 extensions/selections/gth-selections-manager.c |  173 ++++++++++++++++++++++++
 extensions/selections/gth-selections-manager.h |    4 +-
 extensions/selections/main.c                   |    3 +
 5 files changed, 214 insertions(+), 2 deletions(-)
---
diff --git a/extensions/selections/callbacks.c b/extensions/selections/callbacks.c
index 3c9e1a4..95d63fd 100644
--- a/extensions/selections/callbacks.c
+++ b/extensions/selections/callbacks.c
@@ -103,7 +103,7 @@ _selection_button_new (int      n_selection,
        gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name (gth_selection_get_icon_name 
(n_selection), GTK_ICON_SIZE_MENU));
        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
        gtk_widget_show_all (button);
-       gtk_widget_set_sensitive (button, FALSE);
+       gtk_widget_set_sensitive (button, ! gth_selections_manager_get_is_empty (n_selection));
        gtk_widget_set_tooltip_text (button, tooltip);
 
        g_signal_connect (button,
@@ -161,6 +161,13 @@ folder_changed_cb (GthMonitor      *monitor,
 
 
 void
+selections__initialize_cb (void)
+{
+       gth_selections_manager_load_from_file ();
+}
+
+
+void
 selections__gth_browser_construct_cb (GthBrowser *browser)
 {
        BrowserData *data;
@@ -192,6 +199,30 @@ selections__gth_browser_construct_cb (GthBrowser *browser)
 }
 
 
+void
+selections__gth_browser_close_last_window_cb (GthBrowser *browser)
+{
+       gth_selections_manager_save_to_file ();
+}
+
+
+void
+selections__gth_browser_update_sensitivity_cb (GthBrowser *browser)
+{
+       BrowserData *data;
+       int          n_selected;
+
+       if (! GTH_IS_FILE_SOURCE_SELECTIONS (gth_browser_get_location_source (browser)))
+               return;
+
+       data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+       g_return_if_fail (data != NULL);
+
+       n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view 
(browser)));
+       gth_window_enable_action (GTH_WINDOW (browser), "go-to-container-from-selection", n_selected == 1);
+}
+
+
 static guint
 get_numeric_keyval (GthBrowser  *browser,
                    GdkEventKey *event)
diff --git a/extensions/selections/callbacks.h b/extensions/selections/callbacks.h
index 0bff3bb..0fa9aff 100644
--- a/extensions/selections/callbacks.h
+++ b/extensions/selections/callbacks.h
@@ -24,7 +24,10 @@
 
 #include <gthumb.h>
 
+void      selections__initialize_cb                     (void);
 void      selections__gth_browser_construct_cb           (GthBrowser   *browser);
+void      selections__gth_browser_close_last_window_cb   (GthBrowser   *browser);
+void      selections__gth_browser_update_sensitivity_cb  (GthBrowser   *browser);
 gpointer  selections__gth_browser_file_list_key_press_cb (GthBrowser   *browser,
                                                          GdkEventKey  *event);
 void      selections__gth_browser_load_location_after_cb (GthBrowser   *browser,
diff --git a/extensions/selections/gth-selections-manager.c b/extensions/selections/gth-selections-manager.c
index f7423c7..a386d01 100644
--- a/extensions/selections/gth-selections-manager.c
+++ b/extensions/selections/gth-selections-manager.c
@@ -33,6 +33,8 @@ struct _GthSelectionsManagerPrivate {
        char       *order[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
        gboolean    order_inverse[GTH_SELECTIONS_MANAGER_N_SELECTIONS];
        GMutex      mutex;
+       gboolean    loaded;
+       gboolean    changed;
 };
 
 
@@ -106,6 +108,8 @@ gth_selections_manager_init (GthSelectionsManager *self)
                self->priv->order[i] = NULL;
                self->priv->order_inverse[i] = FALSE;
        }
+       self->priv->loaded = FALSE;
+       self->priv->changed = FALSE;
 }
 
 
@@ -293,6 +297,88 @@ _gth_selections_manager_for_each_selection (gpointer user_data)
 }
 
 
+static void
+_gth_selections_manager_load_from_node (GthSelectionsManager *self,
+                                       DomElement           *node)
+{
+       DomElement *child;
+       int         n_selection;
+       GList      *file_list;
+
+       n_selection = atoi (dom_element_get_attribute (node, "n"));
+       if ((n_selection < 0) || (n_selection > GTH_SELECTIONS_MANAGER_N_SELECTIONS))
+               return;
+
+       g_hash_table_remove_all (self->priv->files_hash[n_selection - 1]);
+       _g_object_list_unref (self->priv->files[n_selection - 1]);
+       self->priv->files[n_selection - 1] = NULL;
+
+       file_list = NULL;
+       for (child = node->first_child; child; child = child->next_sibling) {
+               if (g_strcmp0 (child->tag_name, "file") == 0) {
+                       const char *uri;
+
+                       uri = dom_element_get_attribute (child, "uri");
+                       if (uri != NULL) {
+                               GFile *file = g_file_new_for_uri (uri);
+                               file_list = g_list_prepend (file_list, file);
+                               g_hash_table_insert (self->priv->files_hash[n_selection - 1], file, 
GINT_TO_POINTER (1));
+                       }
+               }
+       }
+       self->priv->files[n_selection - 1] = g_list_reverse (file_list);
+}
+
+
+static void
+_gth_selections_manager_load_if_required (GthSelectionsManager *self)
+{
+       GFile       *file;
+       char        *buffer;
+       gsize        size;
+       DomDocument *doc;
+
+       if (self->priv->loaded)
+               return;
+
+       file = gth_user_dir_get_file_for_read (GTH_DIR_DATA, GTHUMB_DIR, "selections.xml", NULL);
+       if (! _g_file_load_in_buffer (file, (void **) &buffer, &size, NULL, NULL)) {
+               g_object_unref (file);
+               return;
+       }
+
+       g_mutex_lock (&self->priv->mutex);
+
+       doc = dom_document_new ();
+       if (dom_document_load (doc, buffer, size, NULL)) {
+               DomElement *root = DOM_ELEMENT (doc)->first_child;
+
+               if (g_strcmp0 (root->tag_name, "selections") == 0) {
+                       DomElement *child;
+                       for (child = root->first_child; child; child = child->next_sibling) {
+                               if (g_strcmp0 (child->tag_name, "selection") == 0)
+                                       _gth_selections_manager_load_from_node (self, child);
+                       }
+               }
+       }
+
+       self->priv->loaded = TRUE;
+
+       g_mutex_unlock (&self->priv->mutex);
+
+       g_object_unref (doc);
+       g_free (buffer);
+       g_object_unref (file);
+}
+
+
+static void
+_gth_selections_manager_changed (GthSelectionsManager *self)
+{
+       self->priv->changed = TRUE;
+}
+
+
 void
 gth_selections_manager_for_each_child (GFile                *folder,
                                       const char           *attributes,
@@ -308,6 +394,8 @@ gth_selections_manager_for_each_child (GFile                *folder,
        self = gth_selections_manager_get_default ();
        n_selection = _g_file_get_n_selection (folder);
 
+       _gth_selections_manager_load_if_required (self);
+
        g_mutex_lock (&self->priv->mutex);
        data = g_new0 (ForEachChildData, 1);
        data->selections_manager = self;
@@ -356,6 +444,8 @@ gth_selections_manager_add_files (GFile *folder,
        if (n_selection <= 0)
                return FALSE;
 
+       _gth_selections_manager_load_if_required (self);
+
        g_mutex_lock (&self->priv->mutex);
 
        new_list = _g_file_list_dup (file_list);
@@ -382,6 +472,7 @@ gth_selections_manager_add_files (GFile *folder,
 
        g_mutex_unlock (&self->priv->mutex);
 
+       _gth_selections_manager_changed (self);
        gth_monitor_emblems_changed (gth_main_get_default_monitor (), file_list);
        gth_monitor_folder_changed (gth_main_get_default_monitor (),
                                    folder,
@@ -408,6 +499,8 @@ gth_selections_manager_remove_files (GFile    *folder,
        if (n_selection <= 0)
                return;
 
+       _gth_selections_manager_load_if_required (self);
+
        g_mutex_lock (&self->priv->mutex);
 
        files_to_remove = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
@@ -434,6 +527,7 @@ gth_selections_manager_remove_files (GFile    *folder,
 
        g_mutex_unlock (&self->priv->mutex);
 
+       _gth_selections_manager_changed (self);
        if (notify)
                gth_monitor_folder_changed (gth_main_get_default_monitor (),
                                            folder,
@@ -460,6 +554,8 @@ gth_selections_manager_reorder (GFile *folder,
 
        self = gth_selections_manager_get_default ();
 
+       _gth_selections_manager_load_if_required (self);
+
        /* reorder the file list */
 
        g_mutex_lock (&self->priv->mutex);
@@ -475,6 +571,7 @@ gth_selections_manager_reorder (GFile *folder,
 
        gth_selections_manager_set_sort_type (folder, "general::unsorted", FALSE);
 
+       _gth_selections_manager_changed (self);
        gth_monitor_order_changed (gth_main_get_default_monitor (),
                                   folder,
                                   new_order);
@@ -503,6 +600,8 @@ gth_selections_manager_set_sort_type (GFile      *folder,
        self->priv->order_inverse[n_selection - 1] = sort_inverse;
 
        g_mutex_unlock (&self->priv->mutex);
+
+       _gth_selections_manager_changed (self);
 }
 
 
@@ -517,6 +616,7 @@ gth_selections_manager_file_exists (int    n_selection,
                return FALSE;
 
        self = gth_selections_manager_get_default ();
+       _gth_selections_manager_load_if_required (self);
        g_mutex_lock (&self->priv->mutex);
 
        result = (g_hash_table_lookup (self->priv->files_hash[n_selection - 1], file) != NULL);
@@ -537,6 +637,7 @@ gth_selections_manager_get_is_empty (int n_selection)
                return TRUE;
 
        self = gth_selections_manager_get_default ();
+       _gth_selections_manager_load_if_required (self);
        g_mutex_lock (&self->priv->mutex);
 
        size = g_hash_table_size (self->priv->files_hash[n_selection - 1]);
@@ -547,6 +648,78 @@ gth_selections_manager_get_is_empty (int n_selection)
 }
 
 
+static DomElement *
+_gth_selections_manager_create_selection_node (GthSelectionsManager *self,
+                                              int                   n_selection,
+                                              DomDocument          *doc)
+{
+       char       *n_selection_txt;
+       DomElement *selection_node;
+       GList      *scan;
+
+       n_selection_txt = g_strdup_printf ("%d", n_selection);
+       selection_node = dom_document_create_element (doc, "selection", "n", n_selection_txt, NULL);
+       for (scan = self->priv->files[n_selection - 1]; scan; scan = scan->next) {
+               GFile *file = scan->data;
+               char  *uri;
+
+               uri = g_file_get_uri (file);
+               dom_element_append_child (selection_node, dom_document_create_element (doc, "file", "uri", 
uri, NULL));
+
+               g_free (uri);
+       }
+
+       g_free (n_selection_txt);
+
+       return selection_node;
+}
+
+
+void
+gth_selections_manager_load_from_file (void)
+{
+       GthSelectionsManager *self;
+
+       self = gth_selections_manager_get_default ();
+       _gth_selections_manager_load_if_required (self);
+}
+
+
+void
+gth_selections_manager_save_to_file (void)
+{
+       GthSelectionsManager *self;
+       DomDocument          *doc;
+       DomElement           *root, *selections;
+       GFile                *file;
+       char                 *buffer;
+       gsize                 size;
+
+       self = gth_selections_manager_get_default ();
+       if (! self->priv->changed)
+               return;
+
+       g_mutex_lock (&self->priv->mutex);
+
+       doc = dom_document_new ();
+       root = DOM_ELEMENT (doc);
+       selections = dom_document_create_element (doc, "selections", NULL);
+       dom_element_append_child (root, selections);
+       for (int i = 1; i <= GTH_SELECTIONS_MANAGER_N_SELECTIONS; i++)
+               dom_element_append_child (selections, _gth_selections_manager_create_selection_node (self, i, 
doc));
+
+       buffer = dom_document_dump (doc, &size);
+       file = gth_user_dir_get_file_for_write (GTH_DIR_DATA, GTHUMB_DIR, "selections.xml", NULL);
+       _g_file_write (file, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, buffer, size, NULL, NULL);
+       self->priv->changed = FALSE;
+
+       g_mutex_unlock (&self->priv->mutex);
+
+       g_object_unref (file);
+       g_free (buffer);
+}
+
+
 int
 _g_file_get_n_selection (GFile *file)
 {
diff --git a/extensions/selections/gth-selections-manager.h b/extensions/selections/gth-selections-manager.h
index 076714f..262882a 100644
--- a/extensions/selections/gth-selections-manager.h
+++ b/extensions/selections/gth-selections-manager.h
@@ -76,6 +76,8 @@ void     gth_selections_manager_update_file_info (GFile                *file,
 gboolean gth_selections_manager_file_exists      (int                   n_selection,
                                                  GFile                *file);
 gboolean gth_selections_manager_get_is_empty     (int                   n_selection);
+void     gth_selections_manager_load_from_file   (void);
+void     gth_selections_manager_save_to_file     (void);
 
 /* utilities */
 
@@ -83,7 +85,7 @@ int      _g_file_get_n_selection                 (GFile                *file);
 const char *
         gth_selection_get_icon_name             (int                   n_selection);
 const char *
-       gth_selection_get_symbolic_icon_name     (int                   n_selection);
+        gth_selection_get_symbolic_icon_name    (int                   n_selection);
 
 G_END_DECLS
 
diff --git a/extensions/selections/main.c b/extensions/selections/main.c
index abd97ad..57afce5 100644
--- a/extensions/selections/main.c
+++ b/extensions/selections/main.c
@@ -33,7 +33,10 @@ gthumb_extension_activate (void)
 {
        gth_main_register_file_source (GTH_TYPE_FILE_SOURCE_SELECTIONS);
        gth_main_register_metadata_provider (GTH_TYPE_METADATA_PROVIDER_SELECTIONS);
+       gth_hook_add_callback ("initialize", 10, G_CALLBACK (selections__initialize_cb), NULL);
        gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK 
(selections__gth_browser_construct_cb), NULL);
+       gth_hook_add_callback ("gth-browser-close-last-window", 10, G_CALLBACK 
(selections__gth_browser_close_last_window_cb), NULL);
+       gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK 
(selections__gth_browser_update_sensitivity_cb), NULL);
        gth_hook_add_callback ("gth-browser-file-list-key-press", 10, G_CALLBACK 
(selections__gth_browser_file_list_key_press_cb), NULL);
        gth_hook_add_callback ("gth-browser-load-location-after", 10, G_CALLBACK 
(selections__gth_browser_load_location_after_cb), NULL);
        gth_hook_add_callback ("gth-browser-update-extra-widget", 20, G_CALLBACK 
(selections__gth_browser_update_extra_widget_cb), NULL);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]