[gthumb] shortcuts: save changes to file, load on startup



commit 2cb3013bfe7bed61b269dcdab90c1f78da365708
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Nov 11 17:29:22 2019 +0100

    shortcuts: save changes to file, load on startup

 gthumb/dlg-preferences-shortcuts.c |  21 +++++---
 gthumb/gth-browser.c               |  17 +++++++
 gthumb/gth-main.c                  |   9 ++++
 gthumb/gth-main.h                  |   1 +
 gthumb/gth-monitor.c               |  21 ++++++++
 gthumb/gth-monitor.h               |   2 +
 gthumb/gth-shortcut.c              | 102 +++++++++++++++++++++++++++++++++++++
 gthumb/gth-shortcut.h              |   5 ++
 gthumb/gth-window.c                |  13 ++++-
 gthumb/gth-window.h                |   1 +
 gthumb/typedefs.h                  |   1 +
 11 files changed, 186 insertions(+), 7 deletions(-)
---
diff --git a/gthumb/dlg-preferences-shortcuts.c b/gthumb/dlg-preferences-shortcuts.c
index 647d049e..15acdac3 100644
--- a/gthumb/dlg-preferences-shortcuts.c
+++ b/gthumb/dlg-preferences-shortcuts.c
@@ -87,6 +87,18 @@ row_data_free (RowData *row_data)
 }
 
 
+static void
+row_data_update_shortcut (RowData         *row_data,
+                         guint            keycode,
+                         GdkModifierType  modifiers)
+{
+       gth_shortcut_set_key (row_data->shortcut, keycode, modifiers);
+       gtk_label_set_text (GTK_LABEL (row_data->accel_label), row_data->shortcut->label);
+
+       gth_main_shortcuts_changed (gth_window_get_shortcuts (GTH_WINDOW (row_data->browser_data->browser)));
+}
+
+
 static void
 accel_dialog_response_cb (GtkDialog *dialog,
                          gint       response_id,
@@ -98,10 +110,8 @@ accel_dialog_response_cb (GtkDialog *dialog,
 
        switch (response_id) {
        case GTK_RESPONSE_OK:
-               if (gth_accel_dialog_get_accel (GTH_ACCEL_DIALOG (dialog), &keycode, &modifiers)) {
-                       gth_shortcut_set_key (row_data->shortcut, keycode, modifiers);
-                       gtk_label_set_text (GTK_LABEL (row_data->accel_label), row_data->shortcut->label);
-               }
+               if (gth_accel_dialog_get_accel (GTH_ACCEL_DIALOG (dialog), &keycode, &modifiers))
+                       row_data_update_shortcut (row_data, keycode, modifiers);
                gtk_widget_destroy (GTK_WIDGET (dialog));
                break;
 
@@ -110,8 +120,7 @@ accel_dialog_response_cb (GtkDialog *dialog,
                break;
 
        case GTH_ACCEL_BUTTON_RESPONSE_DELETE:
-               gth_shortcut_set_key (row_data->shortcut, 0, 0);
-               gtk_label_set_text (GTK_LABEL (row_data->accel_label), row_data->shortcut->label);
+               row_data_update_shortcut (row_data, 0, 0);
                gtk_widget_destroy (GTK_WIDGET (dialog));
                break;
        }
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index dd828f1a..4d9501f5 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -142,6 +142,7 @@ struct _GthBrowserPrivate {
        gulong             emblems_changed_id;
        gulong             entry_points_changed_id;
        gulong             order_changed_id;
+       gulong             shortcuts_changed_id;
        GthFileData       *location;
        GthFileData       *current_file;
        GthFileSource     *location_source;
@@ -2082,6 +2083,8 @@ _gth_browser_real_close (GthBrowser *browser)
                                     browser->priv->entry_points_changed_id);
        g_signal_handler_disconnect (gth_main_get_default_monitor (),
                                     browser->priv->order_changed_id);
+       g_signal_handler_disconnect (gth_main_get_default_monitor (),
+                                    browser->priv->shortcuts_changed_id);
 
        /* remove timeouts */
 
@@ -3504,6 +3507,14 @@ order_changed_cb (GthMonitor *monitor,
 }
 
 
+static void
+shortcuts_changed_cb (GthMonitor *monitor,
+                     GthBrowser *browser)
+{
+       gth_window_load_shortcuts (GTH_WINDOW (browser));
+}
+
+
 static void
 pref_general_filter_changed (GSettings  *settings,
                             const char *key,
@@ -4807,6 +4818,11 @@ gth_browser_init (GthBrowser *browser)
                                  "order-changed",
                                  G_CALLBACK (order_changed_cb),
                                  browser);
+       browser->priv->shortcuts_changed_id =
+               g_signal_connect (gth_main_get_default_monitor (),
+                                 "shortcuts-changed",
+                                 G_CALLBACK (shortcuts_changed_cb),
+                                 browser);
 
        /* init browser data */
 
@@ -4900,6 +4916,7 @@ gth_browser_init (GthBrowser *browser)
 
        gtk_widget_realize (browser->priv->file_list);
        gth_hook_invoke ("gth-browser-construct", browser);
+       gth_window_load_shortcuts (GTH_WINDOW (browser));
 
        performance (DEBUG_INFO, "window initialized");
 
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index d47508d7..72dc9afa 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -32,6 +32,7 @@
 #include "gth-metadata-provider.h"
 #include "gth-user-dir.h"
 #include "gth-preferences.h"
+#include "gth-shortcut.h"
 #include "gtk-utils.h"
 #include "pixbuf-io.h"
 #include "typedefs.h"
@@ -1152,6 +1153,14 @@ gth_main_bookmarks_changed (void)
 }
 
 
+void
+gth_main_shortcuts_changed (GPtrArray *shortcuts_v)
+{
+       if (gth_shortcuts_write_to_file (shortcuts_v, NULL))
+               gth_monitor_shortcuts_changed (gth_main_get_default_monitor ());
+}
+
+
 GthFilterFile *
 gth_main_get_default_filter_file (void)
 {
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index b9fba344..bd0b8153 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -112,6 +112,7 @@ void                   gth_main_register_type                 (const char
 GArray *               gth_main_get_type_set                  (const char           *set_name);
 GBookmarkFile *        gth_main_get_default_bookmarks         (void);
 void                   gth_main_bookmarks_changed             (void);
+void                   gth_main_shortcuts_changed             (GPtrArray *shortcuts_v);
 GthFilterFile *        gth_main_get_default_filter_file       (void);
 GList *                gth_main_get_all_filters               (void);
 void                   gth_main_filters_changed               (void);
diff --git a/gthumb/gth-monitor.c b/gthumb/gth-monitor.c
index c297fc1a..46cdca04 100644
--- a/gthumb/gth-monitor.c
+++ b/gthumb/gth-monitor.c
@@ -33,6 +33,7 @@
 enum {
        ICON_THEME_CHANGED,
        BOOKMARKS_CHANGED,
+       SHORTCUTS_CHANGED,
        FILTERS_CHANGED,
        TAGS_CHANGED,
        FOLDER_CONTENT_CHANGED,
@@ -106,6 +107,15 @@ gth_monitor_class_init (GthMonitorClass *class)
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE,
                              0);
+       monitor_signals[SHORTCUTS_CHANGED] =
+               g_signal_new ("shortcuts-changed",
+                             G_TYPE_FROM_CLASS (class),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GthMonitorClass, shortcuts_changed),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE,
+                             0);
        monitor_signals[FILTERS_CHANGED] =
                g_signal_new ("filters-changed",
                              G_TYPE_FROM_CLASS (class),
@@ -253,6 +263,17 @@ gth_monitor_bookmarks_changed (GthMonitor *self)
 }
 
 
+void
+gth_monitor_shortcuts_changed (GthMonitor *self)
+{
+       g_return_if_fail (GTH_IS_MONITOR (self));
+
+       g_signal_emit (G_OBJECT (self),
+                      monitor_signals[SHORTCUTS_CHANGED],
+                      0);
+}
+
+
 void
 gth_monitor_filters_changed (GthMonitor *self)
 {
diff --git a/gthumb/gth-monitor.h b/gthumb/gth-monitor.h
index 8ffd3ad4..e659b3de 100644
--- a/gthumb/gth-monitor.h
+++ b/gthumb/gth-monitor.h
@@ -61,6 +61,7 @@ struct _GthMonitorClass
 
        void   (*icon_theme_changed)      (GthMonitor      *monitor);
        void   (*bookmarks_changed)       (GthMonitor      *monitor);
+       void   (*shortcuts_changed)       (GthMonitor      *monitor);
        void   (*filters_changed)         (GthMonitor      *monitor);
        void   (*tags_changed)            (GthMonitor      *monitor);
        void   (*folder_changed)          (GthMonitor      *monitor,
@@ -89,6 +90,7 @@ void          gth_monitor_resume                     (GthMonitor      *monitor,
                                                      GFile           *file);
 void          gth_monitor_icon_theme_changed         (GthMonitor      *monitor);
 void          gth_monitor_bookmarks_changed          (GthMonitor      *monitor);
+void          gth_monitor_shortcuts_changed          (GthMonitor      *monitor);
 void          gth_monitor_filters_changed            (GthMonitor      *monitor);
 void          gth_monitor_tags_changed               (GthMonitor      *monitor);
 void          gth_monitor_folder_changed             (GthMonitor      *monitor,
diff --git a/gthumb/gth-shortcut.c b/gthumb/gth-shortcut.c
index 6681ee00..ec407b5e 100644
--- a/gthumb/gth-shortcut.c
+++ b/gthumb/gth-shortcut.c
@@ -20,7 +20,11 @@
  */
 
 #include <config.h>
+#include <glib/gi18n.h>
+#include "dom.h"
+#include "gio-utils.h"
 #include "gth-shortcut.h"
+#include "gth-user-dir.h"
 
 
 GthShortcut *
@@ -146,3 +150,101 @@ gth_shortcut_valid (guint           keycode,
 
        return FALSE;
 }
+
+
+gboolean
+gth_shortcuts_write_to_file (GPtrArray  *shortcuts_v,
+                            GError    **error)
+{
+       DomDocument *doc;
+       DomElement  *shortcuts;
+       int          i;
+       char        *buffer;
+       gsize        size;
+       GFile       *file;
+       gboolean     result;
+
+       doc = dom_document_new ();
+       shortcuts = dom_document_create_element (doc, "shortcuts", NULL);
+       for (i = 0; i < shortcuts_v->len; i++) {
+               GthShortcut *shortcut = g_ptr_array_index (shortcuts_v, i);
+
+               if (shortcut->context == GTH_SHORTCUT_CONTEXT_INTERNAL)
+                       continue;
+
+               dom_element_append_child (shortcuts,
+                       dom_document_create_element (doc, "shortcut",
+                                                    "action", shortcut->action_name,
+                                                    "accelerator", shortcut->accelerator,
+                                                    NULL));
+       }
+       dom_element_append_child (DOM_ELEMENT (doc), shortcuts);
+
+       buffer = dom_document_dump (doc, &size);
+       file = gth_user_dir_get_file_for_write (GTH_DIR_CONFIG, GTHUMB_DIR, SHORTCUTS_FILE, NULL);
+       result = _g_file_write (file, FALSE, G_FILE_CREATE_NONE, buffer, size, NULL, error);
+
+       g_object_unref (file);
+       g_free (buffer);
+       g_object_unref (doc);
+
+       return result;
+}
+
+
+gboolean
+gth_shortcuts_load_from_file (GPtrArray  *shortcuts_v,
+                             GHashTable *shortcuts,
+                             GError    **error)
+{
+       gboolean  success = FALSE;
+       GFile    *file;
+       void     *buffer;
+       gsize     size;
+
+       file = gth_user_dir_get_file_for_write (GTH_DIR_CONFIG, GTHUMB_DIR, SHORTCUTS_FILE, NULL);
+       if (_g_file_load_in_buffer (file, &buffer, &size, NULL, error)) {
+               DomDocument *doc;
+
+               doc = dom_document_new ();
+               if (dom_document_load (doc, buffer, size, error)) {
+                       DomElement *node;
+
+                       for (node = DOM_ELEMENT (doc)->first_child; node; node = node->next_sibling) {
+                               if (g_strcmp0 (node->tag_name, "shortcuts") == 0) {
+                                       DomElement *shortcut_node;
+
+                                       for (shortcut_node = node->first_child; shortcut_node; shortcut_node 
= shortcut_node->next_sibling) {
+                                               if (g_strcmp0 (shortcut_node->tag_name, "shortcut") == 0) {
+                                                       const char  *action_name;
+                                                       const char  *accelerator;
+                                                       GthShortcut *shortcut;
+
+                                                       action_name = dom_element_get_attribute 
(shortcut_node, "action");
+                                                       accelerator = dom_element_get_attribute 
(shortcut_node, "accelerator");
+
+                                                       if (action_name == NULL)
+                                                               continue;
+
+                                                       shortcut = g_hash_table_lookup (shortcuts, 
action_name);
+                                                       if (shortcut != NULL)
+                                                               gth_shortcut_set_accelerator (shortcut, 
accelerator);
+                                               }
+                                       }
+
+                                       success = TRUE;
+                               }
+                       }
+               }
+
+               if (! success && (error != NULL))
+                       *error = g_error_new_literal (DOM_ERROR, DOM_ERROR_INVALID_FORMAT, _("Invalid file 
format"));
+
+               g_object_unref (doc);
+               g_free (buffer);
+       }
+
+       g_object_unref (file);
+
+       return success;
+}
diff --git a/gthumb/gth-shortcut.h b/gthumb/gth-shortcut.h
index fcf23644..4ffc7ee7 100644
--- a/gthumb/gth-shortcut.h
+++ b/gthumb/gth-shortcut.h
@@ -57,6 +57,11 @@ GthShortcut * gth_shortcut_array_find           (GPtrArray         *shortcuts_v,
                                                 GdkModifierType    modifiers);
 gboolean      gth_shortcut_valid                (guint              keycode,
                                                 GdkModifierType    modifiers);
+gboolean      gth_shortcuts_write_to_file       (GPtrArray         *shortcuts_v,
+                                                GError           **error);
+gboolean      gth_shortcuts_load_from_file      (GPtrArray         *shortcuts_v,
+                                                GHashTable        *shortcuts,
+                                                GError           **error);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-window.c b/gthumb/gth-window.c
index 8eda3551..9ea418ec 100644
--- a/gthumb/gth-window.c
+++ b/gthumb/gth-window.c
@@ -706,7 +706,7 @@ _gth_window_add_shortcut (GthWindow   *window,
 {
        g_hash_table_insert (window->priv->shortcuts,
                             g_strdup (shorcut->action_name),
-                            GINT_TO_POINTER (1));
+                            shorcut);
        g_ptr_array_add (window->priv->shortcuts_v, shorcut);
 }
 
@@ -850,3 +850,14 @@ gth_window_activate_shortcut (GthWindow       *window,
 
        return activated;
 }
+
+
+void
+gth_window_load_shortcuts (GthWindow *window)
+{
+       g_return_if_fail (GTH_IS_WINDOW (window));
+
+       gth_shortcuts_load_from_file (window->priv->shortcuts_v,
+                                     window->priv->shortcuts,
+                                     NULL);
+}
diff --git a/gthumb/gth-window.h b/gthumb/gth-window.h
index e6bf2e89..0d14e7b7 100644
--- a/gthumb/gth-window.h
+++ b/gthumb/gth-window.h
@@ -129,6 +129,7 @@ gboolean    gth_window_activate_shortcut    (GthWindow              *window,
                                                 int                     context,
                                                 guint                   keycode,
                                                 GdkModifierType         modifiers);
+void           gth_window_load_shortcuts       (GthWindow              *window);
 
 G_END_DECLS
 
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index 0bb6b9ec..c6b0efae 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -31,6 +31,7 @@ G_BEGIN_DECLS
 #define FILTERS_FILE   "filters.xml"
 #define TAGS_FILE      "tags.xml"
 #define FILE_CACHE     "cache"
+#define SHORTCUTS_FILE "shortcuts.xml"
 
 
 typedef enum {


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