Commit 78841f1f authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

app/config/Makefile.am app/config/gimpconfig-params.[ch] new files

2001-12-08  Sven Neumann  <sven@gimp.org>

	* app/config/Makefile.am
	* app/config/gimpconfig-params.[ch]
	* app/config/gimpconfig-types.[ch]: new files implementing special
	GParamSpecs and GValueTypes needed for GimpConfig.

	* app/config/gimpbaseconfig.c: register tile-cache-size property
	with GimpParamSpecMemsize.

	* app/config/gimpconfig-deserialize.[ch]
	* app/config/gimpconfig-serialize.[ch]: enable serialization and
	deserialization of non-fundamental types.
parent 01a36090
2001-12-08 Sven Neumann <sven@gimp.org>
* app/config/Makefile.am
* app/config/gimpconfig-params.[ch]
* app/config/gimpconfig-types.[ch]: new files implementing special
GParamSpecs and GValueTypes needed for GimpConfig.
* app/config/gimpbaseconfig.c: register tile-cache-size property
with GimpParamSpecMemsize.
* app/config/gimpconfig-deserialize.[ch]
* app/config/gimpconfig-serialize.[ch]: enable serialization and
deserialization of non-fundamental types.
2001-12-07 Michael Natterer <mitch@gimp.org>
* app/Makefile.am
......
......@@ -7,8 +7,12 @@ libappconfig_a_SOURCES = @STRIP_BEGIN@ \
gimpconfig.h \
gimpconfig-deserialize.c \
gimpconfig-deserialize.h \
gimpconfig-params.c \
gimpconfig-params.h \
gimpconfig-serialize.c \
gimpconfig-serialize.h \
gimpconfig-types.c \
gimpconfig-types.h \
gimpbaseconfig.c \
gimpbaseconfig.h \
@STRIP_END@
......
......@@ -23,6 +23,9 @@
#include "base/base-enums.h"
#include "gimpconfig.h"
#include "gimpconfig-params.h"
#include "gimpconfig-types.h"
#include "gimpbaseconfig.h"
......@@ -123,16 +126,18 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
PROP_NUM_PROCESSORS,
g_param_spec_uint ("num-processors",
NULL, NULL,
1, 30, 1,
1, 30,
1,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_TILE_CACHE_SIZE,
g_param_spec_uint ("tile-cache-size",
NULL, NULL,
0, G_MAXINT, 1 << 25,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
gimp_param_spec_memsize ("tile-cache-size",
NULL, NULL,
0, G_MAXUINT,
1 << 25,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_INTERPOLATION_TYPE,
g_param_spec_enum ("interpolation-type",
......
......@@ -30,6 +30,7 @@
#include <glib-object.h>
#include "gimpconfig-deserialize.h"
#include "gimpconfig-types.h"
static void gimp_config_deserialize_property (GObject *object,
......@@ -120,40 +121,65 @@ gimp_config_deserialize_property (GObject *object,
GTokenType *token)
{
GParamSpec *prop_spec;
GType fundamental_type;
GValue value = { 0, };
gchar *orig_cset_first = NULL;
gchar *orig_cset_nth = NULL;
GValue value = { 0, };
prop_spec = G_PARAM_SPEC (scanner->value.v_symbol);
g_value_init (&value, prop_spec->value_type);
fundamental_type = G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (&value));
switch (fundamental_type)
if (G_TYPE_FUNDAMENTAL (prop_spec->value_type) == G_TYPE_ENUM)
{
case G_TYPE_STRING:
*token = G_TOKEN_STRING;
break;
case G_TYPE_BOOLEAN:
case G_TYPE_ENUM:
*token = G_TOKEN_IDENTIFIER;
break;
case G_TYPE_INT:
case G_TYPE_UINT:
case G_TYPE_LONG:
case G_TYPE_ULONG:
*token = G_TOKEN_INT;
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
*token = G_TOKEN_FLOAT;
break;
default:
g_assert_not_reached ();
break;
}
else if (G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type))
{
switch (G_TYPE_FUNDAMENTAL (prop_spec->value_type))
{
case G_TYPE_STRING:
*token = G_TOKEN_STRING;
break;
case G_TYPE_BOOLEAN:
*token = G_TOKEN_IDENTIFIER;
break;
case G_TYPE_INT:
case G_TYPE_UINT:
case G_TYPE_LONG:
case G_TYPE_ULONG:
*token = G_TOKEN_INT;
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
*token = G_TOKEN_FLOAT;
break;
default:
g_assert_not_reached ();
}
}
else /* not an enum and not a fundamental type */
{
if (g_value_type_transformable (G_TYPE_STRING, prop_spec->value_type))
{
*token = G_TOKEN_IDENTIFIER;
}
else
{
g_warning ("%s: %s can not be transformed from a string",
G_STRLOC, g_type_name (prop_spec->value_type));
g_assert_not_reached ();
}
if (prop_spec->value_type == GIMP_TYPE_MEMSIZE)
{
orig_cset_first = scanner->config->cset_identifier_first;
orig_cset_nth = scanner->config->cset_identifier_nth;
scanner->config->cset_identifier_first = G_CSET_DIGITS;
scanner->config->cset_identifier_nth = G_CSET_DIGITS "gGmMkKbB";
}
}
if (g_scanner_peek_next_token (scanner) != *token)
......@@ -161,72 +187,89 @@ gimp_config_deserialize_property (GObject *object,
g_scanner_get_next_token (scanner);
switch (fundamental_type)
g_value_init (&value, prop_spec->value_type);
if (G_TYPE_FUNDAMENTAL (prop_spec->value_type) == G_TYPE_ENUM)
{
case G_TYPE_STRING:
g_value_set_string (&value, scanner->value.v_string);
break;
case G_TYPE_BOOLEAN:
if (! g_ascii_strcasecmp (scanner->value.v_identifier, "yes") ||
! g_ascii_strcasecmp (scanner->value.v_identifier, "true"))
g_value_set_boolean (&value, TRUE);
else if (! g_ascii_strcasecmp (scanner->value.v_identifier, "no") ||
! g_ascii_strcasecmp (scanner->value.v_identifier, "false"))
g_value_set_boolean (&value, FALSE);
GEnumClass *enum_class;
GEnumValue *enum_value;
enum_class = g_type_class_peek (G_VALUE_TYPE (&value));
enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class),
scanner->value.v_identifier);
if (!enum_value)
enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class),
scanner->value.v_identifier);
if (enum_value)
g_value_set_enum (&value, enum_value->value);
else
g_scanner_warn
(scanner,
"expected 'yes' or 'no' for boolean property %s, got '%s'",
prop_spec->name, scanner->value.v_identifier);
break;
case G_TYPE_ENUM:
{
GEnumClass *enum_class;
GEnumValue *enum_value;
enum_class = g_type_class_peek (G_VALUE_TYPE (&value));
enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class),
scanner->value.v_identifier);
if (!enum_value)
enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class),
scanner->value.v_identifier);
if (enum_value)
g_value_set_enum (&value, enum_value->value);
else
g_scanner_warn (scanner,
"invalid value '%s' for enum property %s",
scanner->value.v_identifier, prop_spec->name);
}
break;
case G_TYPE_INT:
g_value_set_int (&value, scanner->value.v_int);
break;
case G_TYPE_UINT:
g_value_set_uint (&value, scanner->value.v_int);
break;
case G_TYPE_LONG:
g_value_set_int (&value, scanner->value.v_int);
break;
case G_TYPE_ULONG:
g_value_set_uint (&value, scanner->value.v_int);
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 ();
g_scanner_warn (scanner,
"invalid value '%s' for enum property %s",
scanner->value.v_identifier, prop_spec->name);
}
else if (G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type))
{
switch (G_TYPE_FUNDAMENTAL (prop_spec->value_type))
{
case G_TYPE_STRING:
g_value_set_string (&value, scanner->value.v_string);
break;
case G_TYPE_BOOLEAN:
if (! g_ascii_strcasecmp (scanner->value.v_identifier, "yes") ||
! g_ascii_strcasecmp (scanner->value.v_identifier, "true"))
g_value_set_boolean (&value, TRUE);
else if (! g_ascii_strcasecmp (scanner->value.v_identifier, "no") ||
! g_ascii_strcasecmp (scanner->value.v_identifier, "false"))
g_value_set_boolean (&value, FALSE);
else
g_scanner_warn
(scanner,
"expected 'yes' or 'no' for boolean property %s, got '%s'",
prop_spec->name, scanner->value.v_identifier);
break;
case G_TYPE_INT:
g_value_set_int (&value, scanner->value.v_int);
break;
case G_TYPE_UINT:
g_value_set_uint (&value, scanner->value.v_int);
break;
case G_TYPE_LONG:
g_value_set_int (&value, scanner->value.v_int);
break;
case G_TYPE_ULONG:
g_value_set_uint (&value, scanner->value.v_int);
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 ();
}
}
else /* not an enum and not a fundamental type */
{
GValue src = { 0, };
g_value_init (&src, G_TYPE_STRING);
g_value_set_string (&src, scanner->value.v_identifier);
g_value_transform (&src, &value);
}
g_object_set_property (object, prop_spec->name, &value);
g_value_unset (&value);
if (orig_cset_first)
scanner->config->cset_identifier_first = orig_cset_first;
if (orig_cset_nth)
scanner->config->cset_identifier_nth = orig_cset_nth;
*token = G_TOKEN_RIGHT_PAREN;
}
......@@ -19,12 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __DESERIALIZE_H__
#define __DESERIALIZE_H__
#ifndef __GIMP_CONFIG_DESERIALIZE_H__
#define __GIMP_CONFIG_DESERIALIZE_H__
gboolean gimp_config_deserialize_properties (GObject *object,
GScanner *scanner);
#endif /* __DESERIALIZE_H__ */
#endif /* __GIMP_CONFIG_DESERIALIZE_H__ */
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* ParamSpecs for config objects
* Copyright (C) 2001 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "gimpconfig-params.h"
#include "gimpconfig-types.h"
static void gimp_param_memsize_class_init (GParamSpecClass *class);
GType
gimp_param_memsize_get_type (void)
{
static GType spec_type = 0;
if (!spec_type)
{
static const GTypeInfo type_info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_memsize_class_init,
NULL, NULL,
sizeof (GParamSpecUInt),
0, NULL, NULL
};
spec_type = g_type_register_static (G_TYPE_PARAM_UINT,
"GimpParamMemsize",
&type_info, 0);
}
return spec_type;
}
static void
gimp_param_memsize_class_init (GParamSpecClass *class)
{
class->value_type = GIMP_TYPE_MEMSIZE;
}
GParamSpec *
gimp_param_spec_memsize (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint minimum,
guint maximum,
guint default_value,
GParamFlags flags)
{
GParamSpecUInt *mspec;
mspec = g_param_spec_internal (GIMP_TYPE_PARAM_MEMSIZE,
name, nick, blurb, flags);
mspec->minimum = minimum;
mspec->maximum = maximum;
mspec->default_value = default_value;
return G_PARAM_SPEC (mspec);
}
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* ParamSpecs for config objects
* Copyright (C) 2001 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CONFIG_PARAMS_H__
#define __GIMP_CONFIG_PARAMS_H__
#define GIMP_TYPE_PARAM_MEMSIZE (gimp_param_memsize_get_type ())
#define GIMP_IS_PARAM_SPEC_MEMSIZE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_SPEC_MEMSIZE))
GType gimp_param_memsize_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_memsize (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint minimum,
guint maximum,
guint default_value,
GParamFlags flags);
#endif /* __GIMP_CONFIG_PARAMS_H__ */
......@@ -85,7 +85,7 @@ gimp_config_serialize_properties (GObject *object,
GEnumClass *enum_class;
GEnumValue *enum_value;
enum_class = g_type_class_peek (G_VALUE_TYPE (&value));
enum_class = g_type_class_peek (prop_spec->value_type);
enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class),
g_value_get_enum (&value));
......@@ -95,14 +95,14 @@ gimp_config_serialize_properties (GObject *object,
g_warning ("Couldn't get nick for enum_value of %s",
G_ENUM_CLASS_TYPE_NAME (enum_class));
}
else if (g_value_type_transformable (G_VALUE_TYPE (&value),
else if (g_value_type_transformable (prop_spec->value_type,
G_TYPE_STRING))
{
GValue tmp_value = { 0, };
g_value_init (&tmp_value, G_TYPE_STRING);
g_value_transform (&value, &tmp_value);
str = g_strescape (g_value_get_string (&tmp_value), NULL);
str = g_value_dup_string (&tmp_value);
g_value_unset (&tmp_value);
}
......
......@@ -19,12 +19,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SERIALIZE_H__
#define __SERIALIZE_H__
#ifndef __GIMP_CONFIG_SERIALIZE_H__
#define __GIMP_CONFIG_SERIALIZE_H__
void gimp_config_serialize_properties (GObject *object,
FILE *file);
#endif /* __SERIALIZE_H__ */
#endif /* __GIMP_CONFIG_SERIALIZE_H__ */
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* ParamSpecs for config objects
* Copyright (C) 2001 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <glib-object.h>
#include "gimpconfig-types.h"
static void memsize_to_string (const GValue *src_value,
GValue *dest_value);
static void string_to_memsize (const GValue *src_value,
GValue *dest_value);
GType
gimp_memsize_get_type (void)
{
static GType memsize_type = 0;
if (!memsize_type)
{
static const GTypeInfo type_info = { 0, };
memsize_type = g_type_register_static (G_TYPE_UINT, "GimpMemsize",
&type_info, 0);
g_value_register_transform_func (memsize_type, G_TYPE_STRING,
memsize_to_string);
g_value_register_transform_func (G_TYPE_STRING, memsize_type,
string_to_memsize);
}
return memsize_type;
}
static void
memsize_to_string (const GValue *src_value,
GValue *dest_value)
{
guint size;
size = src_value->data[0].v_uint;
if (size > (1 << 30) && size % (1 << 30) == 0)
dest_value->data[0].v_pointer = g_strdup_printf ("%uG", size >> 30);
else if (size > (1 << 20) && size % (1 << 20) == 0)
dest_value->data[0].v_pointer = g_strdup_printf ("%uM", size >> 20);
else if (size > (1 << 10) && size % (1 << 10) == 0)
dest_value->data[0].v_pointer = g_strdup_printf ("%uk", size >> 10);
else
dest_value->data[0].v_pointer = g_strdup_printf ("%u", size);
};
static void
string_to_memsize (const GValue *src_value,
GValue *dest_value)
{
gchar *end;
guint size;
if (!src_value->data[0].v_pointer)
goto error;
size = strtoul (src_value->data[0].v_pointer, &end, 0);
if (size == ULONG_MAX)
goto error;
if (end && *end)
{
guint shift;
switch (g_ascii_tolower (*end))
{
case 'b':
shift = 0;
break;
case 'k':
shift = 10;
break;
case 'm':
shift = 20;
break;
case 'g':
shift = 30;
break;
default:
goto error;
}
size <<= shift;
}
g_value_set_uint (dest_value, size);
return;
error:
g_warning ("Can't convert string to memory size.");
};
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* ValueTypes for config objects
* Copyright (C) 2001 Sven Neumann <sven@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_CONFIG_TYPES_H__
#define __GIMP_CONFIG_TYPES_H__
#define GIMP_TYPE_MEMSIZE (gimp_memsize_get_type ())
GType gimp_memsize_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_CONFIG_TYPES_H__ */
......@@ -30,6 +30,7 @@
#include <glib-object.h>
#include "gimpconfig-deserialize.h"
#include "gimpconfig-types.h"
static void gimp_config_deserialize_property (GObject *object,
......@@ -120,40 +121,65 @@ gimp_config_deserialize_property (GObject *object,
GTokenType *token)
{
GParamSpec *prop_spec;
GType fundamental_type;
GValue value = { 0, };
gchar *orig_cset_first = NULL;
gchar *orig_cset_nth = NULL;
GValue value = { 0, };
prop_spec = G_PARAM_SPEC (scanner->value.v_symbol);
g_value_init (&value, prop_spec->value_type);
fundamental_type = G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (&value));
switch (fundamental_type)
if (G_TYPE_FUNDAMENTAL (prop_spec->value_type) == G_TYPE_ENUM)
{
case G_TYPE_STRING:
*token = G_TOKEN_STRING;
break;
case G_TYPE_BOOLEAN:
case G_TYPE_ENUM:
*token = G_TOKEN_IDENTIFIER;
break;
case G_TYPE_INT:
case G_TYPE_UINT:
case G_TYPE_LONG:
case G_TYPE_ULONG:
*token = G_TOKEN_INT;
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
*token = G_TOKEN_FLOAT;
break;
default:
g_assert_not_reached ();
break;
}
else if (G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type))
{
switch (G_TYPE_FUNDAMENTAL (prop_spec->value_type))
{
case G_TYPE_STRING:
*token = G_TOKEN_STRING;
break;
case G_TYPE_BOOLEAN:
*token = G_TOKEN_IDENTIFIER;
break;
case G_TYPE_INT:
case G_TYPE_UINT:
case G_TYPE_LONG:
case G_TYPE_ULONG:
*token = G_TOKEN_INT;
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
*token = G_TOKEN_FLOAT;
break;