mirror of https://github.com/GNOME/gimp.git
added "gint nest_level" to the deserialization functions, so nested calls
2002-05-27 Michael Natterer <mitch@gimp.org> * app/config/gimpconfig.[ch]: added "gint nest_level" to the deserialization functions, so nested calls to deserialize() don't error on the trailing ')'. Made the scanner config parse one-character identifiers and allow G_CSET_A_2_Z for all identifiers. Added gimp_config_deserialize_return() because returning the correct return value from a deserialize() function is not trivial any more with nested calls. * app/config/gimpconfig-deserialize.[ch] * app/config/gimprc.c * app/core/gimpdocumentlist.c * app/core/gimpparasitelist.c: use the new return value utility function and made the main parsing loops simpler. * app/core/gimpunits.c: made the main parsing loops consistent with the stuff that uses GimpConfig. * app/config/gimpconfig-deserialize.c * app/config/gimpconfig-serialize.c: call the (de)serialize_property() functions only if the property's class implements the method itself (does *not* inherit it from one of it's parents). * app/core/gimpcontainer.c: implemented deserialization of containers. For each child entry encountered in the input, check if it's already contained in the container and create it if not. If a "gimp" pointer is passed as user_data pass it as construct property to g_object_new() when creating the object. * app/core/gimpcontext.c: changed deserialization of brush, pattern etc. to honor "no_data". * app/widgets/gimpdeviceinfo.c: added a "gimp" construct_only property which overrides GimpContext's "gimp" property. Moved all initialisation code from gimp_device_info_new() to gimp_device_info_set_property(PROP_GIMP) so it is properly performed if the object is created by GimpContainer's deserialize() implementation. * app/widgets/gimpdevices.c: made gimp_devices_restore_test() work.
This commit is contained in:
parent
9ccebbd48e
commit
dbc8aeb49c
44
ChangeLog
44
ChangeLog
|
@ -1,3 +1,47 @@
|
|||
2002-05-27 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/config/gimpconfig.[ch]: added "gint nest_level" to the
|
||||
deserialization functions, so nested calls to deserialize()
|
||||
don't error on the trailing ')'. Made the scanner config parse
|
||||
one-character identifiers and allow G_CSET_A_2_Z for all
|
||||
identifiers.
|
||||
Added gimp_config_deserialize_return() because returning the
|
||||
correct return value from a deserialize() function is not
|
||||
trivial any more with nested calls.
|
||||
|
||||
* app/config/gimpconfig-deserialize.[ch]
|
||||
* app/config/gimprc.c
|
||||
* app/core/gimpdocumentlist.c
|
||||
* app/core/gimpparasitelist.c: use the new return value utility
|
||||
function and made the main parsing loops simpler.
|
||||
|
||||
* app/core/gimpunits.c: made the main parsing loops consistent
|
||||
with the stuff that uses GimpConfig.
|
||||
|
||||
* app/config/gimpconfig-deserialize.c
|
||||
* app/config/gimpconfig-serialize.c: call the
|
||||
(de)serialize_property() functions only if the property's class
|
||||
implements the method itself (does *not* inherit it from one of
|
||||
it's parents).
|
||||
|
||||
* app/core/gimpcontainer.c: implemented deserialization of
|
||||
containers. For each child entry encountered in the input, check
|
||||
if it's already contained in the container and create it if not.
|
||||
If a "gimp" pointer is passed as user_data pass it as construct
|
||||
property to g_object_new() when creating the object.
|
||||
|
||||
* app/core/gimpcontext.c: changed deserialization of brush,
|
||||
pattern etc. to honor "no_data".
|
||||
|
||||
* app/widgets/gimpdeviceinfo.c: added a "gimp" construct_only
|
||||
property which overrides GimpContext's "gimp" property. Moved all
|
||||
initialisation code from gimp_device_info_new() to
|
||||
gimp_device_info_set_property(PROP_GIMP) so it is properly
|
||||
performed if the object is created by GimpContainer's
|
||||
deserialize() implementation.
|
||||
|
||||
* app/widgets/gimpdevices.c: made gimp_devices_restore_test() work.
|
||||
|
||||
2002-05-27 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* configure.in: restructured, added lots of comments. Reenabled
|
||||
|
|
|
@ -90,6 +90,7 @@ static inline gboolean scanner_string_utf8_valid (GScanner *scanner,
|
|||
* gimp_config_deserialize_properties:
|
||||
* @object: a #GObject.
|
||||
* @scanner: a #GScanner.
|
||||
* @embedded_scope: %TRUE if a trailing ')' should not trigger a parse error.
|
||||
* @store_unknown_tokens: %TRUE if you want to store unknown tokens.
|
||||
*
|
||||
* This function uses the @scanner to configure the properties of @object.
|
||||
|
@ -105,6 +106,7 @@ static inline gboolean scanner_string_utf8_valid (GScanner *scanner,
|
|||
gboolean
|
||||
gimp_config_deserialize_properties (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gboolean store_unknown_tokens)
|
||||
{
|
||||
GObjectClass *klass;
|
||||
|
@ -124,7 +126,7 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
if (!property_specs)
|
||||
return TRUE;
|
||||
|
||||
scope_id = g_quark_from_static_string ("gimp_config_deserialize_properties");
|
||||
scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (object));
|
||||
old_scope_id = g_scanner_set_scope (scanner, scope_id);
|
||||
|
||||
for (i = 0; i < n_property_specs; i++)
|
||||
|
@ -141,8 +143,8 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
g_free (property_specs);
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
next = g_scanner_peek_next_token (scanner);
|
||||
|
||||
|
@ -160,7 +162,7 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_SYMBOL;
|
||||
break;
|
||||
|
||||
|
||||
case G_TOKEN_IDENTIFIER:
|
||||
token = gimp_config_deserialize_unknown (object, scanner);
|
||||
break;
|
||||
|
@ -177,17 +179,11 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (next != G_TOKEN_EOF && next != token && token != G_TOKEN_NONE)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
g_scanner_set_scope (scanner, old_scope_id);
|
||||
|
||||
return (next == G_TOKEN_EOF || next == token);
|
||||
return gimp_config_deserialize_return (scanner, token,
|
||||
nest_level, NULL);
|
||||
}
|
||||
|
||||
static GTokenType
|
||||
|
@ -219,7 +215,9 @@ static GTokenType
|
|||
gimp_config_deserialize_property (GObject *object,
|
||||
GScanner *scanner)
|
||||
{
|
||||
GTypeClass *owner_class;
|
||||
GimpConfigInterface *gimp_config_iface;
|
||||
GimpConfigInterface *parent_iface;
|
||||
GParamSpec *prop_spec;
|
||||
GTokenType token = G_TOKEN_RIGHT_PAREN;
|
||||
GValue value = { 0, };
|
||||
|
@ -228,11 +226,33 @@ gimp_config_deserialize_property (GObject *object,
|
|||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
|
||||
gimp_config_iface =
|
||||
g_type_interface_peek (g_type_class_peek (prop_spec->owner_type),
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
owner_class = g_type_class_peek (prop_spec->owner_type);
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface = g_type_interface_peek (owner_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
|
||||
/* We must call deserialize_property() *only* if the *exact* class
|
||||
* which implements it is param_spec->owner_type's class.
|
||||
*
|
||||
* Therefore, we ask param_spec->owner_type's immediate parent class
|
||||
* for it's GimpConfigInterface and check if we get a different pointer.
|
||||
*
|
||||
* (if the pointers are the same, param_spec->owner_type's
|
||||
* GimpConfigInterface is inherited from one of it's parent classes
|
||||
* and thus not able to handle param_spec->owner_type's properties).
|
||||
*/
|
||||
if (gimp_config_iface)
|
||||
{
|
||||
GTypeClass *owner_parent_class;
|
||||
|
||||
owner_parent_class = g_type_class_peek_parent (owner_class),
|
||||
|
||||
parent_iface = g_type_interface_peek (owner_parent_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
}
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface != parent_iface && /* see comment above */
|
||||
gimp_config_iface->deserialize_property &&
|
||||
gimp_config_iface->deserialize_property (object,
|
||||
prop_spec->param_id,
|
||||
|
@ -385,14 +405,14 @@ gimp_config_deserialize_fundamental (GValue *value,
|
|||
break;
|
||||
case G_TYPE_ULONG:
|
||||
g_value_set_uint (value, scanner->value.v_int);
|
||||
break;
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
g_value_set_float (value, scanner->value.v_float);
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
g_value_set_double (value, scanner->value.v_float);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
@ -519,11 +539,8 @@ gimp_config_deserialize_color (GValue *value,
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -595,7 +612,6 @@ gimp_config_deserialize_color (GValue *value,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
finish:
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
gboolean gimp_config_deserialize_properties (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gboolean store_unknown_tokens);
|
||||
|
||||
|
||||
|
|
|
@ -389,18 +389,42 @@ gimp_config_serialize_property (GObject *object,
|
|||
GString *str,
|
||||
gboolean escaped)
|
||||
{
|
||||
GTypeClass *owner_class;
|
||||
GimpConfigInterface *gimp_config_iface;
|
||||
GimpConfigInterface *parent_iface;
|
||||
GValue value = { 0, };
|
||||
gboolean retval;
|
||||
|
||||
g_value_init (&value, param_spec->value_type);
|
||||
g_object_get_property (object, param_spec->name, &value);
|
||||
|
||||
gimp_config_iface =
|
||||
g_type_interface_peek (g_type_class_peek (param_spec->owner_type),
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
owner_class = g_type_class_peek (param_spec->owner_type);
|
||||
|
||||
gimp_config_iface = g_type_interface_peek (owner_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
|
||||
/* We must call deserialize_property() *only* if the *exact* class
|
||||
* which implements it is param_spec->owner_type's class.
|
||||
*
|
||||
* Therefore, we ask param_spec->owner_type's immediate parent class
|
||||
* for it's GimpConfigInterface and check if we get a different pointer.
|
||||
*
|
||||
* (if the pointers are the same, param_spec->owner_type's
|
||||
* GimpConfigInterface is inherited from one of it's parent classes
|
||||
* and thus not able to handle param_spec->owner_type's properties).
|
||||
*/
|
||||
if (gimp_config_iface)
|
||||
{
|
||||
GTypeClass *owner_parent_class;
|
||||
|
||||
owner_parent_class = g_type_class_peek_parent (owner_class),
|
||||
|
||||
parent_iface = g_type_interface_peek (owner_parent_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
}
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface != parent_iface && /* see comment above */
|
||||
gimp_config_iface->serialize_property &&
|
||||
gimp_config_iface->serialize_property (object,
|
||||
param_spec->param_id,
|
||||
|
|
|
@ -53,6 +53,7 @@ static gboolean gimp_config_iface_serialize (GObject *object,
|
|||
gpointer data);
|
||||
static gboolean gimp_config_iface_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
static GObject *gimp_config_iface_duplicate (GObject *object);
|
||||
static gboolean gimp_config_iface_equal (GObject *a,
|
||||
|
@ -111,9 +112,10 @@ gimp_config_iface_serialize (GObject *object,
|
|||
static gboolean
|
||||
gimp_config_iface_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
return gimp_config_deserialize_properties (object, scanner, FALSE);
|
||||
return gimp_config_deserialize_properties (object, scanner, nest_level, FALSE);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
|
@ -227,7 +229,8 @@ gimp_config_serialize (GObject *object,
|
|||
|
||||
if (success && footer)
|
||||
success = (write (fd, "\n", 1) != -1 &&
|
||||
write (fd, footer, strlen (footer)) != -1);
|
||||
write (fd, footer, strlen (footer)) != -1 &&
|
||||
write (fd, "\n", 1) != -1);
|
||||
|
||||
if (! success)
|
||||
{
|
||||
|
@ -311,10 +314,12 @@ gimp_config_deserialize (GObject *object,
|
|||
scanner->msg_handler = gimp_config_scanner_message;
|
||||
scanner->input_name = filename;
|
||||
|
||||
scanner->config->cset_identifier_first = ( G_CSET_a_2_z );
|
||||
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" );
|
||||
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
|
||||
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
|
||||
|
||||
success = gimp_config_iface->deserialize (object, scanner, data);
|
||||
scanner->config->scan_identifier_1char = TRUE;
|
||||
|
||||
success = gimp_config_iface->deserialize (object, scanner, 0, data);
|
||||
|
||||
g_scanner_destroy (scanner);
|
||||
close (fd);
|
||||
|
@ -325,6 +330,45 @@ gimp_config_deserialize (GObject *object,
|
|||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_config_deserialize_return (GScanner *scanner,
|
||||
GTokenType expected_token,
|
||||
gint nest_level,
|
||||
const gchar *symbol_name)
|
||||
{
|
||||
GTokenType next_token;
|
||||
|
||||
g_return_val_if_fail (scanner != NULL, FALSE);
|
||||
|
||||
next_token = g_scanner_peek_next_token (scanner);
|
||||
|
||||
if (expected_token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, expected_token, NULL, NULL,
|
||||
symbol_name,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (next_token != G_TOKEN_EOF)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, expected_token, NULL, NULL,
|
||||
symbol_name,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GQuark
|
||||
gimp_config_error_quark (void)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@ struct _GimpConfigInterface
|
|||
gpointer data);
|
||||
gboolean (* deserialize) (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
gboolean (* serialize_property) (GObject *object,
|
||||
guint property_id,
|
||||
|
@ -81,6 +82,11 @@ gboolean gimp_config_deserialize (GObject *object,
|
|||
gpointer data,
|
||||
GError **error);
|
||||
|
||||
gboolean gimp_config_deserialize_return (GScanner *scanner,
|
||||
GTokenType expected_token,
|
||||
gint nest_level,
|
||||
const gchar *symbol_name);
|
||||
|
||||
GObject * gimp_config_duplicate (GObject *object);
|
||||
gboolean gimp_config_equal (GObject *a,
|
||||
GObject *b);
|
||||
|
|
|
@ -48,6 +48,7 @@ static gboolean gimp_rc_serialize (GObject *object,
|
|||
gpointer data);
|
||||
static gboolean gimp_rc_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
static GObject * gimp_rc_duplicate (GObject *object);
|
||||
|
||||
|
@ -129,9 +130,10 @@ gimp_rc_serialize (GObject *object,
|
|||
static gboolean
|
||||
gimp_rc_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
return gimp_config_deserialize_properties (object, scanner, TRUE);
|
||||
return gimp_config_deserialize_properties (object, scanner, nest_level, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -120,11 +120,8 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -138,8 +135,8 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
{
|
||||
g_scanner_set_scope (scanner, UNIT_INFO);
|
||||
token = gimp_unitrc_unit_info_deserialize (scanner, gimp);
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
|
||||
if (token == G_TOKEN_RIGHT_PAREN)
|
||||
g_scanner_set_scope (scanner, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -152,7 +149,6 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
|
@ -240,19 +236,13 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
GTokenType token;
|
||||
GimpUnit unit;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &identifier))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -262,42 +252,48 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
break;
|
||||
|
||||
case G_TOKEN_SYMBOL:
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
|
||||
{
|
||||
case UNIT_FACTOR:
|
||||
token = G_TOKEN_FLOAT;
|
||||
if (! gimp_scanner_parse_float (scanner, &factor))
|
||||
return G_TOKEN_FLOAT;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_DIGITS:
|
||||
token = G_TOKEN_INT;
|
||||
if (! gimp_scanner_parse_int (scanner, &digits))
|
||||
return G_TOKEN_INT;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_SYMBOL:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &symbol))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_ABBREV:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &abbreviation))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_SINGULAR:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &singular))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_PLURAL:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &plural))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
|
@ -308,30 +304,23 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
if (gimp_scanner_parse_token (scanner, token))
|
||||
if (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
unit = _gimp_unit_new (gimp, identifier, factor, digits,
|
||||
symbol, abbreviation, singular, plural);
|
||||
|
||||
/* make the unit definition persistent */
|
||||
gimp_unit_set_deletion_flag (unit, FALSE);
|
||||
|
||||
g_free (identifier);
|
||||
g_free (symbol);
|
||||
g_free (abbreviation);
|
||||
g_free (singular);
|
||||
g_free (plural);
|
||||
|
||||
return G_TOKEN_LEFT_PAREN;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
g_free (identifier);
|
||||
g_free (symbol);
|
||||
g_free (abbreviation);
|
||||
|
|
|
@ -30,10 +30,15 @@
|
|||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpcontainer.h"
|
||||
#include "gimpmarshal.h"
|
||||
|
||||
#include "config/gimpconfig.h"
|
||||
#include "config/gimpconfig-deserialize.h"
|
||||
#include "config/gimpscanner.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
/* #define DEBUG_CONTAINER */
|
||||
|
@ -98,6 +103,7 @@ static gboolean gimp_container_serialize (GObject *object,
|
|||
gpointer data);
|
||||
static gboolean gimp_container_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
|
||||
static void gimp_container_disconnect_callback (GimpObject *object,
|
||||
|
@ -434,7 +440,10 @@ gimp_container_serialize_foreach (GObject *object,
|
|||
if (! serialize_data->success)
|
||||
return;
|
||||
|
||||
g_string_assign (str, ")\n");
|
||||
if (serialize_data->indent_level > 0)
|
||||
g_string_assign (str, ")");
|
||||
else
|
||||
g_string_assign (str, ")\n");
|
||||
|
||||
if (write (serialize_data->fd, str->str, str->len) == -1)
|
||||
serialize_data->success = FALSE;
|
||||
|
@ -466,13 +475,123 @@ gimp_container_serialize (GObject *object,
|
|||
static gboolean
|
||||
gimp_container_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
GimpContainer *container;
|
||||
GTokenType token;
|
||||
|
||||
container = GIMP_CONTAINER (object);
|
||||
|
||||
return TRUE;
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_IDENTIFIER;
|
||||
break;
|
||||
|
||||
case G_TOKEN_IDENTIFIER:
|
||||
{
|
||||
GimpObject *child;
|
||||
GType type;
|
||||
gchar *name;
|
||||
|
||||
type = g_type_from_name (scanner->value.v_identifier);
|
||||
|
||||
if (! type)
|
||||
{
|
||||
g_scanner_error (scanner,
|
||||
_("unable to determine type of '%s'"),
|
||||
scanner->value.v_identifier);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! g_type_is_a (type, container->children_type))
|
||||
{
|
||||
g_scanner_error (scanner,
|
||||
_("'%s' is not a subclass of '%s'"),
|
||||
scanner->value.v_identifier,
|
||||
g_type_name (container->children_type));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! g_type_is_a (type, GIMP_TYPE_CONFIG_INTERFACE))
|
||||
{
|
||||
g_scanner_error (scanner,
|
||||
_("'%s' does not implement GimpConfigInterface"),
|
||||
scanner->value.v_identifier);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &name))
|
||||
{
|
||||
token = G_TOKEN_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
child = gimp_container_get_child_by_name (container, name);
|
||||
|
||||
if (child)
|
||||
{
|
||||
g_print ("found child \"%s\"\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("creating child \"%s\"\n", name);
|
||||
|
||||
if (GIMP_IS_GIMP (data))
|
||||
{
|
||||
child = g_object_new (type,
|
||||
"name", name,
|
||||
"gimp", data, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
child = g_object_new (type,
|
||||
"name", name, NULL);
|
||||
}
|
||||
|
||||
gimp_container_add (container, child);
|
||||
|
||||
if (container->policy == GIMP_CONTAINER_POLICY_STRONG)
|
||||
g_object_unref (G_OBJECT (child));
|
||||
}
|
||||
|
||||
{
|
||||
#if 0
|
||||
GimpConfigInterface *config_iface;
|
||||
|
||||
config_iface = GIMP_GET_CONFIG_INTERFACE (child);
|
||||
#endif
|
||||
if (! gimp_config_deserialize_properties (G_OBJECT (child),
|
||||
scanner,
|
||||
nest_level + 1,
|
||||
FALSE))
|
||||
{
|
||||
/* warning should be already set by child */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
break;
|
||||
|
||||
default: /* do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gimp_config_deserialize_return (scanner, token,
|
||||
nest_level, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -574,23 +574,20 @@ gimp_context_class_init (GimpContextClass *klass)
|
|||
gimp_context_prop_types[GIMP_CONTEXT_PROP_BUFFER] = GIMP_TYPE_BUFFER;
|
||||
gimp_context_prop_types[GIMP_CONTEXT_PROP_IMAGEFILE] = GIMP_TYPE_IMAGEFILE;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_GIMP,
|
||||
g_object_class_install_property (object_class, PROP_GIMP,
|
||||
g_param_spec_object ("gimp",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_GIMP,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_IMAGE,
|
||||
g_object_class_install_property (object_class, PROP_IMAGE,
|
||||
g_param_spec_object (gimp_context_prop_names[IMAGE_CHANGED],
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DISPLAY,
|
||||
g_object_class_install_property (object_class, PROP_DISPLAY,
|
||||
g_param_spec_object (gimp_context_prop_names[DISPLAY_CHANGED],
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_OBJECT,
|
||||
|
@ -635,15 +632,13 @@ gimp_context_class_init (GimpContextClass *klass)
|
|||
gimp_context_prop_names[PALETTE_CHANGED],
|
||||
GIMP_TYPE_PALETTE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BUFFER,
|
||||
g_object_class_install_property (object_class, PROP_BUFFER,
|
||||
g_param_spec_object (gimp_context_prop_names[BUFFER_CHANGED],
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_BUFFER,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_IMAGEFILE,
|
||||
g_object_class_install_property (object_class, PROP_IMAGEFILE,
|
||||
g_param_spec_object (gimp_context_prop_names[IMAGEFILE_CHANGED],
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_IMAGEFILE,
|
||||
|
@ -995,7 +990,9 @@ gimp_context_deserialize_property (GObject *object,
|
|||
{
|
||||
GimpContext *context;
|
||||
GimpContainer *container;
|
||||
GimpObject *standard;
|
||||
GimpObject *current;
|
||||
gchar **name_loc;
|
||||
gboolean no_data = FALSE;
|
||||
gchar *object_name;
|
||||
|
||||
context = GIMP_CONTEXT (object);
|
||||
|
@ -1004,33 +1001,42 @@ gimp_context_deserialize_property (GObject *object,
|
|||
{
|
||||
case PROP_TOOL:
|
||||
container = context->gimp->tool_info_list;
|
||||
standard = GIMP_OBJECT (gimp_tool_info_get_standard (context->gimp));
|
||||
current = (GimpObject *) context->tool_info;
|
||||
name_loc = &context->tool_name;
|
||||
no_data = TRUE;
|
||||
break;
|
||||
|
||||
case PROP_BRUSH:
|
||||
container = context->gimp->brush_factory->container;
|
||||
standard = GIMP_OBJECT (gimp_brush_get_standard ());
|
||||
current = (GimpObject *) context->brush;
|
||||
name_loc = &context->brush_name;
|
||||
break;
|
||||
|
||||
case PROP_PATTERN:
|
||||
container = context->gimp->pattern_factory->container;
|
||||
standard = GIMP_OBJECT (gimp_pattern_get_standard ());
|
||||
current = (GimpObject *) context->pattern;
|
||||
name_loc = &context->pattern_name;
|
||||
break;
|
||||
|
||||
case PROP_GRADIENT:
|
||||
container = context->gimp->gradient_factory->container;
|
||||
standard = GIMP_OBJECT (gimp_gradient_get_standard ());
|
||||
current = (GimpObject *) context->gradient;
|
||||
name_loc = &context->gradient_name;
|
||||
break;
|
||||
|
||||
case PROP_PALETTE:
|
||||
container = context->gimp->palette_factory->container;
|
||||
standard = GIMP_OBJECT (gimp_palette_get_standard ());
|
||||
current = (GimpObject *) context->palette;
|
||||
name_loc = &context->palette_name;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! no_data)
|
||||
no_data = context->gimp->no_data;
|
||||
|
||||
if (gimp_scanner_parse_identifier (scanner, "NULL"))
|
||||
{
|
||||
g_value_set_object (value, NULL);
|
||||
|
@ -1044,13 +1050,14 @@ gimp_context_deserialize_property (GObject *object,
|
|||
|
||||
if (! deserialize_obj)
|
||||
{
|
||||
if (gimp_container_num_children (container) > 0)
|
||||
if (no_data)
|
||||
{
|
||||
deserialize_obj = gimp_container_get_child_by_index (container, 0);
|
||||
g_free (*name_loc);
|
||||
*name_loc = g_strdup (object_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
deserialize_obj = standard;
|
||||
deserialize_obj = current;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "gimpdocumentlist.h"
|
||||
#include "gimpimagefile.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
static void gimp_document_list_config_iface_init (gpointer iface,
|
||||
gpointer iface_data);
|
||||
|
@ -44,6 +42,7 @@ static gboolean gimp_document_list_serialize (GObject *list,
|
|||
gpointer data);
|
||||
static gboolean gimp_document_list_deserialize (GObject *list,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
|
||||
|
||||
|
@ -129,6 +128,7 @@ gimp_document_list_serialize (GObject *document_list,
|
|||
static gboolean
|
||||
gimp_document_list_deserialize (GObject *document_list,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
GTokenType token;
|
||||
|
@ -141,11 +141,8 @@ gimp_document_list_deserialize (GObject *document_list,
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -176,6 +173,8 @@ gimp_document_list_deserialize (GObject *document_list,
|
|||
|
||||
gimp_container_add (GIMP_CONTAINER (document_list),
|
||||
GIMP_OBJECT (imagefile));
|
||||
|
||||
g_object_unref (G_OBJECT (imagefile));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -187,20 +186,9 @@ gimp_document_list_deserialize (GObject *document_list,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
GIMP_LIST (document_list)->list =
|
||||
g_list_reverse (GIMP_LIST (document_list)->list);
|
||||
|
||||
if (token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, token, NULL, NULL, document_symbol,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gimp_config_deserialize_return (scanner, token,
|
||||
nest_level, document_symbol);
|
||||
}
|
||||
|
||||
GimpContainer *
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "gimpmarshal.h"
|
||||
#include "gimpparasitelist.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -58,6 +56,7 @@ static gboolean gimp_parasite_list_serialize (GObject *list,
|
|||
gpointer data);
|
||||
static gboolean gimp_parasite_list_deserialize (GObject *list,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
|
||||
static void parasite_serialize (const gchar *key,
|
||||
|
@ -245,6 +244,7 @@ gimp_parasite_list_serialize (GObject *list,
|
|||
static gboolean
|
||||
gimp_parasite_list_deserialize (GObject *list,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
GTokenType token;
|
||||
|
@ -254,11 +254,8 @@ gimp_parasite_list_deserialize (GObject *list,
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -319,17 +316,9 @@ gimp_parasite_list_deserialize (GObject *list,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, token, NULL, NULL, parasite_symbol,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return gimp_config_deserialize_return (scanner, token,
|
||||
nest_level, parasite_symbol);
|
||||
}
|
||||
|
||||
GimpParasiteList *
|
||||
|
|
|
@ -120,11 +120,8 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -138,8 +135,8 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
{
|
||||
g_scanner_set_scope (scanner, UNIT_INFO);
|
||||
token = gimp_unitrc_unit_info_deserialize (scanner, gimp);
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
|
||||
if (token == G_TOKEN_RIGHT_PAREN)
|
||||
g_scanner_set_scope (scanner, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -152,7 +149,6 @@ gimp_unitrc_load (Gimp *gimp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
|
@ -240,19 +236,13 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
GTokenType token;
|
||||
GimpUnit unit;
|
||||
|
||||
if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
if (! gimp_scanner_parse_string (scanner, &identifier))
|
||||
return G_TOKEN_STRING;
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -262,42 +252,48 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
break;
|
||||
|
||||
case G_TOKEN_SYMBOL:
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
|
||||
{
|
||||
case UNIT_FACTOR:
|
||||
token = G_TOKEN_FLOAT;
|
||||
if (! gimp_scanner_parse_float (scanner, &factor))
|
||||
return G_TOKEN_FLOAT;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_DIGITS:
|
||||
token = G_TOKEN_INT;
|
||||
if (! gimp_scanner_parse_int (scanner, &digits))
|
||||
return G_TOKEN_INT;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_SYMBOL:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &symbol))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_ABBREV:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &abbreviation))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_SINGULAR:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &singular))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case UNIT_PLURAL:
|
||||
token = G_TOKEN_STRING;
|
||||
if (! gimp_scanner_parse_string (scanner, &plural))
|
||||
return G_TOKEN_STRING;
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
break;
|
||||
|
||||
case G_TOKEN_RIGHT_PAREN:
|
||||
|
@ -308,30 +304,23 @@ gimp_unitrc_unit_info_deserialize (GScanner *scanner,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (token == G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
token = G_TOKEN_RIGHT_PAREN;
|
||||
|
||||
if (gimp_scanner_parse_token (scanner, token))
|
||||
if (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
unit = _gimp_unit_new (gimp, identifier, factor, digits,
|
||||
symbol, abbreviation, singular, plural);
|
||||
|
||||
/* make the unit definition persistent */
|
||||
gimp_unit_set_deletion_flag (unit, FALSE);
|
||||
|
||||
g_free (identifier);
|
||||
g_free (symbol);
|
||||
g_free (abbreviation);
|
||||
g_free (singular);
|
||||
g_free (plural);
|
||||
|
||||
return G_TOKEN_LEFT_PAREN;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
g_free (identifier);
|
||||
g_free (symbol);
|
||||
g_free (abbreviation);
|
||||
|
|
|
@ -46,6 +46,7 @@ enum
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_GIMP,
|
||||
PROP_MODE,
|
||||
PROP_AXES,
|
||||
PROP_KEYS
|
||||
|
@ -124,6 +125,13 @@ gimp_device_info_class_init (GimpDeviceInfoClass *klass)
|
|||
object_class->set_property = gimp_device_info_set_property;
|
||||
object_class->get_property = gimp_device_info_get_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_GIMP,
|
||||
g_param_spec_object ("gimp",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_GIMP,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_MODE, "mode",
|
||||
GDK_TYPE_INPUT_MODE,
|
||||
GDK_MODE_DISABLED);
|
||||
|
@ -192,6 +200,51 @@ gimp_device_info_set_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GIMP:
|
||||
{
|
||||
GimpContext *context;
|
||||
Gimp *gimp;
|
||||
|
||||
context = GIMP_CONTEXT (device_info);
|
||||
gimp = g_value_get_object (value);
|
||||
|
||||
/* we override GimpContext's "gimp" property, so we need to
|
||||
* register the context just like GimpContext would do it.
|
||||
*/
|
||||
context->gimp = gimp;
|
||||
gimp->context_list = g_list_prepend (gimp->context_list, context);
|
||||
|
||||
gimp_context_define_properties (context,
|
||||
GIMP_DEVICE_INFO_CONTEXT_MASK,
|
||||
FALSE);
|
||||
gimp_context_copy_properties (gimp_get_user_context (gimp),
|
||||
context,
|
||||
GIMP_DEVICE_INFO_CONTEXT_MASK);
|
||||
|
||||
/* FIXME: this is ugly and needs to be done via "notify" once
|
||||
* the contexts' properties are dynamic.
|
||||
*/
|
||||
g_signal_connect_swapped (G_OBJECT (context), "foreground_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "background_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "tool_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "brush_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "pattern_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "gradient_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_MODE:
|
||||
if (device_info->device)
|
||||
gdk_device_set_mode (device_info->device, g_value_get_enum (value));
|
||||
|
@ -305,6 +358,10 @@ gimp_device_info_get_property (GObject *object,
|
|||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GIMP:
|
||||
g_value_set_object (value, GIMP_CONTEXT (device_info)->gimp);
|
||||
break;
|
||||
|
||||
case PROP_MODE:
|
||||
if (device)
|
||||
g_value_set_enum (value, device->mode);
|
||||
|
@ -399,7 +456,6 @@ gimp_device_info_new (Gimp *gimp,
|
|||
const gchar *name)
|
||||
{
|
||||
GimpDeviceInfo *device_info;
|
||||
GimpContext *context;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
@ -409,38 +465,6 @@ gimp_device_info_new (Gimp *gimp,
|
|||
"gimp", gimp,
|
||||
NULL);
|
||||
|
||||
context = GIMP_CONTEXT (device_info);
|
||||
|
||||
gimp_context_define_properties (context,
|
||||
GIMP_DEVICE_INFO_CONTEXT_MASK,
|
||||
FALSE);
|
||||
gimp_context_copy_properties (gimp_get_user_context (gimp),
|
||||
context,
|
||||
GIMP_DEVICE_INFO_CONTEXT_MASK);
|
||||
|
||||
/*
|
||||
* FIXME: this is ugly and needs to be done via "notify" once
|
||||
* the contexts' properties are dynamic.
|
||||
*/
|
||||
g_signal_connect_swapped (G_OBJECT (context), "foreground_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "background_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "tool_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "brush_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "pattern_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
g_signal_connect_swapped (G_OBJECT (context), "gradient_changed",
|
||||
G_CALLBACK (gimp_device_info_changed),
|
||||
device_info);
|
||||
|
||||
return device_info;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,8 @@ void
|
|||
gimp_devices_restore_test (Gimp *gimp)
|
||||
{
|
||||
GimpDeviceManager *manager;
|
||||
GimpDeviceInfo *device_info;
|
||||
GimpContext *user_context;
|
||||
gchar *filename;
|
||||
GError *error = NULL;
|
||||
|
||||
|
@ -193,7 +195,29 @@ gimp_devices_restore_test (Gimp *gimp)
|
|||
|
||||
filename = gimp_personal_rc_file ("test-devicerc");
|
||||
|
||||
if (! gimp_config_deserialize (G_OBJECT (manager->device_info_list),
|
||||
filename,
|
||||
gimp,
|
||||
&error))
|
||||
{
|
||||
g_message ("Could not read test-devicerc: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_free (filename);
|
||||
return;
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
|
||||
device_info = gimp_device_info_get_by_device (manager->current_device);
|
||||
|
||||
g_return_if_fail (GIMP_IS_DEVICE_INFO (device_info));
|
||||
|
||||
user_context = gimp_get_user_context (gimp);
|
||||
|
||||
gimp_context_copy_properties (GIMP_CONTEXT (device_info), user_context,
|
||||
GIMP_DEVICE_INFO_CONTEXT_MASK);
|
||||
gimp_context_set_parent (GIMP_CONTEXT (device_info), user_context);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -213,7 +237,7 @@ gimp_devices_save_test (Gimp *gimp)
|
|||
|
||||
if (! gimp_config_serialize (G_OBJECT (manager->device_info_list),
|
||||
filename,
|
||||
"# test-devicerc",
|
||||
"# test-devicerc\n",
|
||||
"# end test-devicerc",
|
||||
NULL,
|
||||
&error))
|
||||
|
|
|
@ -90,6 +90,7 @@ static inline gboolean scanner_string_utf8_valid (GScanner *scanner,
|
|||
* gimp_config_deserialize_properties:
|
||||
* @object: a #GObject.
|
||||
* @scanner: a #GScanner.
|
||||
* @embedded_scope: %TRUE if a trailing ')' should not trigger a parse error.
|
||||
* @store_unknown_tokens: %TRUE if you want to store unknown tokens.
|
||||
*
|
||||
* This function uses the @scanner to configure the properties of @object.
|
||||
|
@ -105,6 +106,7 @@ static inline gboolean scanner_string_utf8_valid (GScanner *scanner,
|
|||
gboolean
|
||||
gimp_config_deserialize_properties (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gboolean store_unknown_tokens)
|
||||
{
|
||||
GObjectClass *klass;
|
||||
|
@ -124,7 +126,7 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
if (!property_specs)
|
||||
return TRUE;
|
||||
|
||||
scope_id = g_quark_from_static_string ("gimp_config_deserialize_properties");
|
||||
scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (object));
|
||||
old_scope_id = g_scanner_set_scope (scanner, scope_id);
|
||||
|
||||
for (i = 0; i < n_property_specs; i++)
|
||||
|
@ -141,8 +143,8 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
g_free (property_specs);
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
next = g_scanner_peek_next_token (scanner);
|
||||
|
||||
|
@ -160,7 +162,7 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
case G_TOKEN_LEFT_PAREN:
|
||||
token = G_TOKEN_SYMBOL;
|
||||
break;
|
||||
|
||||
|
||||
case G_TOKEN_IDENTIFIER:
|
||||
token = gimp_config_deserialize_unknown (object, scanner);
|
||||
break;
|
||||
|
@ -177,17 +179,11 @@ gimp_config_deserialize_properties (GObject *object,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
if (next != G_TOKEN_EOF && next != token && token != G_TOKEN_NONE)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
g_scanner_set_scope (scanner, old_scope_id);
|
||||
|
||||
return (next == G_TOKEN_EOF || next == token);
|
||||
return gimp_config_deserialize_return (scanner, token,
|
||||
nest_level, NULL);
|
||||
}
|
||||
|
||||
static GTokenType
|
||||
|
@ -219,7 +215,9 @@ static GTokenType
|
|||
gimp_config_deserialize_property (GObject *object,
|
||||
GScanner *scanner)
|
||||
{
|
||||
GTypeClass *owner_class;
|
||||
GimpConfigInterface *gimp_config_iface;
|
||||
GimpConfigInterface *parent_iface;
|
||||
GParamSpec *prop_spec;
|
||||
GTokenType token = G_TOKEN_RIGHT_PAREN;
|
||||
GValue value = { 0, };
|
||||
|
@ -228,11 +226,33 @@ gimp_config_deserialize_property (GObject *object,
|
|||
|
||||
g_value_init (&value, prop_spec->value_type);
|
||||
|
||||
gimp_config_iface =
|
||||
g_type_interface_peek (g_type_class_peek (prop_spec->owner_type),
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
owner_class = g_type_class_peek (prop_spec->owner_type);
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface = g_type_interface_peek (owner_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
|
||||
/* We must call deserialize_property() *only* if the *exact* class
|
||||
* which implements it is param_spec->owner_type's class.
|
||||
*
|
||||
* Therefore, we ask param_spec->owner_type's immediate parent class
|
||||
* for it's GimpConfigInterface and check if we get a different pointer.
|
||||
*
|
||||
* (if the pointers are the same, param_spec->owner_type's
|
||||
* GimpConfigInterface is inherited from one of it's parent classes
|
||||
* and thus not able to handle param_spec->owner_type's properties).
|
||||
*/
|
||||
if (gimp_config_iface)
|
||||
{
|
||||
GTypeClass *owner_parent_class;
|
||||
|
||||
owner_parent_class = g_type_class_peek_parent (owner_class),
|
||||
|
||||
parent_iface = g_type_interface_peek (owner_parent_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
}
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface != parent_iface && /* see comment above */
|
||||
gimp_config_iface->deserialize_property &&
|
||||
gimp_config_iface->deserialize_property (object,
|
||||
prop_spec->param_id,
|
||||
|
@ -385,14 +405,14 @@ gimp_config_deserialize_fundamental (GValue *value,
|
|||
break;
|
||||
case G_TYPE_ULONG:
|
||||
g_value_set_uint (value, scanner->value.v_int);
|
||||
break;
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
g_value_set_float (value, scanner->value.v_float);
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
g_value_set_double (value, scanner->value.v_float);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
|
@ -519,11 +539,8 @@ gimp_config_deserialize_color (GValue *value,
|
|||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
do
|
||||
while (g_scanner_peek_next_token (scanner) == token)
|
||||
{
|
||||
if (g_scanner_peek_next_token (scanner) != token)
|
||||
break;
|
||||
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
|
||||
switch (token)
|
||||
|
@ -595,7 +612,6 @@ gimp_config_deserialize_color (GValue *value,
|
|||
break;
|
||||
}
|
||||
}
|
||||
while (token != G_TOKEN_EOF);
|
||||
|
||||
finish:
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
gboolean gimp_config_deserialize_properties (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gboolean store_unknown_tokens);
|
||||
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ static gboolean gimp_config_iface_serialize (GObject *object,
|
|||
gpointer data);
|
||||
static gboolean gimp_config_iface_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
static GObject *gimp_config_iface_duplicate (GObject *object);
|
||||
static gboolean gimp_config_iface_equal (GObject *a,
|
||||
|
@ -111,9 +112,10 @@ gimp_config_iface_serialize (GObject *object,
|
|||
static gboolean
|
||||
gimp_config_iface_deserialize (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data)
|
||||
{
|
||||
return gimp_config_deserialize_properties (object, scanner, FALSE);
|
||||
return gimp_config_deserialize_properties (object, scanner, nest_level, FALSE);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
|
@ -227,7 +229,8 @@ gimp_config_serialize (GObject *object,
|
|||
|
||||
if (success && footer)
|
||||
success = (write (fd, "\n", 1) != -1 &&
|
||||
write (fd, footer, strlen (footer)) != -1);
|
||||
write (fd, footer, strlen (footer)) != -1 &&
|
||||
write (fd, "\n", 1) != -1);
|
||||
|
||||
if (! success)
|
||||
{
|
||||
|
@ -311,10 +314,12 @@ gimp_config_deserialize (GObject *object,
|
|||
scanner->msg_handler = gimp_config_scanner_message;
|
||||
scanner->input_name = filename;
|
||||
|
||||
scanner->config->cset_identifier_first = ( G_CSET_a_2_z );
|
||||
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" );
|
||||
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
|
||||
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
|
||||
|
||||
success = gimp_config_iface->deserialize (object, scanner, data);
|
||||
scanner->config->scan_identifier_1char = TRUE;
|
||||
|
||||
success = gimp_config_iface->deserialize (object, scanner, 0, data);
|
||||
|
||||
g_scanner_destroy (scanner);
|
||||
close (fd);
|
||||
|
@ -325,6 +330,45 @@ gimp_config_deserialize (GObject *object,
|
|||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_config_deserialize_return (GScanner *scanner,
|
||||
GTokenType expected_token,
|
||||
gint nest_level,
|
||||
const gchar *symbol_name)
|
||||
{
|
||||
GTokenType next_token;
|
||||
|
||||
g_return_val_if_fail (scanner != NULL, FALSE);
|
||||
|
||||
next_token = g_scanner_peek_next_token (scanner);
|
||||
|
||||
if (expected_token != G_TOKEN_LEFT_PAREN)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, expected_token, NULL, NULL,
|
||||
symbol_name,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nest_level > 0 && next_token == G_TOKEN_RIGHT_PAREN)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (next_token != G_TOKEN_EOF)
|
||||
{
|
||||
g_scanner_get_next_token (scanner);
|
||||
g_scanner_unexp_token (scanner, expected_token, NULL, NULL,
|
||||
symbol_name,
|
||||
_("fatal parse error"), TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GQuark
|
||||
gimp_config_error_quark (void)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@ struct _GimpConfigInterface
|
|||
gpointer data);
|
||||
gboolean (* deserialize) (GObject *object,
|
||||
GScanner *scanner,
|
||||
gint nest_level,
|
||||
gpointer data);
|
||||
gboolean (* serialize_property) (GObject *object,
|
||||
guint property_id,
|
||||
|
@ -81,6 +82,11 @@ gboolean gimp_config_deserialize (GObject *object,
|
|||
gpointer data,
|
||||
GError **error);
|
||||
|
||||
gboolean gimp_config_deserialize_return (GScanner *scanner,
|
||||
GTokenType expected_token,
|
||||
gint nest_level,
|
||||
const gchar *symbol_name);
|
||||
|
||||
GObject * gimp_config_duplicate (GObject *object);
|
||||
gboolean gimp_config_equal (GObject *a,
|
||||
GObject *b);
|
||||
|
|
|
@ -389,18 +389,42 @@ gimp_config_serialize_property (GObject *object,
|
|||
GString *str,
|
||||
gboolean escaped)
|
||||
{
|
||||
GTypeClass *owner_class;
|
||||
GimpConfigInterface *gimp_config_iface;
|
||||
GimpConfigInterface *parent_iface;
|
||||
GValue value = { 0, };
|
||||
gboolean retval;
|
||||
|
||||
g_value_init (&value, param_spec->value_type);
|
||||
g_object_get_property (object, param_spec->name, &value);
|
||||
|
||||
gimp_config_iface =
|
||||
g_type_interface_peek (g_type_class_peek (param_spec->owner_type),
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
owner_class = g_type_class_peek (param_spec->owner_type);
|
||||
|
||||
gimp_config_iface = g_type_interface_peek (owner_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
|
||||
/* We must call deserialize_property() *only* if the *exact* class
|
||||
* which implements it is param_spec->owner_type's class.
|
||||
*
|
||||
* Therefore, we ask param_spec->owner_type's immediate parent class
|
||||
* for it's GimpConfigInterface and check if we get a different pointer.
|
||||
*
|
||||
* (if the pointers are the same, param_spec->owner_type's
|
||||
* GimpConfigInterface is inherited from one of it's parent classes
|
||||
* and thus not able to handle param_spec->owner_type's properties).
|
||||
*/
|
||||
if (gimp_config_iface)
|
||||
{
|
||||
GTypeClass *owner_parent_class;
|
||||
|
||||
owner_parent_class = g_type_class_peek_parent (owner_class),
|
||||
|
||||
parent_iface = g_type_interface_peek (owner_parent_class,
|
||||
GIMP_TYPE_CONFIG_INTERFACE);
|
||||
}
|
||||
|
||||
if (gimp_config_iface &&
|
||||
gimp_config_iface != parent_iface && /* see comment above */
|
||||
gimp_config_iface->serialize_property &&
|
||||
gimp_config_iface->serialize_property (object,
|
||||
param_spec->param_id,
|
||||
|
|
Loading…
Reference in New Issue