[gthumb] fixed installation of the accelerators specified in the menus



commit c4a092af6be9a2e4c8e7f67c2b79fe015f60f13b
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Oct 19 18:04:42 2013 +0200

    fixed installation of the accelerators specified in the menus

 extensions/bookmarks/callbacks.c               |    5 +-
 extensions/bookmarks/data/ui/bookmarks-menu.ui |    4 +-
 gthumb/gth-browser-actions-entries.h           |    8 +-
 gthumb/gth-browser.c                           |   17 ++-
 gthumb/gth-window.c                            |   37 ++++--
 gthumb/gth-window.h                            |    9 +-
 gthumb/gtk-utils.c                             |  163 +++++++++++++++++++++++-
 gthumb/gtk-utils.h                             |   12 ++
 gthumb/resources/app-menu.ui                   |    3 +
 gthumb/resources/gears-menu.ui                 |   10 +-
 10 files changed, 237 insertions(+), 31 deletions(-)
---
diff --git a/extensions/bookmarks/callbacks.c b/extensions/bookmarks/callbacks.c
index ad1456f..0dc25be 100644
--- a/extensions/bookmarks/callbacks.c
+++ b/extensions/bookmarks/callbacks.c
@@ -319,6 +319,7 @@ bookmarks__gth_browser_construct_cb (GthBrowser *browser)
        {
                GtkWidget  *button;
                GtkBuilder *builder;
+               GMenuModel *menu;
 
                button = _gtk_menu_button_new_for_header_bar ();
                gtk_widget_set_tooltip_text (button, _("Bookmarks"));
@@ -329,7 +330,9 @@ bookmarks__gth_browser_construct_cb (GthBrowser *browser)
                data->entry_points_menu = G_MENU (gtk_builder_get_object (builder, "entry-points"));
                data->bookmarks_menu = G_MENU (gtk_builder_get_object (builder, "bookmarks"));
 
-               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), G_MENU_MODEL 
(gtk_builder_get_object (builder, "bookmarks-menu")));
+               menu = G_MENU_MODEL (gtk_builder_get_object (builder, "bookmarks-menu"));
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
+               _gtk_window_add_accelerators_from_menu ((GTK_WINDOW (browser)), menu);
 
                gtk_widget_show_all (button);
                gtk_box_pack_start (GTK_BOX (gth_browser_get_headerbar_section (browser, 
GTH_BROWSER_HEADER_SECTION_BROWSER_COMMANDS)), button, FALSE, FALSE, 0);
diff --git a/extensions/bookmarks/data/ui/bookmarks-menu.ui b/extensions/bookmarks/data/ui/bookmarks-menu.ui
index 3511bb5..adcb55a 100644
--- a/extensions/bookmarks/data/ui/bookmarks-menu.ui
+++ b/extensions/bookmarks/data/ui/bookmarks-menu.ui
@@ -6,12 +6,12 @@
       <item>
         <attribute name="label" translatable="yes">_Add Bookmark</attribute>
         <attribute name="action">win.bookmarks-add</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>D]]></attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>d]]></attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Edit Bookmarks…</attribute>
         <attribute name="action">win.bookmarks-edit</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>B]]></attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>b]]></attribute>
       </item>
     </section>
     <submenu id="system-bookmarks">
diff --git a/gthumb/gth-browser-actions-entries.h b/gthumb/gth-browser-actions-entries.h
index 0cb01fd..0f823e2 100644
--- a/gthumb/gth-browser-actions-entries.h
+++ b/gthumb/gth-browser-actions-entries.h
@@ -46,6 +46,12 @@ static const GActionEntry gth_browser_actions[] = {
 };
 
 
+static const GthAccelerator gth_browser_accelerators[] = {
+       { "browser-mode", "Escape" },
+       { "fullscreen", "F11" },
+};
+
+
 static GthActionEntryExt gth_browser_action_entries[] = {
        { "FileMenu", NULL, N_("_File") },
        { "EditMenu", NULL, N_("_Edit") },
@@ -91,7 +97,7 @@ static GthActionEntryExt gth_browser_action_entries[] = {
          G_CALLBACK (gth_browser_activate_action_view_filter) },
 
        { "View_Stop", GTK_STOCK_STOP,
-         NULL, "Escape",
+         NULL, NULL,
          N_("Stop loading the current location"),
          GTH_ACTION_FLAG_NONE,
          G_CALLBACK (gth_browser_activate_action_view_stop) },
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index cfca951..9009809 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -4252,6 +4252,9 @@ gth_browser_init (GthBrowser *browser)
                                         gth_browser_actions,
                                         G_N_ELEMENTS (gth_browser_actions),
                                         browser);
+       gth_window_add_accelerators (GTH_WINDOW (browser),
+                                    gth_browser_accelerators,
+                                    G_N_ELEMENTS (gth_browser_accelerators));
 
        browser->priv->actions = gtk_action_group_new ("Actions");
        gtk_action_group_set_translation_domain (browser->priv->actions, NULL);
@@ -4420,6 +4423,8 @@ gth_browser_init (GthBrowser *browser)
 
                        browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS] = gth_menu_manager_new 
(G_MENU (menu));
                        browser->priv->menu_managers[GTH_BROWSER_MENU_MANAGER_GEARS_FOLDER_ACTIONS] = 
gth_menu_manager_new (G_MENU (gtk_builder_get_object (builder, "folder-actions")));
+
+                       _gtk_window_add_accelerators_from_menu ((GTK_WINDOW (browser)), menu);
                }
 
                /* browser navigation */
@@ -4468,7 +4473,7 @@ gth_browser_init (GthBrowser *browser)
                                                   "view-fullscreen-symbolic",
                                                   _("Switch to fullscreen"),
                                                   "win.fullscreen",
-                                                  "F11");
+                                                  NULL);
 
                /* viewer navigation */
 
@@ -4477,7 +4482,7 @@ gth_browser_init (GthBrowser *browser)
                                                   "go-previous-symbolic",
                                                   _("View the folders"),
                                                   "win.browser-mode",
-                                                  "Escape");
+                                                  NULL);
 
                /* viewer view */
 
@@ -4486,7 +4491,7 @@ gth_browser_init (GthBrowser *browser)
                                                   "view-fullscreen-symbolic",
                                                   _("Switch to fullscreen"),
                                                   "win.fullscreen",
-                                                  "F11");
+                                                  NULL);
        }
 
        /* toolbar */
@@ -5100,7 +5105,11 @@ gth_browser_add_header_bar_button (GthBrowser                    *browser,
        if (tooltip != NULL)
                gtk_widget_set_tooltip_text (button, tooltip);
        if (accelerator != NULL)
-               gth_window_add_accelerator (GTH_WINDOW (browser), button, "activate", accelerator);
+               _gtk_window_add_accelerator_for_action (GTK_WINDOW (browser),
+                                                       gth_window_get_accel_group (GTH_WINDOW (browser)),
+                                                       action_name,
+                                                       accelerator,
+                                                       NULL);
        gtk_widget_show (button);
        gtk_box_pack_start (GTK_BOX (gth_browser_get_headerbar_section (browser, section)), button, FALSE, 
FALSE, 0);
 }
diff --git a/gthumb/gth-window.c b/gthumb/gth-window.c
index 523f7ea..b3164a4 100644
--- a/gthumb/gth-window.c
+++ b/gthumb/gth-window.c
@@ -581,15 +581,34 @@ gth_window_set_title (GthWindow  *window,
 }
 
 
-void
-gth_window_add_accelerator (GthWindow     *window,
-                           GtkWidget     *widget,
-                           const char    *accel_signal,
-                           const char    *accelerator)
+GtkAccelGroup *
+gth_window_get_accel_group (GthWindow *window)
 {
-       guint           accel_key;
-       GdkModifierType accel_mods;
+       if (window->priv->accel_group == NULL) {
+               window->priv->accel_group = gtk_accel_group_new ();
+               gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accel_group);
+       }
+
+       return window->priv->accel_group;
+}
 
-       gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
-       gtk_widget_add_accelerator (widget, accel_signal, window->priv->accel_group, accel_key, accel_mods, 
0);
+
+void
+gth_window_add_accelerators (GthWindow                 *window,
+                            const GthAccelerator       *accelerators,
+                            int                         n_accelerators)
+{
+       GtkAccelGroup *accel_group;
+       int            i;
+
+       accel_group = gth_window_get_accel_group (window);
+       for (i = 0; i < n_accelerators; i++) {
+               const GthAccelerator *acc = accelerators + i;
+
+               _gtk_window_add_accelerator_for_action (GTK_WINDOW (window),
+                                                       accel_group,
+                                                       acc->action_name,
+                                                       acc->accelerator,
+                                                       NULL);
+       }
 }
diff --git a/gthumb/gth-window.h b/gthumb/gth-window.h
index fa15679..426c7c9 100644
--- a/gthumb/gth-window.h
+++ b/gthumb/gth-window.h
@@ -23,6 +23,7 @@
 #define GTH_WINDOW_H
 
 #include <gtk/gtk.h>
+#include "gtk-utils.h"
 
 G_BEGIN_DECLS
 
@@ -103,10 +104,10 @@ void           gth_window_clear_saved_size   (GthWindow     *window,
 void           gth_window_set_title          (GthWindow     *window,
                                              const char    *title,
                                              const char    *subtitle);
-void           gth_window_add_accelerator    (GthWindow     *window,
-                                             GtkWidget     *widget,
-                                             const char    *accel_signal,
-                                             const char    *accelerator);
+GtkAccelGroup *gth_window_get_accel_group      (GthWindow              *window);
+void           gth_window_add_accelerators     (GthWindow              *window,
+                                                const GthAccelerator   *accelerators,
+                                                int                     n_accelerators);
 
 G_END_DECLS
 
diff --git a/gthumb/gtk-utils.c b/gthumb/gtk-utils.c
index 420eb34..b53f997 100644
--- a/gthumb/gtk-utils.c
+++ b/gthumb/gtk-utils.c
@@ -853,7 +853,7 @@ _gtk_info_bar_clear_action_area (GtkInfoBar *info_bar)
 
 typedef struct {
        GMainLoop     *loop;
-       GdkDragAction  action;
+       GdkDragAction  action_name;
 } DropActionData;
 
 
@@ -874,7 +874,7 @@ ask_drag_drop_action_item_activate_cb (GtkMenuItem *menuitem,
 {
        DropActionData *drop_data = user_data;
 
-       drop_data->action = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "drop-action"));
+       drop_data->action_name = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), "drop-action"));
        if (g_main_loop_is_running (drop_data->loop))
                g_main_loop_quit (drop_data->loop);
 }
@@ -911,7 +911,7 @@ _gtk_menu_ask_drag_drop_action (GtkWidget     *widget,
        GtkWidget      *menu;
        GtkWidget      *item;
 
-       drop_data.action = 0;
+       drop_data.action_name = 0;
        drop_data.loop = g_main_loop_new (NULL, FALSE);
 
        menu = gtk_menu_new ();
@@ -960,7 +960,7 @@ _gtk_menu_ask_drag_drop_action (GtkWidget     *widget,
        gtk_widget_destroy (menu);
        g_main_loop_unref (drop_data.loop);
 
-       return drop_data.action;
+       return drop_data.action_name;
 }
 
 
@@ -1110,3 +1110,158 @@ _gtk_image_button_new_for_header_bar (const char *icon_name)
 
        return button;
 }
+
+
+/* -- _gtk_window_add_accelerator_for_action -- */
+
+
+typedef struct {
+       GtkWindow *window;
+       char      *action_name;
+       GVariant  *target;
+} AccelData;
+
+
+static void
+accel_data_free (gpointer  user_data,
+                 GClosure *closure)
+{
+       AccelData *accel_data = user_data;
+
+       g_return_if_fail (accel_data != NULL);
+
+       if (accel_data->target != NULL)
+               g_variant_unref (accel_data->target);
+       g_free (accel_data->action_name);
+       g_free (accel_data);
+}
+
+
+static void
+window_accelerator_activated_cb (GtkAccelGroup *accel_group,
+                                GObject                *object,
+                                guint           key,
+                                GdkModifierType         mod,
+                                gpointer                user_data)
+{
+       AccelData *accel_data = user_data;
+       GAction   *action;
+
+       action = g_action_map_lookup_action (G_ACTION_MAP (accel_data->window), accel_data->action_name);
+       if (action != NULL)
+               g_action_activate (action, accel_data->target);
+}
+
+
+void
+_gtk_window_add_accelerator_for_action (GtkWindow      *window,
+                                       GtkAccelGroup   *accel_group,
+                                       const char      *action_name,
+                                       const char      *accel,
+                                       GVariant        *target)
+{
+       AccelData       *accel_data;
+       guint            key;
+       GdkModifierType  mods;
+       GClosure        *closure;
+
+       if ((action_name == NULL) || (accel == NULL))
+               return;
+
+       if (g_str_has_prefix (action_name, "app."))
+               return;
+
+       accel_data = g_new0 (AccelData, 1);
+       accel_data->window = window;
+       /* remove the win. prefix from the action name */
+       if (g_str_has_prefix (action_name, "win."))
+               accel_data->action_name = g_strdup (action_name + strlen ("win."));
+       else
+               accel_data->action_name = g_strdup (action_name);
+       if (target != NULL)
+               accel_data->target = g_variant_ref (target);
+
+       gtk_accelerator_parse (accel, &key, &mods);
+       closure = g_cclosure_new (G_CALLBACK (window_accelerator_activated_cb),
+                                 accel_data,
+                                 accel_data_free);
+       gtk_accel_group_connect (accel_group,
+                                key,
+                                mods,
+                                0,
+                                closure);
+}
+
+
+/* -- _gtk_window_add_accelerators_from_menu --  */
+
+
+static void
+add_accelerators_from_menu_item (GtkWindow      *window,
+                                GtkAccelGroup  *accel_group,
+                                GMenuModel     *model,
+                                int             item)
+{
+       GMenuAttributeIter      *iter;
+       const char              *key;
+       GVariant                *value;
+       const char              *accel = NULL;
+       const char              *action = NULL;
+       GVariant                *target = NULL;
+
+       iter = g_menu_model_iterate_item_attributes (model, item);
+       while (g_menu_attribute_iter_get_next (iter, &key, &value)) {
+               if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+                       action = g_variant_get_string (value, NULL);
+               else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
+                       accel = g_variant_get_string (value, NULL);
+               else if (g_str_equal (key, "target"))
+                       target = g_variant_ref (value);
+               g_variant_unref (value);
+       }
+       g_object_unref (iter);
+
+       _gtk_window_add_accelerator_for_action (window,
+                                               accel_group,
+                                               action,
+                                               accel,
+                                               target);
+
+       if (target != NULL)
+               g_variant_unref (target);
+}
+
+
+static void
+add_accelerators_from_menu (GtkWindow      *window,
+                           GtkAccelGroup  *accel_group,
+                           GMenuModel     *model)
+{
+       int              i;
+       GMenuLinkIter   *iter;
+       const char      *key;
+       GMenuModel      *m;
+
+       for (i = 0; i < g_menu_model_get_n_items (model); i++) {
+               add_accelerators_from_menu_item (window, accel_group, model, i);
+
+               iter = g_menu_model_iterate_item_links (model, i);
+               while (g_menu_link_iter_get_next (iter, &key, &m)) {
+                       add_accelerators_from_menu (window, accel_group, m);
+                       g_object_unref (m);
+               }
+               g_object_unref (iter);
+       }
+}
+
+
+void
+_gtk_window_add_accelerators_from_menu (GtkWindow  *window,
+                                       GMenuModel *menu)
+{
+       GtkAccelGroup *accel_group;
+
+       accel_group = gtk_accel_group_new ();
+       add_accelerators_from_menu (window, accel_group, menu);
+       gtk_window_add_accel_group (window, accel_group);
+}
diff --git a/gthumb/gtk-utils.h b/gthumb/gtk-utils.h
index 84db4d0..31267d7 100644
--- a/gthumb/gtk-utils.h
+++ b/gthumb/gtk-utils.h
@@ -44,6 +44,11 @@ typedef struct {
        GCallback       callback;
 } GthActionEntryExt;
 
+typedef struct {
+       const char *action_name;
+       const char *accelerator;
+} GthAccelerator;
+
 void            _gtk_action_group_add_actions_with_flags   (GtkActionGroup   *action_group,
                                                            const GthActionEntryExt
                                                                             *entries,
@@ -138,6 +143,13 @@ gboolean        _gtk_file_chooser_set_file_parent          (GtkFileChooser   *ch
                                                            GError          **error);
 GtkWidget *     _gtk_menu_button_new_for_header_bar        (void);
 GtkWidget *     _gtk_image_button_new_for_header_bar       (const char       *icon_name);
+void           _gtk_window_add_accelerator_for_action     (GtkWindow           *window,
+                                                           GtkAccelGroup       *accel_group,
+                                                           const char          *action_name,
+                                                           const char          *accel,
+                                                           GVariant            *target);
+void           _gtk_window_add_accelerators_from_menu     (GtkWindow           *window,
+                                                           GMenuModel          *menu);
 
 G_END_DECLS
 
diff --git a/gthumb/resources/app-menu.ui b/gthumb/resources/app-menu.ui
index 00dc460..2b16d50 100644
--- a/gthumb/resources/app-menu.ui
+++ b/gthumb/resources/app-menu.ui
@@ -6,6 +6,7 @@
       <item>
         <attribute name="label" translatable="yes">New _Window</attribute>
         <attribute name="action">app.new-window</attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>n]]></attribute>
       </item>
     </section>
     <section>
@@ -22,6 +23,7 @@
       <item>
         <attribute name="label" translatable="yes">_Help</attribute>
         <attribute name="action">app.help</attribute>
+        <attribute name="accel">F1</attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_About</attribute>
@@ -30,6 +32,7 @@
       <item>
         <attribute name="label" translatable="yes">_Quit</attribute>
         <attribute name="action">app.quit</attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>q]]></attribute>
       </item>
     </section>
   </menu>
diff --git a/gthumb/resources/gears-menu.ui b/gthumb/resources/gears-menu.ui
index 6873acd..f3c547f 100644
--- a/gthumb/resources/gears-menu.ui
+++ b/gthumb/resources/gears-menu.ui
@@ -6,19 +6,18 @@
       <item>
         <attribute name="label" translatable="yes">New _Window</attribute>
         <attribute name="action">app.new-window</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>N]]></attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Open…</attribute>
         <attribute name="action">win.open-location</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>O]]></attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>o]]></attribute>
       </item>
     </section>
     <section>
       <item>
         <attribute name="label" translatable="yes">_Save</attribute>
         <attribute name="action">win.save</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>S]]></attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>s]]></attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">Save _As</attribute>
@@ -27,7 +26,7 @@
       <item>
         <attribute name="label" translatable="yes">_Revert</attribute>
         <attribute name="action">win.revert-to-saved</attribute>
-        <attribute name="accel"><![CDATA[F4]]></attribute>
+        <attribute name="accel">F4</attribute>
       </item>
     </section>
     <section id="folder-actions">
@@ -36,12 +35,11 @@
       <item>
         <attribute name="label" translatable="yes">Close _All Windows</attribute>
         <attribute name="action">app.quit</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>Q]]></attribute>
       </item>
       <item>
         <attribute name="label" translatable="yes">_Close</attribute>
         <attribute name="action">win.close</attribute>
-        <attribute name="accel"><![CDATA[<Ctrl>W]]></attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>w]]></attribute>
       </item>
     </section>
   </menu>


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