app/config/gimpconfig-deserialize.c transparently serialize and

2003-02-28  Sven Neumann  <sven@gimp.org>

	* app/config/gimpconfig-deserialize.c
	* app/config/gimpconfig-serialize.[ch]: transparently serialize
	and deserialize object properties that implement the
	GimpConfigInterface.

	* app/config/gimpconfig-utils.c (gimp_config_reset_properties):
	call reset recursively if properties are itself objects that
	implement the GimpConfigInterface.

	* app/config/gimpconfig-dump.c: adapt to API changes.

	* app/config/gimpconfig-params.h: made object properties installed
	using GIMP_CONFIG_INSTALL_PROP_OBJECT() be not writable by default.

	* app/core/gimpcontext.c (gimp_context_class_init): made objects
	properties explicitely writeable.

	* app/tools/gimptextoptions.c: made the GimpText object a property
	of GimpTextOptions and removed lots of special handling which is
	now transparently done by GimpConfigInterface.
This commit is contained in:
Sven Neumann 2003-02-28 17:01:13 +00:00 committed by Sven Neumann
parent 25c715c1f4
commit f050987238
14 changed files with 374 additions and 222 deletions

View File

@ -1,3 +1,26 @@
2003-02-28 Sven Neumann <sven@gimp.org>
* app/config/gimpconfig-deserialize.c
* app/config/gimpconfig-serialize.[ch]: transparently serialize
and deserialize object properties that implement the
GimpConfigInterface.
* app/config/gimpconfig-utils.c (gimp_config_reset_properties):
call reset recursively if properties are itself objects that
implement the GimpConfigInterface.
* app/config/gimpconfig-dump.c: adapt to API changes.
* app/config/gimpconfig-params.h: made object properties installed
using GIMP_CONFIG_INSTALL_PROP_OBJECT() be not writable by default.
* app/core/gimpcontext.c (gimp_context_class_init): made objects
properties explicitely writeable.
* app/tools/gimptextoptions.c: made the GimpText object a property
of GimpTextOptions and removed lots of special handling which is
now transparently done by GimpConfigInterface.
2003-02-28 Sven Neumann <sven@gimp.org>
* app/config/gimpconfig-serialize.[ch]: renamed

View File

@ -54,7 +54,8 @@
static GTokenType gimp_config_deserialize_unknown (GObject *object,
GScanner *scanner);
static GTokenType gimp_config_deserialize_property (GObject *object,
GScanner *scanner);
GScanner *scanner,
gint nest_level);
static GTokenType gimp_config_deserialize_value (GValue *value,
GObject *object,
GParamSpec *prop_spec,
@ -74,6 +75,11 @@ static GTokenType gimp_config_deserialize_path (GValue *value,
static GTokenType gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_object (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner,
gint nest_level);
static GTokenType gimp_config_deserialize_value_array (GValue *value,
GObject *object,
GParamSpec *prop_spec,
@ -142,6 +148,8 @@ gimp_config_deserialize_properties (GObject *object,
g_free (property_specs);
g_object_freeze_notify (object);
token = G_TOKEN_LEFT_PAREN;
while (TRUE)
@ -168,7 +176,8 @@ gimp_config_deserialize_properties (GObject *object,
break;
case G_TOKEN_SYMBOL:
token = gimp_config_deserialize_property (object, scanner);
token = gimp_config_deserialize_property (object,
scanner, nest_level);
break;
case G_TOKEN_RIGHT_PAREN:
@ -182,6 +191,8 @@ gimp_config_deserialize_properties (GObject *object,
g_scanner_set_scope (scanner, old_scope_id);
g_object_thaw_notify (object);
/* If store_unknown_tokens is TRUE but the unknown token value couldn't
be parsed the default error message is rather confusing.
We try to produce something more meaningful here ... */
@ -223,7 +234,8 @@ gimp_config_deserialize_unknown (GObject *object,
static GTokenType
gimp_config_deserialize_property (GObject *object,
GScanner *scanner)
GScanner *scanner,
gint nest_level)
{
GTypeClass *owner_class;
GimpConfigInterface *gimp_config_iface;
@ -275,14 +287,20 @@ gimp_config_deserialize_property (GObject *object,
}
else
{
token = gimp_config_deserialize_value (&value,
object, prop_spec, scanner);
if (G_VALUE_HOLDS_OBJECT (&value))
token = gimp_config_deserialize_object (&value,
object, prop_spec,
scanner, nest_level);
else
token = gimp_config_deserialize_value (&value,
object, prop_spec, scanner);
}
if (token == G_TOKEN_RIGHT_PAREN &&
g_scanner_peek_next_token (scanner) == token)
{
g_object_set_property (object, prop_spec->name, &value);
if (!G_VALUE_HOLDS_OBJECT (&value))
g_object_set_property (object, prop_spec->name, &value);
}
#if CONFIG_DEBUG
else
@ -528,7 +546,7 @@ gimp_config_deserialize_path (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
GError *error = NULL;
GError *error = NULL;
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
return G_TOKEN_STRING;
@ -579,6 +597,35 @@ gimp_config_deserialize_color (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
gimp_config_deserialize_object (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner,
gint nest_level)
{
GimpConfigInterface *gimp_config_iface;
GObject *prop_object;
g_object_get_property (object, prop_spec->name, value);
prop_object = g_value_get_object (value);
if (! prop_object)
return G_TOKEN_RIGHT_PAREN;
gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (prop_object);
if (! gimp_config_iface)
return gimp_config_deserialize_any (value, prop_spec, scanner);
if (! gimp_config_iface->deserialize (prop_object,
scanner, nest_level + 1, NULL))
return G_TOKEN_NONE;
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
gimp_config_deserialize_value_array (GValue *value,
GObject *object,

View File

@ -194,13 +194,10 @@ dump_gimprc_system (GObject *rc,
}
g_string_append (str, "# ");
write (fd, str->str, str->len);
if (gimp_config_serialize_property (rc, prop_spec, str, TRUE))
{
g_string_append (str, "\n");
write (fd, str->str, str->len);
}
if (gimp_config_serialize_property (rc, prop_spec, fd, 0))
write (fd, "\n", 1);
}
g_free (property_specs);
@ -300,12 +297,10 @@ dump_gimprc_manpage (GObject *rc,
{
GObjectClass *klass;
GParamSpec **property_specs;
GString *str;
guint n_property_specs;
guint i;
str = g_string_new (man_page_header);
write (fd, str->str, str->len);
write (fd, man_page_header, strlen (man_page_header));
klass = G_OBJECT_GET_CLASS (rc);
property_specs = g_object_class_list_properties (klass, &n_property_specs);
@ -318,13 +313,11 @@ dump_gimprc_manpage (GObject *rc,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
g_string_assign (str, ".TP\n");
write (fd, ".TP\n", strlen (".TP\n"));
if (gimp_config_serialize_property (rc, prop_spec, str, TRUE))
if (gimp_config_serialize_property (rc, prop_spec, fd, 0))
{
g_string_append (str, "\n");
write (fd, str->str, str->len);
write (fd, "\n", 1);
desc = dump_describe_param (prop_spec);
@ -336,7 +329,6 @@ dump_gimprc_manpage (GObject *rc,
}
g_free (property_specs);
g_string_free (str, TRUE);
write (fd, man_page_path, strlen (man_page_path));
write (fd, man_page_footer, strlen (man_page_footer));

View File

@ -149,12 +149,6 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
gimp_param_spec_memsize (name, NULL, blurb,\
min, max, default,\
flags | GIMP_CONFIG_PARAM_FLAGS))
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
name, blurb, object_type, flags)\
g_object_class_install_property (class, id,\
g_param_spec_object (name, NULL, blurb,\
object_type,\
flags | GIMP_CONFIG_PARAM_FLAGS))
#define GIMP_CONFIG_INSTALL_PROP_PATH(class, id,\
name, blurb, type, default, flags)\
g_object_class_install_property (class, id,\
@ -181,4 +175,15 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
flags | GIMP_CONFIG_PARAM_FLAGS))
/* object properties are _not_ writeable by default */
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
name, blurb, object_type, flags)\
g_object_class_install_property (class, id,\
g_param_spec_object (name, NULL, blurb,\
object_type,\
flags |\
G_PARAM_READABLE | GIMP_PARAM_SERIALIZE))
#endif /* __GIMP_CONFIG_PARAMS_H__ */

View File

@ -64,7 +64,6 @@ gimp_config_serialize_properties (GObject *object,
GParamSpec **property_specs;
guint n_property_specs;
guint i;
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -75,8 +74,6 @@ gimp_config_serialize_properties (GObject *object,
if (! property_specs)
return TRUE;
str = g_string_new (NULL);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec = property_specs[i];
@ -84,19 +81,12 @@ gimp_config_serialize_properties (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_free (property_specs);
g_string_free (str, TRUE);
return TRUE;
}
@ -118,7 +108,6 @@ gimp_config_serialize_changed_properties (GObject *object,
GParamSpec **property_specs;
guint n_property_specs;
guint i;
GString *str;
GValue value = { 0, };
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -130,8 +119,6 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! property_specs)
return TRUE;
str = g_string_new (NULL);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec = property_specs[i];
@ -144,22 +131,15 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! g_param_value_defaults (prop_spec, &value))
{
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_value_unset (&value);
}
g_free (property_specs);
g_string_free (str, TRUE);
return TRUE;
}
@ -183,7 +163,6 @@ gimp_config_serialize_properties_diff (GObject *object,
GObjectClass *klass;
GList *diff;
GList *list;
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
g_return_val_if_fail (G_IS_OBJECT (compare), FALSE);
@ -197,8 +176,6 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! diff)
return TRUE;
str = g_string_new (NULL);
for (list = diff; list; list = g_list_next (list))
{
GParamSpec *prop_spec = (GParamSpec *) list->data;
@ -206,18 +183,11 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_string_free (str, TRUE);
g_list_free (diff);
return TRUE;
@ -225,20 +195,23 @@ gimp_config_serialize_properties_diff (GObject *object,
gboolean
gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
GString *str,
gboolean escaped)
gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
gint fd,
gint indent_level)
{
GTypeClass *owner_class;
GimpConfigInterface *config_iface;
GimpConfigInterface *parent_iface = NULL;
GValue value = { 0, };
GString *str;
GValue value = { 0, };
gboolean success = FALSE;
if (! (param_spec->flags & GIMP_PARAM_SERIALIZE))
return FALSE;
str = g_string_new (NULL);
gimp_config_string_indent (str, indent_level);
g_string_append_printf (str, "(%s ", param_spec->name);
g_value_init (&value, param_spec->value_type);
@ -285,15 +258,53 @@ gimp_config_serialize_property (GObject *object,
* FALSE, continue with the default implementation
*/
if (! success && gimp_config_serialize_value (&value, str, escaped))
if (! success)
{
success = TRUE;
if (G_VALUE_HOLDS_OBJECT (&value))
{
GimpConfigInterface *gimp_config_iface = NULL;
GObject *prop_object;
prop_object = g_value_get_object (&value);
if (prop_object)
gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (prop_object);
else
success = TRUE;
if (gimp_config_iface)
{
g_string_append_c (str, '\n');
write (fd, str->str, str->len);
g_string_truncate (str, 0);
success = gimp_config_iface->serialize (prop_object,
fd, indent_level + 1,
NULL);
success = TRUE;
}
}
else
{
success = gimp_config_serialize_value (&value, str, TRUE);
}
}
if (success)
{
g_string_append (str, ")\n");
if (write (fd, str->str, str->len) == -1)
success = FALSE;
}
if (! success)
{
/* don't warn for empty string properties */
if (! G_VALUE_HOLDS_STRING (&value))
if (G_VALUE_HOLDS_STRING (&value))
success = TRUE;
else
g_warning ("couldn't serialize property %s::%s of type %s",
g_type_name (G_TYPE_FROM_INSTANCE (object)),
param_spec->name,
@ -302,8 +313,7 @@ gimp_config_serialize_property (GObject *object,
g_value_unset (&value);
if (success)
g_string_append (str, ")\n");
g_string_free (str, TRUE);
return success;
}
@ -425,7 +435,7 @@ gimp_config_serialize_value (const GValue *value,
if (! gimp_config_serialize_value (g_value_array_get_nth (array,
i),
str, escaped))
str, TRUE))
return FALSE;
}
}

View File

@ -39,8 +39,8 @@ gboolean gimp_config_serialize_unknown_tokens (GObject *object,
gboolean gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
GString *str,
gboolean escaped);
gint fd,
gint indent_level);
gboolean gimp_config_serialize_value (const GValue *value,
GString *str,
gboolean escaped);

View File

@ -27,6 +27,7 @@
#include "libgimpbase/gimpenv.h"
#include "gimpconfig.h"
#include "gimpconfig-utils.h"
@ -170,6 +171,8 @@ gimp_config_copy_properties (GObject *src,
if (!property_specs)
return;
g_object_freeze_notify (dest);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec;
@ -191,6 +194,8 @@ gimp_config_copy_properties (GObject *src,
}
g_free (property_specs);
g_object_thaw_notify (dest);
}
/**
@ -205,6 +210,7 @@ gimp_config_reset_properties (GObject *object)
{
GObjectClass *klass;
GParamSpec **property_specs;
GValue value = { 0, };
guint n_property_specs;
guint i;
@ -217,17 +223,30 @@ gimp_config_reset_properties (GObject *object)
if (!property_specs)
return;
g_object_freeze_notify (object);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec;
prop_spec = property_specs[i];
if ((prop_spec->flags & G_PARAM_WRITABLE) &&
! G_IS_PARAM_SPEC_OBJECT (prop_spec))
{
GValue value = { 0, };
if (G_IS_PARAM_SPEC_OBJECT (prop_spec))
{
if (g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
GIMP_TYPE_CONFIG_INTERFACE))
{
g_value_init (&value, prop_spec->value_type);
g_object_get_property (object, prop_spec->name, &value);
gimp_config_reset (g_value_get_object (&value));
g_value_unset (&value);
}
}
else if (prop_spec->flags & G_PARAM_WRITABLE)
{
g_value_init (&value, prop_spec->value_type);
g_param_value_set_default (prop_spec, &value);
@ -238,6 +257,8 @@ gimp_config_reset_properties (GObject *object)
}
g_free (property_specs);
g_object_thaw_notify (object);
}

View File

@ -560,25 +560,25 @@ gimp_context_class_init (GimpContextClass *klass)
gimp_context_prop_names[GIMP_CONTEXT_PROP_BRUSH],
NULL,
GIMP_TYPE_BRUSH,
0);
G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PATTERN,
gimp_context_prop_names[GIMP_CONTEXT_PROP_PATTERN],
NULL,
GIMP_TYPE_PATTERN,
0);
G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_GRADIENT,
gimp_context_prop_names[GIMP_CONTEXT_PROP_GRADIENT],
NULL,
GIMP_TYPE_GRADIENT,
0);
G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PALETTE,
gimp_context_prop_names[GIMP_CONTEXT_PROP_PALETTE],
NULL,
GIMP_TYPE_PALETTE,
0);
G_PARAM_WRITABLE);
g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_BUFFER,
g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_BUFFER],

View File

@ -26,8 +26,7 @@
#include "tools-types.h"
#include "config/gimpconfig.h"
#include "config/gimpconfig-deserialize.h"
#include "config/gimpconfig-serialize.h"
#include "config/gimpconfig-params.h"
#include "core/gimptoolinfo.h"
@ -44,20 +43,20 @@
#include "libgimp/gimpintl.h"
static void gimp_text_options_init (GimpTextOptions *options);
static void gimp_text_options_class_init (GimpTextOptionsClass *options_class);
static void gimp_text_options_config_iface_init (GimpConfigInterface *config_iface);
enum
{
PROP_0,
PROP_TEXT,
};
static void gimp_text_options_reset (GimpToolOptions *tool_options);
static gboolean gimp_text_options_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data);
static gboolean gimp_text_options_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data);
static void gimp_text_options_init (GimpTextOptions *options);
static void gimp_text_options_class_init (GimpTextOptionsClass *options_class);
static void gimp_text_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static GimpToolOptionsClass *parent_class = NULL;
@ -82,20 +81,10 @@ gimp_text_options_get_type (void)
0, /* n_preallocs */
(GInstanceInitFunc) gimp_text_options_init,
};
static const GInterfaceInfo config_iface_info =
{
(GInterfaceInitFunc) gimp_text_options_config_iface_init,
NULL, /* iface_finalize */
NULL /* iface_data */
};
type = g_type_register_static (GIMP_TYPE_TOOL_OPTIONS,
"GimpTextOptions",
&info, 0);
g_type_add_interface_static (type,
GIMP_TYPE_CONFIG_INTERFACE,
&config_iface_info);
}
return type;
@ -104,22 +93,18 @@ gimp_text_options_get_type (void)
static void
gimp_text_options_class_init (GimpTextOptionsClass *klass)
{
GObjectClass *object_class;
GimpToolOptionsClass *options_class;
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
options_class = GIMP_TOOL_OPTIONS_CLASS (klass);
object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
options_class->reset = gimp_text_options_reset;
}
object_class->get_property = gimp_text_options_get_property;
static void
gimp_text_options_config_iface_init (GimpConfigInterface *config_iface)
{
config_iface->serialize = gimp_text_options_serialize;
config_iface->deserialize = gimp_text_options_deserialize;
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_TEXT,
"text", NULL,
GIMP_TYPE_TEXT,
0);
}
static void
@ -129,43 +114,29 @@ gimp_text_options_init (GimpTextOptions *options)
text = g_object_new (GIMP_TYPE_TEXT, NULL);
options->text = GIMP_TEXT (text);
options->text = GIMP_TEXT (text);
options->buffer = gimp_prop_text_buffer_new (text, "text", -1);
}
static gboolean
gimp_text_options_serialize (GObject *object,
gint fd,
gint indent_level,
gpointer data)
{
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
return gimp_config_serialize_properties (G_OBJECT (options->text),
fd, indent_level);
}
static gboolean
gimp_text_options_deserialize (GObject *object,
GScanner *scanner,
gint nest_level,
gpointer data)
{
GimpTextOptions *options = GIMP_TEXT_OPTIONS (object);
return gimp_config_deserialize_properties (G_OBJECT (options->text),
scanner, nest_level, FALSE);
}
static void
gimp_text_options_reset (GimpToolOptions *tool_options)
gimp_text_options_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpTextOptions *options = GIMP_TEXT_OPTIONS (tool_options);
GimpTextOptions *options;
gimp_config_reset (G_OBJECT (options->text));
options = GIMP_TEXT_OPTIONS (object);
GIMP_TOOL_OPTIONS_CLASS (parent_class)->reset (tool_options);
switch (property_id)
{
case PROP_TEXT:
g_value_set_object (value, options->text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
GtkWidget *

View File

@ -54,7 +54,8 @@
static GTokenType gimp_config_deserialize_unknown (GObject *object,
GScanner *scanner);
static GTokenType gimp_config_deserialize_property (GObject *object,
GScanner *scanner);
GScanner *scanner,
gint nest_level);
static GTokenType gimp_config_deserialize_value (GValue *value,
GObject *object,
GParamSpec *prop_spec,
@ -74,6 +75,11 @@ static GTokenType gimp_config_deserialize_path (GValue *value,
static GTokenType gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_object (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner,
gint nest_level);
static GTokenType gimp_config_deserialize_value_array (GValue *value,
GObject *object,
GParamSpec *prop_spec,
@ -142,6 +148,8 @@ gimp_config_deserialize_properties (GObject *object,
g_free (property_specs);
g_object_freeze_notify (object);
token = G_TOKEN_LEFT_PAREN;
while (TRUE)
@ -168,7 +176,8 @@ gimp_config_deserialize_properties (GObject *object,
break;
case G_TOKEN_SYMBOL:
token = gimp_config_deserialize_property (object, scanner);
token = gimp_config_deserialize_property (object,
scanner, nest_level);
break;
case G_TOKEN_RIGHT_PAREN:
@ -182,6 +191,8 @@ gimp_config_deserialize_properties (GObject *object,
g_scanner_set_scope (scanner, old_scope_id);
g_object_thaw_notify (object);
/* If store_unknown_tokens is TRUE but the unknown token value couldn't
be parsed the default error message is rather confusing.
We try to produce something more meaningful here ... */
@ -223,7 +234,8 @@ gimp_config_deserialize_unknown (GObject *object,
static GTokenType
gimp_config_deserialize_property (GObject *object,
GScanner *scanner)
GScanner *scanner,
gint nest_level)
{
GTypeClass *owner_class;
GimpConfigInterface *gimp_config_iface;
@ -275,14 +287,20 @@ gimp_config_deserialize_property (GObject *object,
}
else
{
token = gimp_config_deserialize_value (&value,
object, prop_spec, scanner);
if (G_VALUE_HOLDS_OBJECT (&value))
token = gimp_config_deserialize_object (&value,
object, prop_spec,
scanner, nest_level);
else
token = gimp_config_deserialize_value (&value,
object, prop_spec, scanner);
}
if (token == G_TOKEN_RIGHT_PAREN &&
g_scanner_peek_next_token (scanner) == token)
{
g_object_set_property (object, prop_spec->name, &value);
if (!G_VALUE_HOLDS_OBJECT (&value))
g_object_set_property (object, prop_spec->name, &value);
}
#if CONFIG_DEBUG
else
@ -528,7 +546,7 @@ gimp_config_deserialize_path (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
GError *error = NULL;
GError *error = NULL;
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
return G_TOKEN_STRING;
@ -579,6 +597,35 @@ gimp_config_deserialize_color (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
gimp_config_deserialize_object (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner,
gint nest_level)
{
GimpConfigInterface *gimp_config_iface;
GObject *prop_object;
g_object_get_property (object, prop_spec->name, value);
prop_object = g_value_get_object (value);
if (! prop_object)
return G_TOKEN_RIGHT_PAREN;
gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (prop_object);
if (! gimp_config_iface)
return gimp_config_deserialize_any (value, prop_spec, scanner);
if (! gimp_config_iface->deserialize (prop_object,
scanner, nest_level + 1, NULL))
return G_TOKEN_NONE;
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
gimp_config_deserialize_value_array (GValue *value,
GObject *object,

View File

@ -149,12 +149,6 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
gimp_param_spec_memsize (name, NULL, blurb,\
min, max, default,\
flags | GIMP_CONFIG_PARAM_FLAGS))
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
name, blurb, object_type, flags)\
g_object_class_install_property (class, id,\
g_param_spec_object (name, NULL, blurb,\
object_type,\
flags | GIMP_CONFIG_PARAM_FLAGS))
#define GIMP_CONFIG_INSTALL_PROP_PATH(class, id,\
name, blurb, type, default, flags)\
g_object_class_install_property (class, id,\
@ -181,4 +175,15 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
flags | GIMP_CONFIG_PARAM_FLAGS))
/* object properties are _not_ writeable by default */
#define GIMP_CONFIG_INSTALL_PROP_OBJECT(class, id,\
name, blurb, object_type, flags)\
g_object_class_install_property (class, id,\
g_param_spec_object (name, NULL, blurb,\
object_type,\
flags |\
G_PARAM_READABLE | GIMP_PARAM_SERIALIZE))
#endif /* __GIMP_CONFIG_PARAMS_H__ */

View File

@ -64,7 +64,6 @@ gimp_config_serialize_properties (GObject *object,
GParamSpec **property_specs;
guint n_property_specs;
guint i;
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -75,8 +74,6 @@ gimp_config_serialize_properties (GObject *object,
if (! property_specs)
return TRUE;
str = g_string_new (NULL);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec = property_specs[i];
@ -84,19 +81,12 @@ gimp_config_serialize_properties (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_free (property_specs);
g_string_free (str, TRUE);
return TRUE;
}
@ -118,7 +108,6 @@ gimp_config_serialize_changed_properties (GObject *object,
GParamSpec **property_specs;
guint n_property_specs;
guint i;
GString *str;
GValue value = { 0, };
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
@ -130,8 +119,6 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! property_specs)
return TRUE;
str = g_string_new (NULL);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec = property_specs[i];
@ -144,22 +131,15 @@ gimp_config_serialize_changed_properties (GObject *object,
if (! g_param_value_defaults (prop_spec, &value))
{
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_value_unset (&value);
}
g_free (property_specs);
g_string_free (str, TRUE);
return TRUE;
}
@ -183,7 +163,6 @@ gimp_config_serialize_properties_diff (GObject *object,
GObjectClass *klass;
GList *diff;
GList *list;
GString *str;
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
g_return_val_if_fail (G_IS_OBJECT (compare), FALSE);
@ -197,8 +176,6 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! diff)
return TRUE;
str = g_string_new (NULL);
for (list = diff; list; list = g_list_next (list))
{
GParamSpec *prop_spec = (GParamSpec *) list->data;
@ -206,18 +183,11 @@ gimp_config_serialize_properties_diff (GObject *object,
if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue;
gimp_config_string_indent (str, indent_level);
if (gimp_config_serialize_property (object, prop_spec, str, TRUE))
{
if (write (fd, str->str, str->len) == -1)
return FALSE;
}
g_string_truncate (str, 0);
if (! gimp_config_serialize_property (object, prop_spec,
fd, indent_level))
return FALSE;
}
g_string_free (str, TRUE);
g_list_free (diff);
return TRUE;
@ -225,20 +195,23 @@ gimp_config_serialize_properties_diff (GObject *object,
gboolean
gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
GString *str,
gboolean escaped)
gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
gint fd,
gint indent_level)
{
GTypeClass *owner_class;
GimpConfigInterface *config_iface;
GimpConfigInterface *parent_iface = NULL;
GValue value = { 0, };
GString *str;
GValue value = { 0, };
gboolean success = FALSE;
if (! (param_spec->flags & GIMP_PARAM_SERIALIZE))
return FALSE;
str = g_string_new (NULL);
gimp_config_string_indent (str, indent_level);
g_string_append_printf (str, "(%s ", param_spec->name);
g_value_init (&value, param_spec->value_type);
@ -285,15 +258,53 @@ gimp_config_serialize_property (GObject *object,
* FALSE, continue with the default implementation
*/
if (! success && gimp_config_serialize_value (&value, str, escaped))
if (! success)
{
success = TRUE;
if (G_VALUE_HOLDS_OBJECT (&value))
{
GimpConfigInterface *gimp_config_iface = NULL;
GObject *prop_object;
prop_object = g_value_get_object (&value);
if (prop_object)
gimp_config_iface = GIMP_GET_CONFIG_INTERFACE (prop_object);
else
success = TRUE;
if (gimp_config_iface)
{
g_string_append_c (str, '\n');
write (fd, str->str, str->len);
g_string_truncate (str, 0);
success = gimp_config_iface->serialize (prop_object,
fd, indent_level + 1,
NULL);
success = TRUE;
}
}
else
{
success = gimp_config_serialize_value (&value, str, TRUE);
}
}
if (success)
{
g_string_append (str, ")\n");
if (write (fd, str->str, str->len) == -1)
success = FALSE;
}
if (! success)
{
/* don't warn for empty string properties */
if (! G_VALUE_HOLDS_STRING (&value))
if (G_VALUE_HOLDS_STRING (&value))
success = TRUE;
else
g_warning ("couldn't serialize property %s::%s of type %s",
g_type_name (G_TYPE_FROM_INSTANCE (object)),
param_spec->name,
@ -302,8 +313,7 @@ gimp_config_serialize_property (GObject *object,
g_value_unset (&value);
if (success)
g_string_append (str, ")\n");
g_string_free (str, TRUE);
return success;
}
@ -425,7 +435,7 @@ gimp_config_serialize_value (const GValue *value,
if (! gimp_config_serialize_value (g_value_array_get_nth (array,
i),
str, escaped))
str, TRUE))
return FALSE;
}
}

View File

@ -39,8 +39,8 @@ gboolean gimp_config_serialize_unknown_tokens (GObject *object,
gboolean gimp_config_serialize_property (GObject *object,
GParamSpec *param_spec,
GString *str,
gboolean escaped);
gint fd,
gint indent_level);
gboolean gimp_config_serialize_value (const GValue *value,
GString *str,
gboolean escaped);

View File

@ -27,6 +27,7 @@
#include "libgimpbase/gimpenv.h"
#include "gimpconfig.h"
#include "gimpconfig-utils.h"
@ -170,6 +171,8 @@ gimp_config_copy_properties (GObject *src,
if (!property_specs)
return;
g_object_freeze_notify (dest);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec;
@ -191,6 +194,8 @@ gimp_config_copy_properties (GObject *src,
}
g_free (property_specs);
g_object_thaw_notify (dest);
}
/**
@ -205,6 +210,7 @@ gimp_config_reset_properties (GObject *object)
{
GObjectClass *klass;
GParamSpec **property_specs;
GValue value = { 0, };
guint n_property_specs;
guint i;
@ -217,17 +223,30 @@ gimp_config_reset_properties (GObject *object)
if (!property_specs)
return;
g_object_freeze_notify (object);
for (i = 0; i < n_property_specs; i++)
{
GParamSpec *prop_spec;
prop_spec = property_specs[i];
if ((prop_spec->flags & G_PARAM_WRITABLE) &&
! G_IS_PARAM_SPEC_OBJECT (prop_spec))
{
GValue value = { 0, };
if (G_IS_PARAM_SPEC_OBJECT (prop_spec))
{
if (g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
GIMP_TYPE_CONFIG_INTERFACE))
{
g_value_init (&value, prop_spec->value_type);
g_object_get_property (object, prop_spec->name, &value);
gimp_config_reset (g_value_get_object (&value));
g_value_unset (&value);
}
}
else if (prop_spec->flags & G_PARAM_WRITABLE)
{
g_value_init (&value, prop_spec->value_type);
g_param_value_set_default (prop_spec, &value);
@ -238,6 +257,8 @@ gimp_config_reset_properties (GObject *object)
}
g_free (property_specs);
g_object_thaw_notify (object);
}