diff --git a/libgimp/gimpresource.c b/libgimp/gimpresource.c index 202bed4f91..ff3b4ec7d9 100644 --- a/libgimp/gimpresource.c +++ b/libgimp/gimpresource.c @@ -112,6 +112,8 @@ typedef struct _GimpResourcePrivate } GimpResourcePrivate; +static void gimp_resource_config_iface_init (GimpConfigInterface *iface); + static void gimp_resource_set_property (GObject *object, guint property_id, const GValue *value, @@ -121,8 +123,21 @@ static void gimp_resource_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static gboolean gimp_resource_serialize (GimpConfig *config, + GimpConfigWriter *writer, + gpointer data); +static GimpConfig * + gimp_resource_deserialize_create (GType type, + GScanner *scanner, + gint nest_level, + gpointer data); -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpResource, gimp_resource, G_TYPE_OBJECT) + +G_DEFINE_TYPE_EXTENDED (GimpResource, gimp_resource, G_TYPE_OBJECT, + G_TYPE_FLAG_ABSTRACT, + G_ADD_PRIVATE (GimpResource) + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, + gimp_resource_config_iface_init)) #define parent_class gimp_resource_parent_class @@ -148,6 +163,13 @@ gimp_resource_class_init (GimpResourceClass *klass) g_object_class_install_properties (object_class, N_PROPS, props); } +static void +gimp_resource_config_iface_init (GimpConfigInterface *iface) +{ + iface->serialize = gimp_resource_serialize; + iface->deserialize_create = gimp_resource_deserialize_create; +} + static void gimp_resource_init (GimpResource *resource) { @@ -195,6 +217,63 @@ gimp_resource_get_property (GObject *object, } } +static gboolean +gimp_resource_serialize (GimpConfig *config, + GimpConfigWriter *writer, + gpointer data) +{ + GimpResource *resource; + gchar *name; + gchar *collection; + gboolean is_internal; + + g_return_val_if_fail (GIMP_IS_RESOURCE (config), FALSE); + + resource = GIMP_RESOURCE (config); + is_internal = _gimp_resource_get_identifiers (resource, &name, &collection); + + if (is_internal) + gimp_config_writer_identifier (writer, "internal"); + gimp_config_writer_string (writer, name); + gimp_config_writer_string (writer, collection); + + g_free (name); + g_free (collection); + + return TRUE; +} + +static GimpConfig * +gimp_resource_deserialize_create (GType type, + GScanner *scanner, + gint nest_level, + gpointer data) +{ + GimpResource *resource = NULL; + gchar *name = NULL; + gchar *collection = NULL; + gboolean is_internal = FALSE; + + if (gimp_scanner_parse_identifier (scanner, "internal")) + is_internal = TRUE; + + if (gimp_scanner_parse_string (scanner, &name) && + gimp_scanner_parse_string (scanner, &collection)) + resource = _gimp_resource_get_by_identifiers (g_type_name (type), name, collection, is_internal); + + if (resource == NULL) + /* Default to context resource. */ + resource = _gimp_context_get_resource (g_type_name (type)); + + if (resource) + g_object_ref (resource); + + g_free (collection); + g_free (name);; + + return GIMP_CONFIG (resource);; +} + /** * gimp_resource_get_id: * @resource: The resource. diff --git a/libgimpconfig/gimpconfig-deserialize.c b/libgimpconfig/gimpconfig-deserialize.c index 8f90b58351..3dd99298dd 100644 --- a/libgimpconfig/gimpconfig-deserialize.c +++ b/libgimpconfig/gimpconfig-deserialize.c @@ -781,8 +781,28 @@ gimp_config_deserialize_object (GValue *value, if (! config_iface) return gimp_config_deserialize_any (value, prop_spec, scanner); - if (! config_iface->deserialize (prop_object, scanner, nest_level + 1, NULL)) - return G_TOKEN_NONE; + if (config_iface->deserialize_create != NULL) + { + /* Some class may prefer to create themselves their objects, for instance + * to maintain unicity of objects (in libgimp in particular, the various + * GimpItem or GimpResource are managed by the lib. A single item or + * resource must be represented for a single object across the whole + * processus. + */ + GimpConfig *created_object; + + created_object = config_iface->deserialize_create (G_TYPE_FROM_INSTANCE (prop_object), + scanner, nest_level + 1, NULL); + + if (created_object == NULL) + return G_TOKEN_NONE; + else + g_value_take_object (value, created_object); + } + else if (! config_iface->deserialize (prop_object, scanner, nest_level + 1, NULL)) + { + return G_TOKEN_NONE; + } return G_TOKEN_RIGHT_PAREN; } diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index a537220d94..131693e487 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -454,7 +454,7 @@ gimp_config_serialize_to_parasite (GimpConfig *config, /** * gimp_config_deserialize_file: - * @config: an oObject that implements the #GimpConfigInterface. + * @config: an object that implements the #GimpConfigInterface. * @file: the file to read configuration from. * @data: user data passed to the deserialize implementation. * @error: return location for a possible error diff --git a/libgimpconfig/gimpconfig-iface.h b/libgimpconfig/gimpconfig-iface.h index 605e999a1a..c142ee6c52 100644 --- a/libgimpconfig/gimpconfig-iface.h +++ b/libgimpconfig/gimpconfig-iface.h @@ -44,6 +44,10 @@ struct _GimpConfigInterface GScanner *scanner, gint nest_level, gpointer data); + GimpConfig * (* deserialize_create) (GType type, + GScanner *scanner, + gint nest_level, + gpointer data); gboolean (* serialize_property) (GimpConfig *config, guint property_id, const GValue *value,