diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index 22e333684c..58fea1d2c6 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -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; } } -} \ No newline at end of file +} diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h index 0be51533c4..8efd95de4b 100644 --- a/app/xcf/xcf-private.h +++ b/app/xcf/xcf-private.h @@ -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; diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c index 02b655ce77..c9195c68fa 100644 --- a/app/xcf/xcf-save.c +++ b/app/xcf/xcf-save.c @@ -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; }