[gimp/multi-stroke] app: use GimpConfig to serialize/deserialize the GimpSymmetry into a parasite.



commit 0d44c4048d377ff10fadb34a2657579049cee0cc
Author: Jehan <jehan girinstud io>
Date:   Wed Mar 25 12:19:48 2015 +0100

    app: use GimpConfig to serialize/deserialize the GimpSymmetry into a parasite.

 app/core/gimpimage-symmetry.c  |   42 +++-----
 app/core/gimpimage-symmetry.h  |    4 +-
 app/core/gimpimage.c           |   14 +---
 app/core/gimpsymmetry-mirror.c |   44 ++-------
 app/core/gimpsymmetry-tiling.c |    1 -
 app/core/gimpsymmetry.c        |   86 +++++++++++++----
 app/core/gimpsymmetry.h        |   10 +-
 app/paint/gimppaintoptions.c   |    7 +-
 app/xcf/xcf-load.c             |  164 ++++++++------------------------
 app/xcf/xcf-private.h          |    3 +-
 app/xcf/xcf-save.c             |  207 ++++++++--------------------------------
 11 files changed, 188 insertions(+), 394 deletions(-)
---
diff --git a/app/core/gimpimage-symmetry.c b/app/core/gimpimage-symmetry.c
index 9b4af60..6d292f2 100644
--- a/app/core/gimpimage-symmetry.c
+++ b/app/core/gimpimage-symmetry.c
@@ -32,10 +32,17 @@
 #include "gimpsymmetry-mirror.h"
 #include "gimpsymmetry-tiling.h"
 
-static GimpSymmetry * gimp_image_symmetry_new (GimpImage *image,
-                                               GType      type);
+GList *
+gimp_image_symmetry_list (void)
+{
+  GList *list = NULL;
+
+  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_MIRROR));
+  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_TILING));
+  return list;
+}
 
-static GimpSymmetry *
+GimpSymmetry *
 gimp_image_symmetry_new (GimpImage *image,
                          GType      type)
 {
@@ -52,18 +59,6 @@ gimp_image_symmetry_new (GimpImage *image,
   return sym;
 }
 
-/*** Public Functions ***/
-
-GList *
-gimp_image_symmetry_list (void)
-{
-  GList *list = NULL;
-
-  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_MIRROR));
-  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_TILING));
-  return list;
-}
-
 /**
  * gimp_image_symmetry_add:
  * @image: the #GimpImage
@@ -72,26 +67,20 @@ gimp_image_symmetry_list (void)
  * Add a symmetry of type @type to @image and make it the
  * selected transformation.
  **/
-GimpSymmetry *
-gimp_image_symmetry_add (GimpImage *image,
-                         GType      type)
+void
+gimp_image_symmetry_add (GimpImage    *image,
+                         GimpSymmetry *sym)
 {
   GimpImagePrivate *private;
-  GimpSymmetry     *sym;
 
-  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
-  g_return_val_if_fail (g_type_is_a (type, GIMP_TYPE_SYMMETRY), NULL);
-
-
-  sym = gimp_image_symmetry_new (image, type);
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+  g_return_if_fail (GIMP_IS_SYMMETRY (sym));
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
   private->symmetries = g_list_prepend (private->symmetries,
                                         sym);
   private->selected_symmetry = sym;
-
-  return sym;
 }
 
 /**
@@ -178,6 +167,7 @@ gimp_image_symmetry_select (GimpImage *image,
             }
         }
     }
+
   return FALSE;
 }
 
diff --git a/app/core/gimpimage-symmetry.h b/app/core/gimpimage-symmetry.h
index b9dacc9..109bd53 100644
--- a/app/core/gimpimage-symmetry.h
+++ b/app/core/gimpimage-symmetry.h
@@ -23,8 +23,10 @@
 
 GList        * gimp_image_symmetry_list      (void);
 
-GimpSymmetry * gimp_image_symmetry_add       (GimpImage    *image,
+GimpSymmetry * gimp_image_symmetry_new       (GimpImage    *image,
                                               GType         type);
+void           gimp_image_symmetry_add       (GimpImage    *image,
+                                              GimpSymmetry *sym);
 void           gimp_image_symmetry_remove    (GimpImage    *image,
                                               GimpSymmetry *sym);
 GList        * gimp_image_symmetry_get       (GimpImage    *image);
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index c23410a..2086fcf 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -2303,11 +2303,8 @@ gimp_image_get_xcf_version (GimpImage    *image,
                             gint         *gimp_version,
                             const gchar **version_string)
 {
-  GimpImagePrivate *private;
-  GList            *list;
-  gint              version = 0;  /* default to oldest */
-
-  private = GIMP_IMAGE_GET_PRIVATE (image);
+  GList *list;
+  gint   version = 0;  /* default to oldest */
 
   /* need version 1 for colormaps */
   if (gimp_image_get_colormap (image))
@@ -2350,12 +2347,6 @@ gimp_image_get_xcf_version (GimpImage    *image,
   if (zlib_compression)
     version = MAX (8, version);
 
-  /* need version 9 for symmetry */
-  if (private->symmetries)
-    {
-      version = MAX (9, version);
-    }
-
   switch (version)
     {
     case 0:
@@ -2375,7 +2366,6 @@ gimp_image_get_xcf_version (GimpImage    *image,
     case 6:
     case 7:
     case 8:
-    case 9:
       if (gimp_version)   *gimp_version   = 210;
       if (version_string) *version_string = "GIMP 2.10";
       break;
diff --git a/app/core/gimpsymmetry-mirror.c b/app/core/gimpsymmetry-mirror.c
index a6d662c..afdf571 100644
--- a/app/core/gimpsymmetry-mirror.c
+++ b/app/core/gimpsymmetry-mirror.c
@@ -86,8 +86,6 @@ static void       gimp_mirror_guide_position_cb   (GObject      *object,
                                                    GimpMirror   *mirror);
 static GParamSpec ** gimp_mirror_get_settings     (GimpSymmetry *sym,
                                                    gint         *n_settings);
-static GParamSpec ** gimp_mirror_get_xcf_settings (GimpSymmetry *sym,
-                                                   gint         *n_settings);
 static void  gimp_mirror_set_horizontal_symmetry  (GimpMirror   *mirror,
                                                    gboolean      active);
 static void    gimp_mirror_set_vertical_symmetry  (GimpMirror   *mirror,
@@ -102,18 +100,17 @@ G_DEFINE_TYPE (GimpMirror, gimp_mirror, GIMP_TYPE_SYMMETRY)
 static void
 gimp_mirror_class_init (GimpMirrorClass *klass)
 {
-  GObjectClass         *object_class       = G_OBJECT_CLASS (klass);
+  GObjectClass      *object_class   = G_OBJECT_CLASS (klass);
   GimpSymmetryClass *symmetry_class = GIMP_SYMMETRY_CLASS (klass);
 
-  object_class->finalize               = gimp_mirror_finalize;
-  object_class->set_property           = gimp_mirror_set_property;
-  object_class->get_property           = gimp_mirror_get_property;
+  object_class->finalize            = gimp_mirror_finalize;
+  object_class->set_property        = gimp_mirror_set_property;
+  object_class->get_property        = gimp_mirror_get_property;
 
-  symmetry_class->label            = "Mirror";
-  symmetry_class->update_strokes   = gimp_mirror_update_strokes;
-  symmetry_class->get_operation    = gimp_mirror_get_operation;
-  symmetry_class->get_settings     = gimp_mirror_get_settings;
-  symmetry_class->get_xcf_settings = gimp_mirror_get_xcf_settings;
+  symmetry_class->label             = "Mirror";
+  symmetry_class->update_strokes    = gimp_mirror_update_strokes;
+  symmetry_class->get_operation     = gimp_mirror_get_operation;
+  symmetry_class->get_settings      = gimp_mirror_get_settings;
 
   /* Properties for user settings */
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HORIZONTAL_SYMMETRY,
@@ -508,31 +505,6 @@ gimp_mirror_get_settings (GimpSymmetry *sym,
   return pspecs;
 }
 
-static GParamSpec **
-gimp_mirror_get_xcf_settings (GimpSymmetry *sym,
-                              gint         *n_settings)
-{
-  GParamSpec **pspecs;
-
-  *n_settings = 6;
-  pspecs = g_new (GParamSpec*, 6);
-
-  pspecs[0] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "horizontal-symmetry");
-  pspecs[1] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "vertical-symmetry");
-  pspecs[2] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "point-symmetry");
-  pspecs[3] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "horizontal-position");
-  pspecs[4] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "vertical-position");
-  pspecs[5] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "disable-transformation");
-
-  return pspecs;
-}
-
 static void
 gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
                                      gboolean    active)
diff --git a/app/core/gimpsymmetry-tiling.c b/app/core/gimpsymmetry-tiling.c
index a7cbb28..c1b05a1 100644
--- a/app/core/gimpsymmetry-tiling.c
+++ b/app/core/gimpsymmetry-tiling.c
@@ -100,7 +100,6 @@ gimp_tiling_class_init (GimpTilingClass *klass)
   symmetry_class->update_strokes   = gimp_tiling_update_strokes;
   symmetry_class->get_operation    = gimp_tiling_get_operation;
   symmetry_class->get_settings     = gimp_tiling_get_settings;
-  symmetry_class->get_xcf_settings = gimp_tiling_get_settings;
 
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_X_INTERVAL,
                                    "x-interval", _("Intervals on x-axis (pixels)"),
diff --git a/app/core/gimpsymmetry.c b/app/core/gimpsymmetry.c
index cc3a734..3664aae 100644
--- a/app/core/gimpsymmetry.c
+++ b/app/core/gimpsymmetry.c
@@ -25,10 +25,14 @@
 #include <gegl.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
 #include "core-types.h"
 
 #include "gimpdrawable.h"
 #include "gimpimage.h"
+#include "gimpimage-symmetry.h"
 #include "gimpitem.h"
 #include "gimpsymmetry.h"
 
@@ -72,7 +76,9 @@ static GParamSpec **
           gimp_symmetry_real_get_settings (GimpSymmetry *sym,
                                            gint         *n_properties);
 
-G_DEFINE_TYPE (GimpSymmetry, gimp_symmetry, GIMP_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (GimpSymmetry, gimp_symmetry, GIMP_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
 
 #define parent_class gimp_symmetry_parent_class
 
@@ -116,7 +122,6 @@ gimp_symmetry_class_init (GimpSymmetryClass *klass)
   klass->update_strokes      = gimp_symmetry_real_update_strokes;
   klass->get_operation       = gimp_symmetry_real_get_op;
   klass->get_settings        = gimp_symmetry_real_get_settings;
-  klass->get_xcf_settings    = gimp_symmetry_real_get_settings;
 
   g_object_class_install_property (object_class, PROP_IMAGE,
                                    g_param_spec_object ("image",
@@ -347,24 +352,69 @@ gimp_symmetry_get_settings (GimpSymmetry *sym,
                                                       n_properties);
 }
 
-/**
- * gimp_symmetry_get_xcf_settings:
- * @sym:         the #GimpSymmetry
- * @n_properties: the number of properties in the returned array
+/*
+ * gimp_symmetry_parasite_name:
+ * @type: the #GimpSymmetry's #GType
  *
- * Returns an array of the symmetry properties which are to be serialized
- * when saving to XCF.
- * These properties may be different to `gimp_symmetry_get_settings()`
- * (for instance some properties are not meant to be user-changeable but
- * still saved)
- * The returned array must be freed by the caller.
- **/
-GParamSpec **
-gimp_symmetry_get_xcf_settings (GimpSymmetry *sym,
-                                gint         *n_properties)
+ * Returns: a newly allocated string.
+ */
+gchar *
+gimp_symmetry_parasite_name (GType type)
+{
+  GimpSymmetryClass *klass;
+
+  klass = g_type_class_ref (type);
+
+  return g_strconcat ("gimp-image-symmetry:", klass->label, NULL);
+}
+
+GimpParasite *
+gimp_symmetry_to_parasite (const GimpSymmetry *sym)
 {
+  GimpParasite *parasite;
+  gchar        *str;
+
   g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);
 
-  return GIMP_SYMMETRY_GET_CLASS (sym)->get_xcf_settings (sym,
-                                                          n_properties);
+  str = gimp_config_serialize_to_string (GIMP_CONFIG (sym), NULL);
+  g_return_val_if_fail (str != NULL, NULL);
+
+  parasite = gimp_parasite_new (gimp_symmetry_parasite_name (sym->type),
+                                GIMP_PARASITE_PERSISTENT,
+                                strlen (str) + 1, str);
+  g_free (str);
+
+  return parasite;
+}
+
+GimpSymmetry *
+gimp_symmetry_from_parasite (const GimpParasite *parasite,
+                             GimpImage          *image,
+                             GType               type)
+{
+  GimpSymmetry    *symmetry;
+  const gchar     *str;
+  GError          *error = NULL;
+
+  g_return_val_if_fail (parasite != NULL, NULL);
+  g_return_val_if_fail (strcmp (gimp_parasite_name (parasite),
+                                gimp_symmetry_parasite_name (type)) == 0,
+                        NULL);
+
+  str = gimp_parasite_data (parasite);
+  g_return_val_if_fail (str != NULL, NULL);
+
+  symmetry = gimp_image_symmetry_new (image, type);
+
+  if (! gimp_config_deserialize_string (GIMP_CONFIG (symmetry),
+                                        str,
+                                        gimp_parasite_data_size (parasite),
+                                        NULL,
+                                        &error))
+    {
+      g_warning ("Failed to deserialize symmetry parasite: %s", error->message);
+      g_error_free (error);
+    }
+
+  return symmetry;
 }
diff --git a/app/core/gimpsymmetry.h b/app/core/gimpsymmetry.h
index 44f1d8c..ed966ef 100644
--- a/app/core/gimpsymmetry.h
+++ b/app/core/gimpsymmetry.h
@@ -64,9 +64,6 @@ struct _GimpSymmetryClass
   GParamSpec **
              (* get_settings)               (GimpSymmetry *sym,
                                              gint         *n_properties);
-  GParamSpec **
-             (* get_xcf_settings)           (GimpSymmetry *sym,
-                                             gint         *n_properties);
 };
 
 
@@ -86,7 +83,10 @@ GeglNode   * gimp_symmetry_get_operation    (GimpSymmetry *sym,
                                              gint          paint_height);
 GParamSpec ** gimp_symmetry_get_settings     (GimpSymmetry *sym,
                                               gint         *n_properties);
-GParamSpec ** gimp_symmetry_get_xcf_settings (GimpSymmetry *sym,
-                                              gint         *n_properties);
 
+gchar        * gimp_symmetry_parasite_name  (GType type);
+GimpParasite * gimp_symmetry_to_parasite    (const GimpSymmetry *symmetry);
+GimpSymmetry * gimp_symmetry_from_parasite  (const GimpParasite *parasite,
+                                             GimpImage          *image,
+                                             GType               type);
 #endif  /*  __GIMP_SYMMETRY_H__  */
diff --git a/app/paint/gimppaintoptions.c b/app/paint/gimppaintoptions.c
index f5d184d..afc9fb1 100644
--- a/app/paint/gimppaintoptions.c
+++ b/app/paint/gimppaintoptions.c
@@ -568,8 +568,11 @@ gimp_paint_options_set_property (GObject      *object,
           if (! gimp_image_symmetry_select (context->image,
                                             options->symmetry))
             {
-              gimp_image_symmetry_add (context->image,
-                                       options->symmetry);
+              GimpSymmetry *sym;
+
+              sym = gimp_image_symmetry_new (context->image,
+                                             options->symmetry);
+              gimp_image_symmetry_add (context->image, sym);
             }
         }
       else
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index 057d480..bcd6ea4 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -158,6 +158,7 @@ xcf_load_image (Gimp     *gimp,
   gint                image_type;
   GimpPrecision       precision = GIMP_PRECISION_U8_GAMMA;
   gint                num_successful_elements = 0;
+  GList              *iter;
 
   /* read in the image width, height and type */
   info->cp += xcf_read_int32 (info->input, (guint32 *) &width, 1);
@@ -270,6 +271,44 @@ xcf_load_image (Gimp     *gimp,
                                  gimp_parasite_name (parasite));
     }
 
+  /* check for symmetry parasites */
+  for (iter = gimp_image_symmetry_list (); iter; iter = g_list_next (iter))
+    {
+      GType  type = (GType) iter->data;
+      gchar *parasite_name = gimp_symmetry_parasite_name (type);
+
+      parasite = gimp_image_parasite_find (image,
+                                           parasite_name);
+      g_free (parasite_name);
+      if (parasite)
+        {
+          GimpSymmetry *sym = gimp_symmetry_from_parasite (parasite,
+                                                           image,
+                                                           type);
+
+          if (sym)
+            {
+              GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+              gimp_parasite_list_remove (private->parasites,
+                                         gimp_parasite_name (parasite));
+
+              gimp_image_symmetry_add (image, sym);
+            }
+        }
+    }
+  parasite = gimp_image_parasite_find (image, "gimp-image-symmetry-selected");
+  if (parasite)
+    {
+      const gchar *str;
+
+      str = gimp_parasite_data (parasite);
+      if (! gimp_image_symmetry_select (image, g_type_from_name (str)))
+        g_warning ("%s: no symmetry of type %s",
+                   G_STRFUNC, str);
+    }
+
+
   /* migrate the old "exif-data" parasite */
   parasite = gimp_image_parasite_find (GIMP_IMAGE (image),
                                        "exif-data");
@@ -726,131 +765,6 @@ xcf_load_image_props (XcfInfo   *info,
           }
           break;
 
-        case PROP_SYMMETRY:
-            {
-              GimpSymmetry  *sym;
-              GimpSymmetry  *active_sym = NULL;
-              gint32         active;
-              gint32         n_syms;
-              gchar         *name;
-              GType          type;
-              GParamSpec   **settings;
-              GParamSpec    *spec;
-              gint           n_settings;
-              gint           i, j;
-
-              info->cp += xcf_read_int32 (info->input,
-                                          (guint32 *) &active, 1);
-              info->cp += xcf_read_int32 (info->input,
-                                          (guint32 *) &n_syms, 1);
-              for (i = 1; i <= n_syms; i++)
-                {
-                  info->cp += xcf_read_string (info->input, &name, 1);
-                  type = g_type_from_name (name);
-                  if (! type || ! g_type_is_a (type, GIMP_TYPE_SYMMETRY))
-                    {
-                      gimp_message (info->gimp, G_OBJECT (info->progress),
-                                    GIMP_MESSAGE_ERROR,
-                                    "Unknown Symmetry: %s",
-                                    name);
-                      g_free (name);
-                      return FALSE;
-                    }
-                  sym = gimp_image_symmetry_add (image, type);
-
-                  settings = gimp_symmetry_get_xcf_settings (sym,
-                                                             &n_settings);
-                  for (j = 0; j < n_settings; j++)
-                    {
-                      if (settings[j] == NULL)
-                        continue;
-
-                      spec = settings[j];
-                      switch (spec->value_type)
-                        {
-                        case G_TYPE_BOOLEAN:
-                            {
-                              guint8 value;
-
-                              info->cp += xcf_read_int8 (info->input,
-                                                         &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (gboolean) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_FLOAT:
-                        case G_TYPE_DOUBLE:
-                            {
-                              gfloat value;
-
-                              info->cp += xcf_read_float (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (spec->value_type == G_TYPE_FLOAT) ?
-                                            value : (gdouble) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_UINT:
-                            {
-                              guint32 value;
-
-                              info->cp += xcf_read_int32 (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (guint) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_INT:
-                            {
-                              guint32 value;
-
-                              info->cp += xcf_read_int32 (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (gint) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_STRING:
-                            {
-                              gchar* value;
-
-                              info->cp += xcf_read_string (info->input,
-                                                           &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            value,
-                                            NULL);
-                              g_free (value);
-                            }
-                          break;
-                        default:
-                          /* We don't handle this settings. */
-                          gimp_message (info->gimp, G_OBJECT (info->progress),
-                                        GIMP_MESSAGE_ERROR,
-                                        "Unknown settings '%s' for '%s'",
-                                        name, g_param_spec_get_name (spec));
-                          g_free (name);
-                          return FALSE;
-                        }
-                    }
-                  g_free (settings);
-
-                  if (active == i)
-                    active_sym = sym;
-                }
-              gimp_image_symmetry_select (image, active_sym->type);
-              g_free (name);
-            }
-          break;
-
         case PROP_SAMPLE_POINTS:
           {
             gint32 x, y;
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index 1e10734..5e77700 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -56,8 +56,7 @@ typedef enum
   PROP_GROUP_ITEM         = 29,
   PROP_ITEM_PATH          = 30,
   PROP_GROUP_ITEM_FLAGS   = 31,
-  PROP_LOCK_POSITION      = 32,
-  PROP_SYMMETRY           = 33
+  PROP_LOCK_POSITION      = 32
 } PropType;
 
 typedef enum
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 1495b70..73e71b1 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -341,10 +341,12 @@ xcf_save_image_props (XcfInfo    *info,
                       GimpImage  *image,
                       GError    **error)
 {
-  GimpImagePrivate *private       = GIMP_IMAGE_GET_PRIVATE (image);
-  GimpParasite     *grid_parasite = NULL;
-  GimpParasite     *meta_parasite = NULL;
-  GimpUnit          unit          = gimp_image_get_unit (image);
+  GimpImagePrivate *private            = GIMP_IMAGE_GET_PRIVATE (image);
+  GimpParasite     *grid_parasite      = NULL;
+  GimpParasite     *meta_parasite      = NULL;
+  GList            *symmetry_parasites = NULL;
+  GList            *iter;
+  GimpUnit          unit               = gimp_image_get_unit (image);
   gdouble           xres;
   gdouble           yres;
 
@@ -364,10 +366,6 @@ xcf_save_image_props (XcfInfo    *info,
     xcf_check_error (xcf_save_prop (info, image, PROP_GUIDES, error,
                                     gimp_image_get_guides (image)));
 
-  if (g_list_length (gimp_image_symmetry_get (image)))
-    xcf_check_error (xcf_save_prop (info, image, PROP_SYMMETRY, error,
-                                    gimp_image_symmetry_get (image)));
-
   if (gimp_image_get_sample_points (image))
     xcf_check_error (xcf_save_prop (info, image, PROP_SAMPLE_POINTS, error,
                                     gimp_image_get_sample_points (image)));
@@ -418,6 +416,31 @@ xcf_save_image_props (XcfInfo    *info,
         }
     }
 
+  if (g_list_length (gimp_image_symmetry_get (image)))
+    {
+      GimpParasite *parasite  = NULL;
+
+      for (iter = gimp_image_symmetry_get (image); iter; iter = g_list_next (iter))
+        {
+          parasite = gimp_symmetry_to_parasite (GIMP_SYMMETRY (iter->data));
+          gimp_parasite_list_add (private->parasites, parasite);
+          symmetry_parasites = g_list_prepend (symmetry_parasites, parasite);
+        }
+      if (gimp_image_symmetry_selected (image))
+        {
+          const gchar *name;
+
+          name = g_type_name (gimp_image_symmetry_selected (image)->type);
+
+          parasite = gimp_parasite_new ("gimp-image-symmetry-selected",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (name) + 1,
+                                        name);
+          gimp_parasite_list_add (private->parasites, parasite);
+          symmetry_parasites = g_list_prepend (symmetry_parasites, parasite);
+        }
+    }
+
   if (gimp_parasite_list_length (private->parasites) > 0)
     {
       xcf_check_error (xcf_save_prop (info, image, PROP_PARASITES, error,
@@ -438,6 +461,16 @@ xcf_save_image_props (XcfInfo    *info,
       gimp_parasite_free (meta_parasite);
     }
 
+  for (iter = symmetry_parasites; iter; iter = g_list_next (iter))
+    {
+      GimpParasite *parasite = iter->data;
+
+      gimp_parasite_list_remove (private->parasites,
+                                 gimp_parasite_name (parasite));
+    }
+  g_list_free_full (symmetry_parasites,
+                    (GDestroyNotify) gimp_parasite_free);
+
   xcf_check_error (xcf_save_prop (info, image, PROP_END, error));
 
   return TRUE;
@@ -903,164 +936,6 @@ xcf_save_prop (XcfInfo    *info,
       }
       break;
 
-    case PROP_SYMMETRY:
-      {
-        GList         *syms;
-        GList         *iter;
-        GimpSymmetry  *sym;
-        GParamSpec   **settings;
-        GParamSpec    *spec;
-        gint           n_settings;
-        guint32        base;
-        glong          pos;
-        gint           i = 0;
-
-        xcf_write_prop_type_check_error (info, prop_type);
-        /* because we don't know how much room the Symmetry list
-         * will take we save the file position and write the length
-         * later.
-         */
-        pos = info->cp;
-        size = 0;
-        xcf_write_int32_check_error (info, &size, 1);
-        base = info->cp;
-
-        syms = va_arg (args, GList *);
-
-        /* Index of active symmetry starting at 1
-         * (because 0 means none active) */
-        if (gimp_image_symmetry_selected (image))
-          {
-            for (i = 1, iter = syms; iter; iter = g_list_next (iter), i++)
-              {
-                sym = GIMP_SYMMETRY (iter->data);
-                if (sym == gimp_image_symmetry_selected (image))
-                  break;
-              }
-          }
-        xcf_write_int32_check_error (info, (guint32 *)  &i, 1);
-        /* Number of symmetry that follows. */
-        i = g_list_length (syms);
-        xcf_write_int32_check_error (info, (guint32 *)  &i, 1);
-
-        for (iter = syms; iter; iter = g_list_next (iter))
-          {
-            const gchar *name;
-
-            sym = GIMP_SYMMETRY (iter->data);
-
-            name = g_type_name (sym->type);
-            xcf_write_string_check_error (info, (gchar **) &name, 1);
-
-            settings = gimp_symmetry_get_xcf_settings (sym,
-                                                       &n_settings);
-
-            for (i = 0; i < n_settings; i++)
-              {
-                if (settings[i] == NULL)
-                  continue;
-
-                spec = settings[i];
-
-                switch (spec->value_type)
-                  {
-                  case G_TYPE_BOOLEAN:
-                      {
-                        gboolean value;
-                        guint8   uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint8) value;
-                        xcf_write_int8_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_FLOAT:
-                      {
-                        gfloat value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        xcf_write_float_check_error (info, &value, 1);
-                      }
-                    break;
-                  case G_TYPE_DOUBLE:
-                      {
-                        gdouble value;
-                        gfloat  float_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        float_value = (gfloat) value;
-                        xcf_write_float_check_error (info, &float_value, 1);
-                      }
-                    break;
-                  case G_TYPE_UINT:
-                      {
-                        guint   value;
-                        guint32 uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint32) value;
-                        xcf_write_int32_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_INT:
-                      {
-                        gint    value;
-                        guint32 uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint32) value;
-                        xcf_write_int32_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_STRING:
-                      {
-                        gchar* value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        xcf_write_string_check_error (info, &value, 1);
-                        g_free (value);
-                      }
-                    break;
-                  default:
-                    /* We don't handle this settings. */
-                    gimp_message (info->gimp, G_OBJECT (info->progress),
-                                  GIMP_MESSAGE_ERROR,
-                                  "Unknown settings '%s' for '%s'",
-                                  name, g_param_spec_get_name (spec));
-                    return FALSE;
-                  }
-              }
-            g_free (settings);
-          }
-
-        size = info->cp - base;
-
-        /* go back to the saved position and write the length */
-        xcf_check_error (xcf_seek_pos (info, pos, error));
-        xcf_write_int32_check_error (info, &size, 1);
-
-        xcf_check_error (xcf_seek_pos (info, base + size, error));
-      }
-      break;
-
     case PROP_SAMPLE_POINTS:
       {
         GList *sample_points;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]