mirror of https://github.com/GNOME/gimp.git
libgimp, libgimpconfig: GimpResource can now be (de)serialized.
I add a new class method deserialize_create() to GimpConfigInterface which returns the GimpConfig object per deserialization, instead of modifying an existing bare object. This matters for cases like our GimpResource (and later our GimpItem) classes which are fully managed by libgimp and should be unique objects per actual resource. It should even be possible to compare the pointer itself for identity. That's why we need to let GimpResource create the object (in reality request it to the infra and only ref it) through this new class method. With this commit and the previous ones, all GimpResource are now properly stored as plug-in settings (e.g. the "film" plug-in has a font setting which is now properly remembered). These identifiers are not portable (across various installations and therefore not for XCF either), but at least they are reasonably identifying data on a same installation (unlike GimpResource's int ID which is only valid within a single session) which makes them very fine for plug-in settings storage. When a data file disappears, we fallback to the context default data instead.
This commit is contained in:
parent
38c717b149
commit
ce0a84003c
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue