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> 2003-02-28 Sven Neumann <sven@gimp.org>
* app/config/gimpconfig-serialize.[ch]: renamed * app/config/gimpconfig-serialize.[ch]: renamed

View File

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

View File

@ -194,13 +194,10 @@ dump_gimprc_system (GObject *rc,
} }
g_string_append (str, "# "); g_string_append (str, "# ");
write (fd, str->str, str->len);
if (gimp_config_serialize_property (rc, prop_spec, str, TRUE)) if (gimp_config_serialize_property (rc, prop_spec, fd, 0))
{ write (fd, "\n", 1);
g_string_append (str, "\n");
write (fd, str->str, str->len);
}
} }
g_free (property_specs); g_free (property_specs);
@ -300,12 +297,10 @@ dump_gimprc_manpage (GObject *rc,
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
GString *str;
guint n_property_specs; guint n_property_specs;
guint i; guint i;
str = g_string_new (man_page_header); write (fd, man_page_header, strlen (man_page_header));
write (fd, str->str, str->len);
klass = G_OBJECT_GET_CLASS (rc); klass = G_OBJECT_GET_CLASS (rc);
property_specs = g_object_class_list_properties (klass, &n_property_specs); 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)) if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
continue; 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, "\n", 1);
write (fd, str->str, str->len);
desc = dump_describe_param (prop_spec); desc = dump_describe_param (prop_spec);
@ -336,7 +329,6 @@ dump_gimprc_manpage (GObject *rc,
} }
g_free (property_specs); g_free (property_specs);
g_string_free (str, TRUE);
write (fd, man_page_path, strlen (man_page_path)); write (fd, man_page_path, strlen (man_page_path));
write (fd, man_page_footer, strlen (man_page_footer)); 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,\ gimp_param_spec_memsize (name, NULL, blurb,\
min, max, default,\ min, max, default,\
flags | GIMP_CONFIG_PARAM_FLAGS)) 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,\ #define GIMP_CONFIG_INSTALL_PROP_PATH(class, id,\
name, blurb, type, default, flags)\ name, blurb, type, default, flags)\
g_object_class_install_property (class, id,\ g_object_class_install_property (class, id,\
@ -181,4 +175,15 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
flags | GIMP_CONFIG_PARAM_FLAGS)) 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__ */ #endif /* __GIMP_CONFIG_PARAMS_H__ */

View File

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

View File

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

View File

@ -27,6 +27,7 @@
#include "libgimpbase/gimpenv.h" #include "libgimpbase/gimpenv.h"
#include "gimpconfig.h"
#include "gimpconfig-utils.h" #include "gimpconfig-utils.h"
@ -170,6 +171,8 @@ gimp_config_copy_properties (GObject *src,
if (!property_specs) if (!property_specs)
return; return;
g_object_freeze_notify (dest);
for (i = 0; i < n_property_specs; i++) for (i = 0; i < n_property_specs; i++)
{ {
GParamSpec *prop_spec; GParamSpec *prop_spec;
@ -191,6 +194,8 @@ gimp_config_copy_properties (GObject *src,
} }
g_free (property_specs); g_free (property_specs);
g_object_thaw_notify (dest);
} }
/** /**
@ -205,6 +210,7 @@ gimp_config_reset_properties (GObject *object)
{ {
GObjectClass *klass; GObjectClass *klass;
GParamSpec **property_specs; GParamSpec **property_specs;
GValue value = { 0, };
guint n_property_specs; guint n_property_specs;
guint i; guint i;
@ -217,17 +223,30 @@ gimp_config_reset_properties (GObject *object)
if (!property_specs) if (!property_specs)
return; return;
g_object_freeze_notify (object);
for (i = 0; i < n_property_specs; i++) for (i = 0; i < n_property_specs; i++)
{ {
GParamSpec *prop_spec; GParamSpec *prop_spec;
prop_spec = property_specs[i]; prop_spec = property_specs[i];
if ((prop_spec->flags & G_PARAM_WRITABLE) && if (G_IS_PARAM_SPEC_OBJECT (prop_spec))
! G_IS_PARAM_SPEC_OBJECT (prop_spec)) {
{ if (g_type_interface_peek (g_type_class_peek (prop_spec->value_type),
GValue value = { 0, }; 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_value_init (&value, prop_spec->value_type);
g_param_value_set_default (prop_spec, &value); g_param_value_set_default (prop_spec, &value);
@ -238,6 +257,8 @@ gimp_config_reset_properties (GObject *object)
} }
g_free (property_specs); 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], gimp_context_prop_names[GIMP_CONTEXT_PROP_BRUSH],
NULL, NULL,
GIMP_TYPE_BRUSH, GIMP_TYPE_BRUSH,
0); G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PATTERN, GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PATTERN,
gimp_context_prop_names[GIMP_CONTEXT_PROP_PATTERN], gimp_context_prop_names[GIMP_CONTEXT_PROP_PATTERN],
NULL, NULL,
GIMP_TYPE_PATTERN, GIMP_TYPE_PATTERN,
0); G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_GRADIENT, GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_GRADIENT,
gimp_context_prop_names[GIMP_CONTEXT_PROP_GRADIENT], gimp_context_prop_names[GIMP_CONTEXT_PROP_GRADIENT],
NULL, NULL,
GIMP_TYPE_GRADIENT, GIMP_TYPE_GRADIENT,
0); G_PARAM_WRITABLE);
GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PALETTE, GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PALETTE,
gimp_context_prop_names[GIMP_CONTEXT_PROP_PALETTE], gimp_context_prop_names[GIMP_CONTEXT_PROP_PALETTE],
NULL, NULL,
GIMP_TYPE_PALETTE, GIMP_TYPE_PALETTE,
0); G_PARAM_WRITABLE);
g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_BUFFER, g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_BUFFER,
g_param_spec_object (gimp_context_prop_names[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 "tools-types.h"
#include "config/gimpconfig.h" #include "config/gimpconfig.h"
#include "config/gimpconfig-deserialize.h" #include "config/gimpconfig-params.h"
#include "config/gimpconfig-serialize.h"
#include "core/gimptoolinfo.h" #include "core/gimptoolinfo.h"
@ -44,20 +43,20 @@
#include "libgimp/gimpintl.h" #include "libgimp/gimpintl.h"
static void gimp_text_options_init (GimpTextOptions *options); enum
static void gimp_text_options_class_init (GimpTextOptionsClass *options_class); {
static void gimp_text_options_config_iface_init (GimpConfigInterface *config_iface); PROP_0,
PROP_TEXT,
};
static void gimp_text_options_reset (GimpToolOptions *tool_options);
static gboolean gimp_text_options_serialize (GObject *object, static void gimp_text_options_init (GimpTextOptions *options);
gint fd, static void gimp_text_options_class_init (GimpTextOptionsClass *options_class);
gint indent_level,
gpointer data); static void gimp_text_options_get_property (GObject *object,
static gboolean gimp_text_options_deserialize (GObject *object, guint property_id,
GScanner *scanner, GValue *value,
gint nest_level, GParamSpec *pspec);
gpointer data);
static GimpToolOptionsClass *parent_class = NULL; static GimpToolOptionsClass *parent_class = NULL;
@ -82,20 +81,10 @@ gimp_text_options_get_type (void)
0, /* n_preallocs */ 0, /* n_preallocs */
(GInstanceInitFunc) gimp_text_options_init, (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, type = g_type_register_static (GIMP_TYPE_TOOL_OPTIONS,
"GimpTextOptions", "GimpTextOptions",
&info, 0); &info, 0);
g_type_add_interface_static (type,
GIMP_TYPE_CONFIG_INTERFACE,
&config_iface_info);
} }
return type; return type;
@ -104,22 +93,18 @@ gimp_text_options_get_type (void)
static void static void
gimp_text_options_class_init (GimpTextOptionsClass *klass) gimp_text_options_class_init (GimpTextOptionsClass *klass)
{ {
GObjectClass *object_class; GObjectClass *object_class;
GimpToolOptionsClass *options_class;
object_class = G_OBJECT_CLASS (klass); object_class = G_OBJECT_CLASS (klass);
options_class = GIMP_TOOL_OPTIONS_CLASS (klass);
parent_class = g_type_class_peek_parent (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_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_TEXT,
gimp_text_options_config_iface_init (GimpConfigInterface *config_iface) "text", NULL,
{ GIMP_TYPE_TEXT,
config_iface->serialize = gimp_text_options_serialize; 0);
config_iface->deserialize = gimp_text_options_deserialize;
} }
static void static void
@ -129,43 +114,29 @@ gimp_text_options_init (GimpTextOptions *options)
text = g_object_new (GIMP_TYPE_TEXT, NULL); 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); 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 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 * GtkWidget *

View File

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

View File

@ -149,12 +149,6 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
gimp_param_spec_memsize (name, NULL, blurb,\ gimp_param_spec_memsize (name, NULL, blurb,\
min, max, default,\ min, max, default,\
flags | GIMP_CONFIG_PARAM_FLAGS)) 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,\ #define GIMP_CONFIG_INSTALL_PROP_PATH(class, id,\
name, blurb, type, default, flags)\ name, blurb, type, default, flags)\
g_object_class_install_property (class, id,\ g_object_class_install_property (class, id,\
@ -181,4 +175,15 @@ GParamSpec * gimp_param_spec_unit (const gchar *name,
flags | GIMP_CONFIG_PARAM_FLAGS)) 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__ */ #endif /* __GIMP_CONFIG_PARAMS_H__ */

View File

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

View File

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

View File

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