Issue #10566: support GimpConfig and enum arguments and a few more fixes.
Now that we save GEGL operation arguments ourselves (instead of relying on GEGL-generated XML), we can serialize and deserialize GimpConfig arguments which are used in various operations implemented within GIMP core code. Additionally: - Also support saving and loading all enum types. - PROP_EFFECT_ARGUMENT renamed to PROP_FILTER_ARGUMENT for consistent naming. - A bit more accurate handling on save and load errors with dedicated messages to various issues. - Use PROP_FLOAT_OPACITY instead of the obsolete 8-bit PROP_OPACITY (actually 32-bit but stored as 0-255 int). - Fix a leaking string.
This commit is contained in:
parent
8b2975e0e8
commit
956f16e173
3 changed files with 125 additions and 34 deletions
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "core/core-types.h"
|
||||
|
||||
|
|
@ -2379,9 +2380,12 @@ xcf_load_effect_props (XcfInfo *info,
|
|||
|
||||
while (TRUE)
|
||||
{
|
||||
goffset next_prop;
|
||||
|
||||
if (! xcf_load_prop (info, &prop_type, &prop_size))
|
||||
return FALSE;
|
||||
|
||||
next_prop = info->cp + prop_size;
|
||||
switch (prop_type)
|
||||
{
|
||||
case PROP_END:
|
||||
|
|
@ -2396,12 +2400,13 @@ xcf_load_effect_props (XcfInfo *info,
|
|||
}
|
||||
break;
|
||||
|
||||
case PROP_OPACITY:
|
||||
case PROP_FLOAT_OPACITY:
|
||||
{
|
||||
guint32 opacity;
|
||||
gfloat opacity;
|
||||
|
||||
xcf_read_int32 (info, &opacity, 1);
|
||||
filter->opacity = (gdouble) opacity / 255.0;
|
||||
xcf_read_float (info, &opacity, 1);
|
||||
|
||||
filter->opacity = (gdouble) opacity;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2470,30 +2475,43 @@ xcf_load_effect_props (XcfInfo *info,
|
|||
}
|
||||
break;
|
||||
|
||||
case PROP_EFFECT_ARGUMENT:
|
||||
case PROP_FILTER_ARGUMENT:
|
||||
{
|
||||
gchar *filter_prop_name;
|
||||
guint32 filter_type = FILTER_PROP_UNKNOWN;
|
||||
GValue filter_prop_value = G_VALUE_INIT;
|
||||
gboolean valid_property = FALSE;
|
||||
GParamSpec *pspec;
|
||||
gchar *filter_prop_name;
|
||||
guint32 filter_type = FILTER_PROP_UNKNOWN;
|
||||
GValue filter_prop_value = G_VALUE_INIT;
|
||||
gboolean valid_prop_value = TRUE;
|
||||
|
||||
xcf_read_string (info, &filter_prop_name, 1);
|
||||
xcf_read_int32 (info, (guint32 *) &filter_type, 1);
|
||||
|
||||
/* Check if valid property first */
|
||||
if (gegl_operation_find_property (filter->operation_name,
|
||||
filter_prop_name))
|
||||
valid_property = TRUE;
|
||||
if (! (pspec = gegl_operation_find_property (filter->operation_name,
|
||||
filter_prop_name)))
|
||||
{
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: filter \"%s\" does not "
|
||||
"have the %s property. It was not set.",
|
||||
filter->operation_name, filter_prop_name);
|
||||
g_free (filter_prop_name);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (filter_type)
|
||||
{
|
||||
case FILTER_PROP_INT:
|
||||
case FILTER_PROP_ENUM:
|
||||
{
|
||||
guint32 value;
|
||||
|
||||
xcf_read_int32 (info, (guint32 *) &value, 1);
|
||||
g_value_init (&filter_prop_value, G_TYPE_INT);
|
||||
g_value_set_int (&filter_prop_value, value);
|
||||
g_value_init (&filter_prop_value, pspec->value_type);
|
||||
if (filter_type == FILTER_PROP_INT)
|
||||
g_value_set_int (&filter_prop_value, value);
|
||||
else
|
||||
g_value_set_enum (&filter_prop_value, value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2529,23 +2547,59 @@ xcf_load_effect_props (XcfInfo *info,
|
|||
}
|
||||
break;
|
||||
|
||||
case FILTER_PROP_CONFIG:
|
||||
{
|
||||
GObject *config;
|
||||
gchar *serialized;
|
||||
GError *error = NULL;
|
||||
|
||||
if (! g_type_is_a (pspec->value_type, GIMP_TYPE_CONFIG))
|
||||
{
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: property '%s' of filter '%s' is a %s, which does not implement GimpConfig interface.\n",
|
||||
filter_prop_name, filter->operation_name, g_type_name (pspec->value_type));
|
||||
valid_prop_value = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
xcf_read_string (info, &serialized, 1);
|
||||
g_value_init (&filter_prop_value, pspec->value_type);
|
||||
config = g_object_new (pspec->value_type, NULL);
|
||||
if (gimp_config_deserialize_string (GIMP_CONFIG (config), serialized, -1, NULL, &error))
|
||||
{
|
||||
g_value_set_object (&filter_prop_value, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: failure to deserialize config object for property '%s' of filter '%s': %s\n"
|
||||
"Serialized config was: %s",
|
||||
filter_prop_name, filter->operation_name,
|
||||
error->message, serialized);
|
||||
valid_prop_value = FALSE;
|
||||
}
|
||||
|
||||
g_object_unref (config);
|
||||
g_free (serialized);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: property '%s' of filter '%s' holds unsupported type %s.\n",
|
||||
filter_prop_name, filter->operation_name, g_type_name (pspec->value_type));
|
||||
valid_prop_value = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid_property)
|
||||
{
|
||||
gegl_node_set_property (filter->operation, filter_prop_name,
|
||||
&filter_prop_value);
|
||||
}
|
||||
if (valid_prop_value)
|
||||
gegl_node_set_property (filter->operation, filter_prop_name,
|
||||
&filter_prop_value);
|
||||
else
|
||||
{
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: filter \"%s\" does not "
|
||||
"have the %s property. It was not set.",
|
||||
filter->operation_name, filter_prop_name);
|
||||
}
|
||||
xcf_seek_pos (info, next_prop, NULL);
|
||||
|
||||
g_value_unset (&filter_prop_value);
|
||||
g_free (filter_prop_name);
|
||||
|
|
@ -4453,4 +4507,4 @@ xcf_fix_item_path (GimpLayer *layer,
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ typedef enum
|
|||
PROP_LOCK_VISIBILITY = 42,
|
||||
PROP_SELECTED_PATH = 43,
|
||||
PROP_FILTER_REGION = 44,
|
||||
PROP_EFFECT_ARGUMENT = 45
|
||||
PROP_FILTER_ARGUMENT = 45
|
||||
} PropType;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -105,7 +105,9 @@ typedef enum
|
|||
FILTER_PROP_INT = 1,
|
||||
FILTER_PROP_BOOL = 2,
|
||||
FILTER_PROP_FLOAT = 3,
|
||||
FILTER_PROP_STRING = 4
|
||||
FILTER_PROP_STRING = 4,
|
||||
FILTER_PROP_ENUM = 5,
|
||||
FILTER_PROP_CONFIG = 6,
|
||||
} FilterPropType;
|
||||
|
||||
typedef struct _XcfInfo XcfInfo;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "config/gimpgeglconfig.h"
|
||||
|
||||
|
|
@ -837,11 +838,11 @@ xcf_save_effect_props (XcfInfo *info,
|
|||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
GeglNode *node;
|
||||
const gchar *operation;
|
||||
gchar *operation;
|
||||
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_VISIBLE, error,
|
||||
gimp_filter_get_active (filter)), ;);
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_OPACITY, error,
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_FLOAT_OPACITY, error,
|
||||
gimp_drawable_filter_get_opacity (GIMP_DRAWABLE_FILTER (filter))), ;);
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_MODE, error,
|
||||
gimp_drawable_filter_get_paint_mode (GIMP_DRAWABLE_FILTER (filter))), ;);
|
||||
|
|
@ -893,15 +894,33 @@ xcf_save_effect_props (XcfInfo *info,
|
|||
break;
|
||||
|
||||
default:
|
||||
if (g_type_is_a (G_VALUE_TYPE (&value), GIMP_TYPE_CONFIG))
|
||||
{
|
||||
filter_type = FILTER_PROP_CONFIG;
|
||||
}
|
||||
else if (g_type_is_a (G_VALUE_TYPE (&value), G_TYPE_ENUM))
|
||||
{
|
||||
filter_type = FILTER_PROP_ENUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_message (info->gimp, G_OBJECT (info->progress),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
"XCF Warning: argument \"%s\" of filter %s has "
|
||||
"unsupported type %s. It was discarded.",
|
||||
pspec->name, operation,
|
||||
g_type_name (G_VALUE_TYPE (&value)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (filter_type != FILTER_PROP_UNKNOWN)
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_EFFECT_ARGUMENT, error,
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_FILTER_ARGUMENT, error,
|
||||
pspec->name, filter_type, value), ;);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
g_free (operation);
|
||||
g_free (pspecs);
|
||||
|
||||
xcf_check_error (xcf_save_prop (info, image, PROP_END, error), ;);
|
||||
|
|
@ -1726,7 +1745,7 @@ xcf_save_prop (XcfInfo *info,
|
|||
}
|
||||
break;
|
||||
|
||||
case PROP_EFFECT_ARGUMENT:
|
||||
case PROP_FILTER_ARGUMENT:
|
||||
{
|
||||
const gchar *string = va_arg (args, const gchar *);
|
||||
guint32 filter_type = va_arg (args, guint32);
|
||||
|
|
@ -1748,8 +1767,14 @@ xcf_save_prop (XcfInfo *info,
|
|||
switch (filter_type)
|
||||
{
|
||||
case FILTER_PROP_INT:
|
||||
case FILTER_PROP_ENUM:
|
||||
{
|
||||
guint32 value = g_value_get_int (&filter_value);
|
||||
guint32 value;
|
||||
|
||||
if (filter_type == FILTER_PROP_INT)
|
||||
value = g_value_get_int (&filter_value);
|
||||
else
|
||||
value = g_value_get_enum (&filter_value);
|
||||
|
||||
xcf_write_int32_check_error (info, &value, 1, va_end (args));
|
||||
}
|
||||
|
|
@ -1779,6 +1804,16 @@ xcf_save_prop (XcfInfo *info,
|
|||
}
|
||||
break;
|
||||
|
||||
case FILTER_PROP_CONFIG:
|
||||
{
|
||||
GimpConfig *config = g_value_get_object (&filter_value);
|
||||
gchar *value = gimp_config_serialize_to_string (config, NULL);
|
||||
|
||||
xcf_write_string_check_error (info, (gchar **) &value, 1, va_end (args));
|
||||
g_free (value);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue