From 1e663aa13266cad55e5019c03e768a38955166eb Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 13 Oct 2010 23:40:16 -0400 Subject: Replace EBinding with GBinding. GObject now does property bindings itself. Requires GLib >= 2.26. --- e-util/Makefile.am | 2 - e-util/e-binding.c | 557 ----------------------------------------------------- e-util/e-binding.h | 117 ----------- e-util/e-config.c | 6 +- e-util/e-util.c | 61 ++++++ e-util/e-util.h | 12 ++ 6 files changed, 77 insertions(+), 678 deletions(-) delete mode 100644 e-util/e-binding.c delete mode 100644 e-util/e-binding.h (limited to 'e-util') diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 4b08698896..619f88c27a 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -15,7 +15,6 @@ eutilinclude_HEADERS = \ e-alert-activity.h \ e-alert-dialog.h \ e-alert-sink.h \ - e-binding.h \ e-bit-array.h \ e-categories-config.h \ e-charset.h \ @@ -95,7 +94,6 @@ libeutil_la_SOURCES = \ e-alert-activity.c \ e-alert-dialog.c \ e-alert-sink.c \ - e-binding.c \ e-bit-array.c \ e-categories-config.c \ e-charset.c \ diff --git a/e-util/e-binding.c b/e-util/e-binding.c deleted file mode 100644 index 4b0f563a43..0000000000 --- a/e-util/e-binding.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * e-binding.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-binding.h" - -static gpointer -e_binding_warn (GObject *object, - const gchar *property_name) -{ - g_warning ( - "%s instances have no '%s' property to bind to", - G_OBJECT_TYPE_NAME (object), property_name); - - return NULL; -} - -static gboolean -e_binding_transform_negate (const GValue *src_value, - GValue *dst_value) -{ - if (!g_value_transform (src_value, dst_value)) - return FALSE; - - g_value_set_boolean (dst_value, !g_value_get_boolean (dst_value)); - - return TRUE; -} - -static void -e_bind_properties_transfer (GObject *src_object, - GParamSpec *src_pspec, - GObject *dst_object, - GParamSpec *dst_pspec, - EBindingTransform transform, - gpointer user_data) -{ - const gchar *src_name; - const gchar *dst_name; - gboolean result; - GValue src_value = { 0, }; - GValue dst_value = { 0, }; - - src_name = g_param_spec_get_name (src_pspec); - dst_name = g_param_spec_get_name (dst_pspec); - - g_value_init (&src_value, G_PARAM_SPEC_VALUE_TYPE (src_pspec)); - g_object_get_property (src_object, src_name, &src_value); - - g_value_init (&dst_value, G_PARAM_SPEC_VALUE_TYPE (dst_pspec)); - result = (*transform) (&src_value, &dst_value, user_data); - - g_value_unset (&src_value); - - g_return_if_fail (result); - - g_param_value_validate (dst_pspec, &dst_value); - g_object_set_property (dst_object, dst_name, &dst_value); - g_value_unset (&dst_value); -} - -static void -e_bind_properties_notify (GObject *src_object, - GParamSpec *src_pspec, - gpointer data) -{ - EBindingLink *link = data; - - /* Block the destination handler for mutual bindings, - * so we don't recurse here. */ - if (link->dst_handler != 0) - g_signal_handler_block (link->dst_object, link->dst_handler); - - e_bind_properties_transfer ( - src_object, src_pspec, - link->dst_object, link->dst_pspec, - link->transform, link->user_data); - - /* Unblock destination handler. */ - if (link->dst_handler != 0) - g_signal_handler_unblock (link->dst_object, link->dst_handler); -} - -static void -e_binding_on_dst_object_destroy (gpointer data, - GObject *object) -{ - EBinding *binding = data; - - binding->link.dst_object = NULL; - - /* Calls e_binding_on_disconnect() */ - g_signal_handler_disconnect ( - binding->src_object, binding->link.handler); -} - -static void -e_binding_on_disconnect (gpointer data, - GClosure *closure) -{ - EBindingLink *link = data; - EBinding *binding; - - binding = (EBinding *) - (((gchar *) link) - G_STRUCT_OFFSET (EBinding, link)); - - if (binding->base.destroy != NULL) - binding->base.destroy (link->user_data); - - if (link->dst_object != NULL) - g_object_weak_unref ( - link->dst_object, - e_binding_on_dst_object_destroy, binding); - - g_slice_free (EBinding, binding); -} - -/* Recursively calls e_mutual_binding_on_disconnect_object2() */ -static void -e_mutual_binding_on_disconnect_object1 (gpointer data, - GClosure *closure) -{ - EMutualBinding *binding; - EBindingLink *link = data; - GObject *object2; - - binding = (EMutualBinding *) - (((gchar *) link) - G_STRUCT_OFFSET (EMutualBinding, direct)); - binding->reverse.dst_object = NULL; - - object2 = binding->direct.dst_object; - if (object2 != NULL) { - if (binding->base.destroy != NULL) - binding->base.destroy (binding->direct.user_data); - binding->direct.dst_object = NULL; - g_signal_handler_disconnect (object2, binding->reverse.handler); - g_slice_free (EMutualBinding, binding); - } -} - -/* Recursively calls e_mutual_binding_on_disconnect_object1() */ -static void -e_mutual_binding_on_disconnect_object2 (gpointer data, - GClosure *closure) -{ - EMutualBinding *binding; - EBindingLink *link = data; - GObject *object1; - - binding = (EMutualBinding *) - (((gchar *) link) - G_STRUCT_OFFSET (EMutualBinding, reverse)); - binding->direct.dst_object = NULL; - - object1 = binding->reverse.dst_object; - if (object1 != NULL) { - binding->reverse.dst_object = NULL; - g_signal_handler_disconnect (object1, binding->direct.handler); - } -} - -static void -e_binding_link_init (EBindingLink *link, - GObject *src_object, - const gchar *src_property, - GObject *dst_object, - GParamSpec *dst_pspec, - EBindingTransform transform, - GClosureNotify destroy_notify, - gpointer user_data) -{ - gchar *signal_name; - - link->dst_object = dst_object; - link->dst_pspec = dst_pspec; - link->dst_handler = 0; - link->transform = transform; - link->user_data = user_data; - - signal_name = g_strconcat ("notify::", src_property, NULL); - link->handler = g_signal_connect_data ( - src_object, signal_name, - G_CALLBACK (e_bind_properties_notify), - link, destroy_notify, 0); - g_free (signal_name); -} - -/** - * e_binding_new: - * @src_object: The source #GObject. - * @src_property: The name of the property to bind from. - * @dst_object: The destination #GObject. - * @dst_property: The name of the property to bind to. - * - * One-way binds @src_property in @src_object to @dst_property - * in @dst_object. - * - * Before binding the value of @dst_property is set to the - * value of @src_property. - * - * Returns: The descriptor of the binding. It is automatically - * removed if one of the objects is finalized. - **/ -EBinding * -e_binding_new (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property) -{ - return e_binding_new_full ( - src_object, src_property, - dst_object, dst_property, - NULL, NULL, NULL); -} - -/** - * e_binding_new_full: - * @src_object: The source #GObject. - * @src_property: The name of the property to bind from. - * @dst_object: The destination #GObject. - * @dst_property: The name of the property to bind to. - * @transform: Transformation function or %NULL. - * @destroy_notify: Callback function that is called on - * disconnection with @user_data or %NULL. - * @user_data: User data associated with the binding. - * - * One-way binds @src_property in @src_object to @dst_property - * in @dst_object. - * - * Before binding the value of @dst_property is set to the - * value of @src_property. - * - * Returns: The descriptor of the binding. It is automatically - * removed if one of the objects is finalized. - **/ -EBinding * -e_binding_new_full (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property, - EBindingTransform transform, - GDestroyNotify destroy_notify, - gpointer user_data) -{ - EBinding *binding; - GParamSpec *src_pspec; - GParamSpec *dst_pspec; - - g_return_val_if_fail (G_IS_OBJECT (src_object), NULL); - g_return_val_if_fail (G_IS_OBJECT (dst_object), NULL); - - src_pspec = g_object_class_find_property ( - G_OBJECT_GET_CLASS (src_object), src_property); - dst_pspec = g_object_class_find_property ( - G_OBJECT_GET_CLASS (dst_object), dst_property); - - if (src_pspec == NULL) - return e_binding_warn (src_object, src_property); - if (dst_pspec == NULL) - return e_binding_warn (dst_object, dst_property); - - if (transform == NULL) - transform = (EBindingTransform) g_value_transform; - - e_bind_properties_transfer ( - src_object, src_pspec, - dst_object, dst_pspec, - transform, user_data); - - binding = g_slice_new (EBinding); - binding->src_object = src_object; - binding->base.destroy = destroy_notify; - - e_binding_link_init ( - &binding->link, src_object, src_property, dst_object, - dst_pspec, transform, e_binding_on_disconnect, user_data); - - g_object_weak_ref ( - dst_object, e_binding_on_dst_object_destroy, binding); - - return binding; -} - -/** - * e_binding_new_with_negation: - * @src_object: The source #GObject. - * @src_property: The name of the property to bind from. - * @dst_object: The destination #GObject. - * @dst_property: The name of the property to bind to. - * - * Convenience function for binding with boolean negation of value. - * - * Returns: The descriptor of the binding. It is automatically - * removed if one of the objects is finalized. - **/ -EBinding * -e_binding_new_with_negation (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property) -{ - EBindingTransform transform; - - transform = (EBindingTransform) e_binding_transform_negate; - - return e_binding_new_full ( - src_object, src_property, - dst_object, dst_property, - transform, NULL, NULL); -} - -/** - * e_binding_unbind: - * @binding: An #EBinding to unbind. - * - * Disconnects the binding between two properties. Should be - * rarely used by applications. - * - * This functions also calls the @destroy_notify function that - * was specified when @binding was created. - **/ -void -e_binding_unbind (EBinding *binding) -{ - g_signal_handler_disconnect ( - binding->src_object, binding->link.handler); -} - -/** - * e_mutual_binding_new: - * @object1 : The first #GObject. - * @property1: The first property to bind. - * @object2 : The second #GObject. - * @property2: The second property to bind. - * - * Mutually binds values of two properties. - * - * Before binding the value of @property2 is set to the value - * of @property1. - * - * Returns: The descriptor of the binding. It is automatically - * removed if one of the objects is finalized. - **/ -EMutualBinding * -e_mutual_binding_new (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2) -{ - return e_mutual_binding_new_full ( - object1, property1, - object2, property2, - NULL, NULL, NULL, NULL); -} - -/** - * e_mutual_binding_new_full: - * @object1: The first #GObject. - * @property1: The first property to bind. - * @object2: The second #GObject. - * @property2: The second property to bind. - * @transform: Transformation function or %NULL. - * @reverse_transform: The inverse transformation function or %NULL. - * @destroy_notify: Callback function called on disconnection with - * @user_data as argument or %NULL. - * @user_data: User data associated with the binding. - * - * Mutually binds values of two properties. - * - * Before binding the value of @property2 is set to the value of - * @property1. - * - * Both @transform and @reverse_transform should simultaneously be - * %NULL or non-%NULL. If they are non-%NULL, they should be reverse - * in each other. - * - * Returns: The descriptor of the binding. It is automatically - * removed if one of the objects is finalized. - **/ -EMutualBinding * -e_mutual_binding_new_full (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2, - EBindingTransform transform, - EBindingTransform reverse_transform, - GDestroyNotify destroy_notify, - gpointer user_data) -{ - EMutualBinding *binding; - GParamSpec *pspec1; - GParamSpec *pspec2; - - g_return_val_if_fail (G_IS_OBJECT (object1), NULL); - g_return_val_if_fail (G_IS_OBJECT (object2), NULL); - - pspec1 = g_object_class_find_property ( - G_OBJECT_GET_CLASS (object1), property1); - pspec2 = g_object_class_find_property ( - G_OBJECT_GET_CLASS (object2), property2); - - if (pspec1 == NULL) - return e_binding_warn (object1, property1); - if (pspec2 == NULL) - return e_binding_warn (object2, property2); - - if (transform == NULL) - transform = (EBindingTransform) g_value_transform; - - if (reverse_transform == NULL) - reverse_transform = (EBindingTransform) g_value_transform; - - e_bind_properties_transfer ( - object1, pspec1, object2, - pspec2, transform, user_data); - - binding = g_slice_new (EMutualBinding); - binding->base.destroy = destroy_notify; - - e_binding_link_init ( - &binding->direct, - object1, property1, object2, pspec2, transform, - e_mutual_binding_on_disconnect_object1, user_data); - - e_binding_link_init ( - &binding->reverse, - object2, property2, object1, pspec1, reverse_transform, - e_mutual_binding_on_disconnect_object2, user_data); - - /* Tell each link about the reverse link for mutual bindings, - * to make sure that we do not ever recurse in notify (yeah, - * the GObject notify dispatching is really weird!). */ - binding->direct.dst_handler = binding->reverse.handler; - binding->reverse.dst_handler = binding->direct.handler; - - return binding; -} - -/** - * e_mutual_binding_new_with_negation: - * @object1: The first #GObject. - * @property1: The first property to bind. - * @object2: The second #GObject. - * @property2: The second property to bind. - * - * Convenience function for binding with boolean negation of value. - * - * Returns: The descriptor of the binding. It is automatically removed - * if one of the objects if finalized. - **/ -EMutualBinding* -e_mutual_binding_new_with_negation (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2) -{ - EBindingTransform transform; - - transform = (EBindingTransform) e_binding_transform_negate; - - return e_mutual_binding_new_full ( - object1, property1, - object2, property2, - transform, transform, - NULL, NULL); -} - -/** - * e_mutual_binding_unbind: - * @binding: An #EMutualBinding to unbind. - * - * Disconnects the binding between two properties. Should be - * rarely used by applications. - * - * This functions also calls the @destroy_notify function that - * was specified when @binding was created. - **/ -void -e_mutual_binding_unbind (EMutualBinding *binding) -{ - g_signal_handler_disconnect ( - binding->reverse.dst_object, binding->direct.handler); -} - -/** - * e_binding_transform_color_to_string: - * @src_value: a #GValue of type #GDK_TYPE_COLOR - * @dst_value: a #GValue of type #G_TYPE_STRING - * @user_data: not used - * - * Transforms a #GdkColor value to a color string specification. - * - * Returns: %TRUE always - **/ -gboolean -e_binding_transform_color_to_string (const GValue *src_value, - GValue *dst_value, - gpointer user_data) -{ - const GdkColor *color; - gchar *string; - - color = g_value_get_boxed (src_value); - string = gdk_color_to_string (color); - g_value_set_string (dst_value, string); - g_free (string); - - return TRUE; -} - -/** - * e_binding_transform_string_to_color: - * @src_value: a #GValue of type #G_TYPE_STRING - * @dst_value: a #GValue of type #GDK_TYPE_COLOR - * @user_data: not used - * - * Transforms a color string specification to a #GdkColor. - * - * Returns: %TRUE if color string specification was valid - **/ -gboolean -e_binding_transform_string_to_color (const GValue *src_value, - GValue *dst_value, - gpointer user_data) -{ - GdkColor color; - const gchar *string; - gboolean success = FALSE; - - string = g_value_get_string (src_value); - if (gdk_color_parse (string, &color)) { - g_value_set_boxed (dst_value, &color); - success = TRUE; - } - - return success; -} diff --git a/e-util/e-binding.h b/e-util/e-binding.h deleted file mode 100644 index 180edc9f49..0000000000 --- a/e-util/e-binding.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * e-binding.h - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -/* This is a direct rip-off of Xfce's excellent ExoBinding API, - * which binds two GObject properties together. ExoBinding was - * written by Benedikt Meurer . */ - -#ifndef E_BINDING_H -#define E_BINDING_H - -#include - -G_BEGIN_DECLS - -typedef struct _EBinding EBinding; -typedef struct _EBindingBase EBindingBase; -typedef struct _EBindingLink EBindingLink; -typedef struct _EMutualBinding EMutualBinding; - -typedef gboolean (*EBindingTransform) (const GValue *src_value, - GValue *dst_value, - gpointer user_data); - -struct _EBindingBase { - GDestroyNotify destroy; -}; - -struct _EBindingLink { - GObject *dst_object; - GParamSpec *dst_pspec; - gulong dst_handler; /* only set for mutual bindings */ - gulong handler; - EBindingTransform transform; - gpointer user_data; -}; - -struct _EBinding { - /*< private >*/ - GObject *src_object; - EBindingBase base; - EBindingLink link; -}; - -struct _EMutualBinding { - /*< private >*/ - EBindingBase base; - EBindingLink direct; - EBindingLink reverse; -}; - -EBinding * e_binding_new (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property); -EBinding * e_binding_new_full (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property, - EBindingTransform transform, - GDestroyNotify destroy_notify, - gpointer user_data); -EBinding * e_binding_new_with_negation (gpointer src_object, - const gchar *src_property, - gpointer dst_object, - const gchar *dst_property); -void e_binding_unbind (EBinding *binding); - -EMutualBinding *e_mutual_binding_new (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2); -EMutualBinding *e_mutual_binding_new_full (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2, - EBindingTransform transform, - EBindingTransform reverse_transform, - GDestroyNotify destroy_notify, - gpointer user_data); -EMutualBinding *e_mutual_binding_new_with_negation - (gpointer object1, - const gchar *property1, - gpointer object2, - const gchar *property2); -void e_mutual_binding_unbind (EMutualBinding *binding); - -/* Useful transformation functions */ -gboolean e_binding_transform_color_to_string - (const GValue *src_value, - GValue *dst_value, - gpointer user_data); -gboolean e_binding_transform_string_to_color - (const GValue *src_value, - GValue *dst_value, - gpointer user_data); - -G_END_DECLS - -#endif /* E_BINDING_H */ diff --git a/e-util/e-config.c b/e-util/e-config.c index dd51f8efc7..6646fa17d9 100644 --- a/e-util/e-config.c +++ b/e-util/e-config.c @@ -31,7 +31,6 @@ #include #include "e-config.h" -#include "e-binding.h" #include @@ -1704,7 +1703,10 @@ ech_config_section_factory (EConfig *config, /* This is why we have a custom factory for sections. * When the plugin is disabled the frame is invisible. */ plugin = group->hook->hook.plugin; - e_binding_new (plugin, "enabled", widget, "visible"); + g_object_bind_property ( + plugin, "enabled", + widget, "visible", + G_BINDING_SYNC_CREATE); parent = widget; diff --git a/e-util/e-util.c b/e-util/e-util.c index 68662bd3d4..22f792c3a7 100644 --- a/e-util/e-util.c +++ b/e-util/e-util.c @@ -1494,3 +1494,64 @@ e_util_set_source_combo_box_list (GtkWidget *source_combo_box, g_object_unref (gconf_client); } +/** + * e_binding_transform_color_to_string: + * @binding: a #GBinding + * @source_value: a #GValue of type #GDK_TYPE_COLOR + * @target_value: a #GValue of type #G_TYPE_STRING + * @user_data: not used + * + * Transforms a #GdkColor value to a color string specification. + * + * Returns: %TRUE always + **/ +gboolean +e_binding_transform_color_to_string (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + const GdkColor *color; + gchar *string; + + g_return_val_if_fail (G_IS_BINDING (binding), FALSE); + + color = g_value_get_boxed (source_value); + string = gdk_color_to_string (color); + g_value_set_string (target_value, string); + g_free (string); + + return TRUE; +} + +/** + * e_binding_transform_string_to_color: + * @binding: a #GBinding + * @source_value: a #GValue of type #G_TYPE_STRING + * @target_value: a #GValue of type #GDK_TYPE_COLOR + * @user_data: not used + * + * Transforms a color string specification to a #GdkColor. + * + * Returns: %TRUE if color string specification was valid + **/ +gboolean +e_binding_transform_string_to_color (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + GdkColor color; + const gchar *string; + gboolean success = FALSE; + + g_return_val_if_fail (G_IS_BINDING (binding), FALSE); + + string = g_value_get_string (source_value); + if (gdk_color_parse (string, &color)) { + g_value_set_boxed (target_value, &color); + success = TRUE; + } + + return success; +} diff --git a/e-util/e-util.h b/e-util/e-util.h index 71fc12f431..9aa24f3d87 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -142,6 +142,18 @@ void e_util_set_source_combo_box_list (GtkWidget *source_combo_box, const gchar *source_gconf_path); +/* Useful GBinding transformation functions */ +gboolean e_binding_transform_color_to_string + (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data); +gboolean e_binding_transform_string_to_color + (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data); + G_END_DECLS #endif /* E_UTIL_H */ -- cgit v1.2.3