[gnumeric] GnmAction: introspection fixes.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] GnmAction: introspection fixes.
- Date: Fri, 18 May 2018 19:49:20 +0000 (UTC)
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]