[gtk+/action-helper: 16/16] gtkmodelmenu: add support for action namespaces



commit e3afbe5d873fcb3d7bcc82adc0432207a23bce9a
Author: Lars Uebernickel <lars uebernic de>
Date:   Wed Jun 20 16:56:56 2012 +0200

    gtkmodelmenu: add support for action namespaces
    
    If a section or submenu item has a "action-namespace" attribute, the
    action names of the created GtkModelMenuItems will be prefixed with that
    namespace.  Namespaces can be cascaded.

 gtk/gtkmodelmenu.c     |   38 ++++++++++++++++++++++++++++++--------
 gtk/gtkmodelmenu.h     |    1 +
 gtk/gtkmodelmenuitem.c |   42 +++++++++++++++++++++++++++++++++++++++---
 gtk/gtkmodelmenuitem.h |    1 +
 4 files changed, 71 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkmodelmenu.c b/gtk/gtkmodelmenu.c
index 390923f..ab9bbb4 100644
--- a/gtk/gtkmodelmenu.c
+++ b/gtk/gtkmodelmenu.c
@@ -39,6 +39,7 @@ typedef struct {
   GSList            *connected;
   gboolean           with_separators;
   gint               n_items;
+  gchar             *action_namespace;
 } GtkModelMenuBinding;
 
 static void
@@ -49,6 +50,7 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
                                       gpointer    user_data);
 static void gtk_model_menu_binding_append_model (GtkModelMenuBinding *binding,
                                                  GMenuModel *model,
+                                                 const gchar *action_namespace,
                                                  gboolean with_separators);
 
 static void
@@ -66,6 +68,7 @@ gtk_model_menu_binding_free (gpointer data)
     }
 
   g_object_unref (binding->model);
+  g_free (binding->action_namespace);
 
   g_slice_free (GtkModelMenuBinding, binding);
 }
@@ -73,6 +76,7 @@ gtk_model_menu_binding_free (gpointer data)
 static void
 gtk_model_menu_binding_append_item (GtkModelMenuBinding  *binding,
                                     GMenuModel           *model,
+                                    const gchar          *action_namespace,
                                     gint                  item_index,
                                     gchar               **heading)
 {
@@ -80,15 +84,29 @@ gtk_model_menu_binding_append_item (GtkModelMenuBinding  *binding,
 
   if ((section = g_menu_model_get_item_link (model, item_index, "section")))
     {
+      const gchar *section_namespace = NULL;
+
       g_menu_model_get_item_attribute (model, item_index, "label", "s", heading);
-      gtk_model_menu_binding_append_model (binding, section, FALSE);
+      g_menu_model_get_item_attribute (model, item_index, "action-namespace", "&s", &section_namespace);
+
+      if (action_namespace)
+        {
+          gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
+          gtk_model_menu_binding_append_model (binding, section, namespace, FALSE);
+          g_free (namespace);
+        }
+      else
+        {
+          gtk_model_menu_binding_append_model (binding, section, section_namespace, FALSE);
+        }
+
       g_object_unref (section);
     }
   else
     {
       GtkMenuItem *item;
 
-      item = gtk_model_menu_item_new (model, item_index, binding->accels);
+      item = gtk_model_menu_item_new (model, item_index, action_namespace, binding->accels);
       gtk_menu_shell_append (binding->shell, GTK_WIDGET (item));
       gtk_widget_show (GTK_WIDGET (item));
       binding->n_items++;
@@ -98,6 +116,7 @@ gtk_model_menu_binding_append_item (GtkModelMenuBinding  *binding,
 static void
 gtk_model_menu_binding_append_model (GtkModelMenuBinding *binding,
                                      GMenuModel          *model,
+                                     const gchar         *action_namespace,
                                      gboolean             with_separators)
 {
   gint n, i;
@@ -140,7 +159,7 @@ gtk_model_menu_binding_append_model (GtkModelMenuBinding *binding,
       gint our_position = binding->n_items;
       gchar *heading = NULL;
 
-      gtk_model_menu_binding_append_item (binding, model, i, &heading);
+      gtk_model_menu_binding_append_item (binding, model, action_namespace, i, &heading);
 
       if (with_separators && our_position < binding->n_items)
         {
@@ -182,7 +201,7 @@ gtk_model_menu_binding_populate (GtkModelMenuBinding *binding)
   binding->n_items = 0;
 
   /* add new items from the model */
-  gtk_model_menu_binding_append_model (binding, binding->model, binding->with_separators);
+  gtk_model_menu_binding_append_model (binding, binding->model, binding->action_namespace, binding->with_separators);
 }
 
 static gboolean
@@ -227,6 +246,7 @@ gtk_model_menu_binding_items_changed (GMenuModel *model,
 static void
 gtk_model_menu_bind (GtkMenuShell *shell,
                      GMenuModel   *model,
+                     const gchar  *action_namespace,
                      gboolean      with_separators)
 {
   GtkModelMenuBinding *binding;
@@ -238,6 +258,7 @@ gtk_model_menu_bind (GtkMenuShell *shell,
   binding->update_idle = 0;
   binding->connected = NULL;
   binding->with_separators = with_separators;
+  binding->action_namespace = g_strdup (action_namespace);
 
   g_object_set_data_full (G_OBJECT (shell), "gtk-model-menu-binding", binding, gtk_model_menu_binding_free);
 }
@@ -258,6 +279,7 @@ gtk_model_menu_populate (GtkMenuShell  *shell,
 
 GtkWidget *
 gtk_model_menu_create_menu (GMenuModel    *model,
+                            const gchar   *action_namespace,
                             GtkAccelGroup *accels)
 {
   GtkWidget *menu;
@@ -265,7 +287,7 @@ gtk_model_menu_create_menu (GMenuModel    *model,
   menu = gtk_menu_new ();
   gtk_menu_set_accel_group (GTK_MENU (menu), accels);
 
-  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
+  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, action_namespace, TRUE);
   gtk_model_menu_populate (GTK_MENU_SHELL (menu), accels);
 
   return menu;
@@ -293,7 +315,7 @@ gtk_menu_new_from_model (GMenuModel *model)
   GtkWidget *menu;
 
   menu = gtk_menu_new ();
-  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, TRUE);
+  gtk_model_menu_bind (GTK_MENU_SHELL (menu), model, NULL, TRUE);
   gtk_model_menu_populate (GTK_MENU_SHELL (menu), NULL);
 
   return menu;
@@ -307,7 +329,7 @@ gtk_model_menu_create_menu_bar (GMenuModel    *model,
 
   menubar = gtk_menu_bar_new ();
 
-  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
+  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
   gtk_model_menu_populate (GTK_MENU_SHELL (menubar), accels);
 
   return menubar;
@@ -336,7 +358,7 @@ gtk_menu_bar_new_from_model (GMenuModel *model)
 
   menubar = gtk_menu_bar_new ();
 
-  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, FALSE);
+  gtk_model_menu_bind (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
   gtk_model_menu_populate (GTK_MENU_SHELL (menubar), NULL);
 
   return menubar;
diff --git a/gtk/gtkmodelmenu.h b/gtk/gtkmodelmenu.h
index 05654c9..1bc27be 100644
--- a/gtk/gtkmodelmenu.h
+++ b/gtk/gtkmodelmenu.h
@@ -30,6 +30,7 @@ GtkWidget * gtk_model_menu_create_menu_bar (GMenuModel        *model,
 
 G_GNUC_INTERNAL
 GtkWidget * gtk_model_menu_create_menu     (GMenuModel        *model,
+                                            const gchar       *action_namespace,
                                             GtkAccelGroup     *accels);
 
 #endif /* __GTK_MODEL_MENU_H__ */
diff --git a/gtk/gtkmodelmenuitem.c b/gtk/gtkmodelmenuitem.c
index 07cad70..b7338a5 100644
--- a/gtk/gtkmodelmenuitem.c
+++ b/gtk/gtkmodelmenuitem.c
@@ -64,9 +64,27 @@ gtk_model_menu_item_draw_indicator (GtkCheckMenuItem *check_item,
 }
 
 static void
+gtk_actionable_set_namespaced_action_name (GtkActionable *actionable,
+                                           const gchar   *namespace,
+                                           const gchar   *action_name)
+{
+  if (namespace)
+    {
+      gchar *name = g_strdup_printf ("%s.%s", namespace, action_name);
+      gtk_actionable_set_action_name (actionable, name);
+      g_free (name);
+    }
+  else
+    {
+      gtk_actionable_set_action_name (actionable, action_name);
+    }
+}
+
+static void
 gtk_model_menu_item_setup (GtkModelMenuItem  *item,
                            GMenuModel        *model,
                            gint               item_index,
+                           const gchar       *action_namespace,
                            GtkAccelGroup     *accels)
 {
   GMenuAttributeIter *iter;
@@ -76,7 +94,23 @@ gtk_model_menu_item_setup (GtkModelMenuItem  *item,
 
   if ((submenu = g_menu_model_get_item_link (model, item_index, "submenu")))
     {
-      gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), gtk_model_menu_create_menu (submenu, accels));
+      const gchar *section_namespace = NULL;
+      GtkWidget *menu;
+
+      g_menu_model_get_item_attribute (model, item_index, "action-namespace", "&s", &section_namespace);
+
+      if (action_namespace)
+        {
+          gchar *namespace = g_strjoin (".", action_namespace, section_namespace, NULL);
+          menu = gtk_model_menu_create_menu (submenu, namespace, accels);
+          g_free (namespace);
+        }
+      else
+        {
+          menu = gtk_model_menu_create_menu (submenu, section_namespace, accels);
+        }
+
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
       g_object_unref (submenu);
     }
 
@@ -87,7 +121,8 @@ gtk_model_menu_item_setup (GtkModelMenuItem  *item,
         gtk_menu_item_set_label (GTK_MENU_ITEM (item), g_variant_get_string (value, NULL));
 
       else if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
-        gtk_actionable_set_action_name (GTK_ACTIONABLE (item), g_variant_get_string (value, NULL));
+        gtk_actionable_set_namespaced_action_name (GTK_ACTIONABLE (item), action_namespace,
+                                                   g_variant_get_string (value, NULL));
 
       else if (g_str_equal (key, "target"))
         gtk_actionable_set_action_target_value (GTK_ACTIONABLE (item), value);
@@ -178,13 +213,14 @@ gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
 GtkMenuItem *
 gtk_model_menu_item_new (GMenuModel        *model,
                          gint               item_index,
+                         const gchar       *action_namespace,
                          GtkAccelGroup     *accels)
 {
   GtkModelMenuItem *item;
 
   item = g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
 
-  gtk_model_menu_item_setup (item, model, item_index, accels);
+  gtk_model_menu_item_setup (item, model, item_index, action_namespace, accels);
 
   return GTK_MENU_ITEM (item);
 }
diff --git a/gtk/gtkmodelmenuitem.h b/gtk/gtkmodelmenuitem.h
index 8017e3b..9e35327 100644
--- a/gtk/gtkmodelmenuitem.h
+++ b/gtk/gtkmodelmenuitem.h
@@ -36,6 +36,7 @@ GType                   gtk_model_menu_item_get_type                    (void) G
 G_GNUC_INTERNAL
 GtkMenuItem *           gtk_model_menu_item_new                         (GMenuModel        *model,
                                                                          gint               item_index,
+                                                                         const gchar       *action_namespace,
                                                                          GtkAccelGroup     *accels);
 
 #endif /* __GTK_MODEL_MENU_ITEM_H__ */



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