[gnumeric] GnmAction: introspection fixes.



commit 08ee8a48a9477e62993cc269a48234de0f93f2b1
Author: Morten Welinder <terra gnome org>
Date:   Fri May 18 15:48:38 2018 -0400

    GnmAction: introspection fixes.
    
    Rework things to make scope of handler right.

 src/application.c |   56 +++++++++++++++++++++++++++++++++++------------------
 src/application.h |   18 ++++++++++------
 src/gnm-plugin.c  |    7 +++--
 src/wbc-gtk.c     |    5 +---
 4 files changed, 53 insertions(+), 33 deletions(-)
---
diff --git a/src/application.c b/src/application.c
index 70c1b86..72fc119 100644
--- a/src/application.c
+++ b/src/application.c
@@ -908,40 +908,61 @@ static GSList *extra_uis = NULL;
  * @label: label.
  * @icon: icon name.
  * @always_available: whether the action should always be available.
- * @handler: (scope async): the handler.
+ * @handler: (scope notified): the handler.
+ * @data: user data for @handler
+ * @notify: destroy notification for @data
  *
  * Returns: (transfer full): the newly allocated #GnmAction.
  **/
 GnmAction *
 gnm_action_new (char const *id, char const *label,
                char const *icon_name, gboolean always_available,
-               GnmActionHandler handler)
+               GnmActionHandler handler,
+               gpointer data, GDestroyNotify notify)
 {
        GnmAction *res = g_new0 (GnmAction, 1);
+       res->ref_count  = 1;
        res->id         = g_strdup (id);
        res->label      = g_strdup (label);
        res->icon_name  = g_strdup (icon_name);
        res->always_available = always_available;
        res->handler    = handler;
+       res->data       = data;
+       res->notify     = notify;
        return res;
 }
 
+/**
+ * gnm_action_unref:
+ * @action: (transfer full) (nullable): #GnmAction
+ */
 void
-gnm_action_free (GnmAction *action)
+gnm_action_unref (GnmAction *action)
 {
-       if (NULL != action) {
-               g_free (action->id);
-               g_free (action->label);
-               g_free (action->icon_name);
-               g_free (action);
-       }
+       if (!action || action->ref_count-- > 1)
+               return;
+
+       if (action->notify)
+               action->notify (action->data);
+
+       g_free (action->id);
+       g_free (action->label);
+       g_free (action->icon_name);
+       g_free (action);
 }
 
-static GnmAction *
-gnm_action_copy (GnmAction const *action)
+/**
+ * gnm_action_ref:
+ * @action: (transfer none) (nullable): #GnmAction
+ *
+ * Returns: (transfer full) (nullable): a new reference to @action.
+ */
+GnmAction *
+gnm_action_ref (GnmAction *action)
 {
-       return gnm_action_new (action->id, action->label, action->icon_name,
-                              action->always_available, action->handler);
+       if (action)
+               action->ref_count++;
+       return action;
 }
 
 GType
@@ -951,8 +972,8 @@ gnm_action_get_type (void)
 
        if (t == 0) {
                t = g_boxed_type_register_static ("GnmAction",
-                        (GBoxedCopyFunc)gnm_action_copy,
-                        (GBoxedFreeFunc)gnm_action_free);
+                        (GBoxedCopyFunc)gnm_action_ref,
+                        (GBoxedFreeFunc)gnm_action_unref);
        }
        return t;
 }
@@ -994,7 +1015,6 @@ gnm_app_extra_ui_get_type (void)
  * @actions: (element-type GnmAction): list of actions.
  * @layout: the xml string describing the menus and toolbars.
  * @domain: localization domain.
- * @user_data: user data
  *
  * Returns: (transfer full): the newly allocated #GnmAppExtraUI.
  **/
@@ -1002,15 +1022,13 @@ GnmAppExtraUI *
 gnm_app_add_extra_ui (char const *group_name,
                      GSList *actions,
                      const char *layout,
-                     char const *domain,
-                     gpointer user_data)
+                     char const *domain)
 {
        GnmAppExtraUI *extra_ui = g_new0 (GnmAppExtraUI, 1);
        extra_uis = g_slist_prepend (extra_uis, extra_ui);
        extra_ui->group_name = g_strdup (group_name);
        extra_ui->actions = actions;
        extra_ui->layout = g_strdup (layout);
-       extra_ui->user_data = user_data;
        g_signal_emit (G_OBJECT (app), signals[CUSTOM_UI_ADDED], 0, extra_ui);
        if (gnm_debug_flag ("extra-ui"))
                g_printerr ("Adding extra ui [%s] %p\n", group_name, extra_ui);
diff --git a/src/application.h b/src/application.h
index 088adbc..5321f68 100644
--- a/src/application.h
+++ b/src/application.h
@@ -61,8 +61,9 @@ GnmRange const        *gnm_app_clipboard_area_get       (void);
  **/
 
 typedef void (*GnmActionHandler) (GnmAction const *action, WorkbookControl *wbc,
-                                 gpointer user_data);
+                                 gpointer data);
 struct _GnmAction {
+       unsigned ref_count;
        char *id;        /* id of the function that will handle this */
        char *label;     /* untranslated, gettext domain will be passed later */
        char *icon_name; /* optionally NULL */
@@ -74,27 +75,30 @@ struct _GnmAction {
         **/
        gboolean always_available;
 
-       GnmActionHandler        handler;
+       GnmActionHandler handler;
+       gpointer data;
+       GDestroyNotify notify;
 };
+
 typedef struct {
        char *group_name;
        GSList     *actions;
        char       *layout;
        char const *domain;
-       gpointer    user_data;
 } GnmAppExtraUI;
 
 GType      gnm_action_get_type (void);
 GnmAction *gnm_action_new  (char const *name, char const *label,
                            char const *icon, gboolean always_available,
-                           GnmActionHandler handler);
-void      gnm_action_free (GnmAction *action);
+                           GnmActionHandler handler,
+                           gpointer data, GDestroyNotify notify);
+GnmAction *gnm_action_ref   (GnmAction *action);
+void      gnm_action_unref (GnmAction *action);
 
 GType      gnm_app_extra_ui_get_type (void);
 GnmAppExtraUI *gnm_app_add_extra_ui (char const *group_name,
                                     GSList *actions, const char *layout,
-                                    char const *domain,
-                                    gpointer user_data);
+                                    char const *domain);
 void      gnm_app_remove_extra_ui  (GnmAppExtraUI *extra_ui);
 void      gnm_app_foreach_extra_ui (GFunc func, gpointer data);
 
diff --git a/src/gnm-plugin.c b/src/gnm-plugin.c
index b78aa52..0bcb430 100644
--- a/src/gnm-plugin.c
+++ b/src/gnm-plugin.c
@@ -332,7 +332,7 @@ plugin_service_ui_finalize (GObject *obj)
 
        g_free (service_ui->file_name);
        service_ui->file_name = NULL;
-       g_slist_free_full (service_ui->actions, (GDestroyNotify)gnm_action_free);
+       g_slist_free_full (service_ui->actions, (GDestroyNotify)gnm_action_unref);
        service_ui->actions = NULL;
 
        parent_class = g_type_class_peek (GO_TYPE_PLUGIN_SERVICE);
@@ -412,7 +412,8 @@ plugin_service_ui_read_xml (GOPluginService *service, xmlNode *tree, GOErrorInfo
                        if (!go_xml_node_get_bool (ptr, "always_available", &always_available))
                                always_available = FALSE;
                        action = gnm_action_new (name, label, icon, always_available,
-                               (GnmActionHandler) cb_ui_service_activate);
+                                                (GnmActionHandler) cb_ui_service_activate,
+                                                service, NULL);
                        if (NULL != name) xmlFree (name);
                        g_free (label);
                        if (NULL != icon) xmlFree (icon);
@@ -471,7 +472,7 @@ plugin_service_ui_activate (GOPluginService *service, GOErrorInfo **ret_error)
        group_name = g_strconcat (go_plugin_get_id (service->plugin), service->id, NULL);
        service_ui->layout_id = gnm_app_add_extra_ui (group_name,
                service_ui->actions,
-               xml_ui, tdomain, service);
+               xml_ui, tdomain);
        g_free (group_name);
        g_free (xml_ui);
        g_object_unref (src);
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index 8ea06bb..5288511 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -3410,13 +3410,11 @@ static void
 cb_custom_ui_handler (GObject *gtk_action, WorkbookControl *wbc)
 {
        GnmAction *action = g_object_get_data (gtk_action, "GnmAction");
-       GnmAppExtraUI *extra_ui = g_object_get_data (gtk_action, "ExtraUI");
 
        g_return_if_fail (action != NULL);
        g_return_if_fail (action->handler != NULL);
-       g_return_if_fail (extra_ui != NULL);
 
-       action->handler (action, wbc, extra_ui->user_data);
+       action->handler (action, wbc, action->data);
 }
 
 static void
@@ -3445,7 +3443,6 @@ cb_add_custom_ui (G_GNUC_UNUSED GnmApp *app,
                gtk_action_group_add_actions (details->actions, &entry, 1, gtk);
                res = gtk_action_group_get_action (details->actions, action->id);
                g_object_set_data (G_OBJECT (res), "GnmAction", action);
-               g_object_set_data (G_OBJECT (res), "ExtraUI", extra_ui);
        }
        gtk_ui_manager_insert_action_group (gtk->ui, details->actions, 0);
 


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