~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/config/gimpconfig-serialize.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
 
 *
4
 
 * Object properties serialization routines
5
 
 * Copyright (C) 2001-2002  Sven Neumann <sven@gimp.org>
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
10
 
 * (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
 
 */
21
 
 
22
 
#include "config.h"
23
 
 
24
 
#include <glib-object.h>
25
 
 
26
 
#include "libgimpbase/gimpbase.h"
27
 
#include "libgimpmath/gimpmath.h"
28
 
#include "libgimpcolor/gimpcolor.h"
29
 
 
30
 
#include "config-types.h"
31
 
 
32
 
#include "gimpconfig.h"
33
 
#include "gimpconfig-params.h"
34
 
#include "gimpconfig-serialize.h"
35
 
#include "gimpconfig-types.h"
36
 
#include "gimpconfig-utils.h"
37
 
#include "gimpconfigwriter.h"
38
 
 
39
 
 
40
 
static void  serialize_unknown_token (const gchar  *key,
41
 
                                      const gchar  *value,
42
 
                                      gpointer      data);
43
 
 
44
 
 
45
 
/**
46
 
 * gimp_config_serialize_properties:
47
 
 * @config: a #GimpConfig.
48
 
 * @writer: a #GimpConfigWriter.
49
 
 *
50
 
 * This function writes all object properties to the @writer.
51
 
 *
52
 
 * Returns: %TRUE if serialization succeeded, %FALSE otherwise
53
 
 **/
54
 
gboolean
55
 
gimp_config_serialize_properties (GimpConfig          *config,
56
 
                                  GimpConfigWriter *writer)
57
 
{
58
 
  GObjectClass  *klass;
59
 
  GParamSpec   **property_specs;
60
 
  guint          n_property_specs;
61
 
  guint          i;
62
 
 
63
 
  g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
64
 
 
65
 
  klass = G_OBJECT_GET_CLASS (config);
66
 
 
67
 
  property_specs = g_object_class_list_properties (klass, &n_property_specs);
68
 
 
69
 
  if (! property_specs)
70
 
    return TRUE;
71
 
 
72
 
  for (i = 0; i < n_property_specs; i++)
73
 
    {
74
 
      GParamSpec *prop_spec = property_specs[i];
75
 
 
76
 
      if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
77
 
        continue;
78
 
 
79
 
      if (! gimp_config_serialize_property (config, prop_spec, writer))
80
 
        return FALSE;
81
 
    }
82
 
 
83
 
  g_free (property_specs);
84
 
 
85
 
  return TRUE;
86
 
}
87
 
 
88
 
/**
89
 
 * gimp_config_serialize_changed_properties:
90
 
 * @config: a #GimpConfig.
91
 
 * @writer: a #GimpConfigWriter.
92
 
 *
93
 
 * This function writes all object properties that have been changed from
94
 
 * their default values to the @writer.
95
 
 *
96
 
 * Returns: %TRUE if serialization succeeded, %FALSE otherwise
97
 
 **/
98
 
gboolean
99
 
gimp_config_serialize_changed_properties (GimpConfig       *config,
100
 
                                          GimpConfigWriter *writer)
101
 
{
102
 
  GObjectClass  *klass;
103
 
  GParamSpec   **property_specs;
104
 
  guint          n_property_specs;
105
 
  guint          i;
106
 
  GValue         value = { 0, };
107
 
 
108
 
  g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
109
 
 
110
 
  klass = G_OBJECT_GET_CLASS (config);
111
 
 
112
 
  property_specs = g_object_class_list_properties (klass, &n_property_specs);
113
 
 
114
 
  if (! property_specs)
115
 
    return TRUE;
116
 
 
117
 
  for (i = 0; i < n_property_specs; i++)
118
 
    {
119
 
      GParamSpec *prop_spec = property_specs[i];
120
 
 
121
 
      if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
122
 
        continue;
123
 
 
124
 
      g_value_init (&value, prop_spec->value_type);
125
 
      g_object_get_property (G_OBJECT (config), prop_spec->name, &value);
126
 
 
127
 
      if (! g_param_value_defaults (prop_spec, &value))
128
 
        {
129
 
          if (! gimp_config_serialize_property (config, prop_spec, writer))
130
 
            return FALSE;
131
 
        }
132
 
 
133
 
      g_value_unset (&value);
134
 
    }
135
 
 
136
 
  g_free (property_specs);
137
 
 
138
 
  return TRUE;
139
 
}
140
 
 
141
 
/**
142
 
 * gimp_config_serialize_properties_diff:
143
 
 * @config: a #GimpConfig.
144
 
 * @compare: a #GimpConfig of the same type as @config.
145
 
 * @writer: a #GimpConfigWriter.
146
 
 *
147
 
 * This function compares @config and @compare and writes all
148
 
 * properties of @config that have different values than @compare to
149
 
 * the @writer.
150
 
 *
151
 
 * Returns: %TRUE if serialization succeeded, %FALSE otherwise
152
 
 **/
153
 
gboolean
154
 
gimp_config_serialize_properties_diff (GimpConfig       *config,
155
 
                                       GimpConfig       *compare,
156
 
                                       GimpConfigWriter *writer)
157
 
{
158
 
  GObjectClass *klass;
159
 
  GList        *diff;
160
 
  GList        *list;
161
 
 
162
 
  g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
163
 
  g_return_val_if_fail (G_IS_OBJECT (compare), FALSE);
164
 
  g_return_val_if_fail (G_TYPE_FROM_INSTANCE (config) ==
165
 
                        G_TYPE_FROM_INSTANCE (compare), FALSE);
166
 
 
167
 
  klass = G_OBJECT_GET_CLASS (config);
168
 
 
169
 
  diff = gimp_config_diff (config, compare, GIMP_PARAM_SERIALIZE);
170
 
 
171
 
  if (! diff)
172
 
    return TRUE;
173
 
 
174
 
  for (list = diff; list; list = g_list_next (list))
175
 
    {
176
 
      GParamSpec *prop_spec = (GParamSpec *) list->data;
177
 
 
178
 
      if (! (prop_spec->flags & GIMP_PARAM_SERIALIZE))
179
 
        continue;
180
 
 
181
 
      if (! gimp_config_serialize_property (config, prop_spec, writer))
182
 
        return FALSE;
183
 
    }
184
 
 
185
 
  g_list_free (diff);
186
 
 
187
 
  return TRUE;
188
 
}
189
 
 
190
 
 
191
 
gboolean
192
 
gimp_config_serialize_property (GimpConfig       *config,
193
 
                                GParamSpec       *param_spec,
194
 
                                GimpConfigWriter *writer)
195
 
{
196
 
  GTypeClass          *owner_class;
197
 
  GimpConfigInterface *config_iface;
198
 
  GimpConfigInterface *parent_iface = NULL;
199
 
  GValue               value   = { 0, };
200
 
  gboolean             success = FALSE;
201
 
 
202
 
  if (! (param_spec->flags & GIMP_PARAM_SERIALIZE))
203
 
    return FALSE;
204
 
 
205
 
  if (param_spec->flags & GIMP_PARAM_IGNORE)
206
 
    return TRUE;
207
 
 
208
 
  g_value_init (&value, param_spec->value_type);
209
 
  g_object_get_property (G_OBJECT (config), param_spec->name, &value);
210
 
 
211
 
  if (param_spec->flags & GIMP_PARAM_DEFAULTS &&
212
 
      g_param_value_defaults (param_spec, &value))
213
 
    {
214
 
      g_value_unset (&value);
215
 
      return TRUE;
216
 
    }
217
 
 
218
 
  owner_class = g_type_class_peek (param_spec->owner_type);
219
 
 
220
 
  config_iface = g_type_interface_peek (owner_class, GIMP_TYPE_CONFIG);
221
 
 
222
 
  /*  We must call serialize_property() *only* if the *exact* class
223
 
   *  which implements it is param_spec->owner_type's class.
224
 
   *
225
 
   *  Therefore, we ask param_spec->owner_type's immediate parent class
226
 
   *  for it's GimpConfigInterface and check if we get a different pointer.
227
 
   *
228
 
   *  (if the pointers are the same, param_spec->owner_type's
229
 
   *   GimpConfigInterface is inherited from one of it's parent classes
230
 
   *   and thus not able to handle param_spec->owner_type's properties).
231
 
   */
232
 
  if (config_iface)
233
 
    {
234
 
      GTypeClass *owner_parent_class;
235
 
 
236
 
      owner_parent_class = g_type_class_peek_parent (owner_class),
237
 
 
238
 
      parent_iface = g_type_interface_peek (owner_parent_class,
239
 
                                            GIMP_TYPE_CONFIG);
240
 
    }
241
 
 
242
 
  if (config_iface                     &&
243
 
      config_iface != parent_iface     && /* see comment above */
244
 
      config_iface->serialize_property &&
245
 
      config_iface->serialize_property (config,
246
 
                                        param_spec->param_id,
247
 
                                        (const GValue *) &value,
248
 
                                        param_spec,
249
 
                                        writer))
250
 
    {
251
 
      success = TRUE;
252
 
    }
253
 
 
254
 
  /*  If there is no serialize_property() method *or* if it returned
255
 
   *  FALSE, continue with the default implementation
256
 
   */
257
 
 
258
 
  if (! success)
259
 
    {
260
 
      if (G_VALUE_HOLDS_OBJECT (&value))
261
 
        {
262
 
          GimpConfigInterface *config_iface = NULL;
263
 
          GimpConfig          *prop_object;
264
 
 
265
 
          prop_object = g_value_get_object (&value);
266
 
 
267
 
          if (prop_object)
268
 
            config_iface = GIMP_CONFIG_GET_INTERFACE (prop_object);
269
 
          else
270
 
            success = TRUE;
271
 
 
272
 
          if (config_iface)
273
 
            {
274
 
              gimp_config_writer_open (writer, param_spec->name);
275
 
 
276
 
              /*  if the object property is not GIMP_PARAM_AGGREGATE,
277
 
               *  deserializing will need to know the exact type
278
 
               *  in order to create the object
279
 
               */
280
 
              if (! (param_spec->flags & GIMP_PARAM_AGGREGATE))
281
 
                {
282
 
                  GType object_type = G_TYPE_FROM_INSTANCE (prop_object);
283
 
 
284
 
                  gimp_config_writer_string (writer, g_type_name (object_type));
285
 
                }
286
 
 
287
 
              success = config_iface->serialize (prop_object, writer, NULL);
288
 
 
289
 
              if (success)
290
 
                gimp_config_writer_close (writer);
291
 
              else
292
 
                gimp_config_writer_revert (writer);
293
 
            }
294
 
        }
295
 
      else if (! G_VALUE_HOLDS_OBJECT (&value))
296
 
        {
297
 
          GString *str = g_string_new (NULL);
298
 
 
299
 
          success = gimp_config_serialize_value (&value, str, TRUE);
300
 
 
301
 
          if (success)
302
 
            {
303
 
              gimp_config_writer_open (writer, param_spec->name);
304
 
              gimp_config_writer_print (writer, str->str, str->len);
305
 
              gimp_config_writer_close (writer);
306
 
            }
307
 
 
308
 
          g_string_free (str, TRUE);
309
 
        }
310
 
 
311
 
      if (! success)
312
 
        {
313
 
          /* don't warn for empty string properties */
314
 
          if (G_VALUE_HOLDS_STRING (&value))
315
 
            {
316
 
              success = TRUE;
317
 
            }
318
 
          else
319
 
            {
320
 
              g_warning ("couldn't serialize property %s::%s of type %s",
321
 
                         g_type_name (G_TYPE_FROM_INSTANCE (config)),
322
 
                         param_spec->name,
323
 
                         g_type_name (param_spec->value_type));
324
 
            }
325
 
        }
326
 
    }
327
 
 
328
 
  g_value_unset (&value);
329
 
 
330
 
  return success;
331
 
}
332
 
 
333
 
/**
334
 
 * gimp_config_serialize_value:
335
 
 * @value: a #GValue.
336
 
 * @str: a #Gstring.
337
 
 * @escaped: whether to escape string values.
338
 
 *
339
 
 * This utility function appends a string representation of #GValue to @str.
340
 
 *
341
 
 * Return value: %TRUE if serialization succeeded, %FALSE otherwise.
342
 
 **/
343
 
gboolean
344
 
gimp_config_serialize_value (const GValue *value,
345
 
                             GString      *str,
346
 
                             gboolean      escaped)
347
 
{
348
 
  if (G_VALUE_HOLDS_BOOLEAN (value))
349
 
    {
350
 
      gboolean bool;
351
 
 
352
 
      bool = g_value_get_boolean (value);
353
 
      g_string_append (str, bool ? "yes" : "no");
354
 
      return TRUE;
355
 
    }
356
 
 
357
 
  if (G_VALUE_HOLDS_ENUM (value))
358
 
    {
359
 
      GEnumClass *enum_class = g_type_class_peek (G_VALUE_TYPE (value));
360
 
      GEnumValue *enum_value = g_enum_get_value (enum_class,
361
 
                                                 g_value_get_enum (value));
362
 
 
363
 
      if (enum_value && enum_value->value_nick)
364
 
        {
365
 
          g_string_append (str, enum_value->value_nick);
366
 
          return TRUE;
367
 
        }
368
 
      else
369
 
        {
370
 
          g_warning ("Couldn't get nick for enum_value of %s",
371
 
                     G_ENUM_CLASS_TYPE_NAME (enum_class));
372
 
          return FALSE;
373
 
        }
374
 
    }
375
 
 
376
 
  if (G_VALUE_HOLDS_STRING (value))
377
 
    {
378
 
      const gchar *cstr = g_value_get_string (value);
379
 
 
380
 
      if (!cstr)
381
 
        return FALSE;
382
 
 
383
 
      if (escaped)
384
 
        gimp_config_string_append_escaped (str, cstr);
385
 
      else
386
 
        g_string_append (str, cstr);
387
 
 
388
 
      return TRUE;
389
 
    }
390
 
 
391
 
  if (G_VALUE_HOLDS_DOUBLE (value) || G_VALUE_HOLDS_FLOAT (value))
392
 
    {
393
 
      gdouble v_double;
394
 
      gchar   buf[G_ASCII_DTOSTR_BUF_SIZE];
395
 
 
396
 
      if (G_VALUE_HOLDS_DOUBLE (value))
397
 
        v_double = g_value_get_double (value);
398
 
      else
399
 
        v_double = (gdouble) g_value_get_float (value);
400
 
 
401
 
      g_ascii_formatd (buf, sizeof (buf), "%f", v_double);
402
 
      g_string_append (str, buf);
403
 
      return TRUE;
404
 
    }
405
 
 
406
 
  if (GIMP_VALUE_HOLDS_RGB (value))
407
 
    {
408
 
      GimpRGB *rgb;
409
 
      gchar    buf[4][G_ASCII_DTOSTR_BUF_SIZE];
410
 
 
411
 
      rgb = g_value_get_boxed (value);
412
 
 
413
 
      g_ascii_formatd (buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", rgb->r);
414
 
      g_ascii_formatd (buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", rgb->g);
415
 
      g_ascii_formatd (buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", rgb->b);
416
 
      g_ascii_formatd (buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", rgb->a);
417
 
 
418
 
      g_string_append_printf (str, "(color-rgba %s %s %s %s)",
419
 
                              buf[0], buf[1], buf[2], buf[3]);
420
 
      return TRUE;
421
 
    }
422
 
 
423
 
  if (GIMP_VALUE_HOLDS_MATRIX2 (value))
424
 
    {
425
 
      GimpMatrix2 *trafo;
426
 
      gchar        buf[4][G_ASCII_DTOSTR_BUF_SIZE];
427
 
      gint         i, j, k;
428
 
 
429
 
      trafo = g_value_get_boxed (value);
430
 
 
431
 
      for (i = 0, k = 0; i < 2; i++)
432
 
        for (j = 0; j < 2; j++, k++)
433
 
          g_ascii_formatd (buf[k],
434
 
                           G_ASCII_DTOSTR_BUF_SIZE, "%f", trafo->coeff[i][j]);
435
 
 
436
 
      g_string_append_printf (str, "(matrix %s %s %s %s)",
437
 
                              buf[0], buf[1], buf[2], buf[3]);
438
 
      return TRUE;
439
 
    }
440
 
 
441
 
  if (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY)
442
 
    {
443
 
      GValueArray *array;
444
 
 
445
 
      array = g_value_get_boxed (value);
446
 
 
447
 
      if (array)
448
 
        {
449
 
          gint i;
450
 
 
451
 
          g_string_append_printf (str, "%d", array->n_values);
452
 
 
453
 
          for (i = 0; i < array->n_values; i++)
454
 
            {
455
 
              g_string_append (str, " ");
456
 
 
457
 
              if (! gimp_config_serialize_value (g_value_array_get_nth (array,
458
 
                                                                        i),
459
 
                                                 str, TRUE))
460
 
                return FALSE;
461
 
            }
462
 
        }
463
 
      else
464
 
        {
465
 
          g_string_append (str, "NULL");
466
 
        }
467
 
 
468
 
      return TRUE;
469
 
    }
470
 
 
471
 
  if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
472
 
    {
473
 
      GValue  tmp_value = { 0, };
474
 
 
475
 
      g_value_init (&tmp_value, G_TYPE_STRING);
476
 
      g_value_transform (value, &tmp_value);
477
 
 
478
 
      g_string_append (str, g_value_get_string (&tmp_value));
479
 
 
480
 
      g_value_unset (&tmp_value);
481
 
      return TRUE;
482
 
    }
483
 
 
484
 
  return FALSE;
485
 
}
486
 
 
487
 
 
488
 
/**
489
 
 * gimp_config_serialize_unknown_tokens:
490
 
 * @config: a #GimpConfig.
491
 
 * @writer: a #GimpConfigWriter.
492
 
 *
493
 
 * Writes all unknown tokens attached to @config to the @writer.  See
494
 
 * gimp_config_add_unknown_token().
495
 
 *
496
 
 * Returns: %TRUE if serialization succeeded, %FALSE otherwise
497
 
 **/
498
 
gboolean
499
 
gimp_config_serialize_unknown_tokens (GimpConfig       *config,
500
 
                                      GimpConfigWriter *writer)
501
 
{
502
 
  g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
503
 
 
504
 
  gimp_config_writer_linefeed (writer);
505
 
  gimp_config_foreach_unknown_token (config, serialize_unknown_token, writer);
506
 
 
507
 
  return TRUE;
508
 
}
509
 
 
510
 
static void
511
 
serialize_unknown_token (const gchar *key,
512
 
                         const gchar *value,
513
 
                         gpointer     data)
514
 
{
515
 
  GimpConfigWriter *writer = data;
516
 
 
517
 
  gimp_config_writer_open (writer, key);
518
 
  gimp_config_writer_string (writer, value);
519
 
  gimp_config_writer_close (writer);
520
 
}