1 /* This file is part of GEGL
2 *
3 * GEGL is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 3 of the License, or (at your option) any later version.
7 *
8 * GEGL is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
15 *
16 * Copyright 2003 Calvin Williamson
17 * 2006 Øyvind Kolås
18 *
19 * Original contents copied from gimp/app/core/gimpparamspecs.h
20 * (c) 1995-2006 Spencer Kimball, Peter Mattis and others.
21 */
22
23 #include "config.h"
24
25 #include <glib.h>
26 #include <glib-object.h>
27 #include "gegl-paramspecs.h"
28 #include "gegl-types.h"
29 #include <babl/babl.h>
30 #include "gegl-color.h"
31 #include "gegl-audio-fragment.h"
32 #include "gegl-curve.h"
33 #include "gegl-path.h"
34
35 static void gegl_param_double_class_init (GParamSpecClass *klass);
36 static void gegl_param_double_init (GParamSpec *pspec);
37
38 GType
gegl_param_double_get_type(void)39 gegl_param_double_get_type (void)
40 {
41 static GType type = 0;
42
43 if (!type)
44 {
45 const GTypeInfo info =
46 {
47 sizeof (GParamSpecClass),
48 NULL, NULL,
49 (GClassInitFunc) gegl_param_double_class_init,
50 NULL, NULL,
51 sizeof (GeglParamSpecDouble),
52 0,
53 (GInstanceInitFunc) gegl_param_double_init
54 };
55 type = g_type_register_static (G_TYPE_PARAM_DOUBLE,
56 "GeglParamDouble", &info, 0);
57 }
58 return type;
59 }
60
61 static void
gegl_param_double_class_init(GParamSpecClass * klass)62 gegl_param_double_class_init (GParamSpecClass *klass)
63 {
64 klass->value_type = G_TYPE_DOUBLE;
65 }
66
67 static void
gegl_param_double_init(GParamSpec * pspec)68 gegl_param_double_init (GParamSpec *pspec)
69 {
70 GParamSpecDouble *dpspec = G_PARAM_SPEC_DOUBLE (pspec);
71 GeglParamSpecDouble *gdpspec = GEGL_PARAM_SPEC_DOUBLE (pspec);
72 gdpspec->ui_minimum = dpspec->minimum;
73 gdpspec->ui_maximum = dpspec->maximum;
74 gdpspec->ui_gamma = 1.0;
75 }
76
77 GParamSpec *
gegl_param_spec_double(const gchar * name,const gchar * nick,const gchar * blurb,gdouble minimum,gdouble maximum,gdouble default_value,gdouble ui_minimum,gdouble ui_maximum,gdouble ui_gamma,GParamFlags flags)78 gegl_param_spec_double (const gchar *name,
79 const gchar *nick,
80 const gchar *blurb,
81 gdouble minimum,
82 gdouble maximum,
83 gdouble default_value,
84 gdouble ui_minimum,
85 gdouble ui_maximum,
86 gdouble ui_gamma,
87 GParamFlags flags)
88 {
89 GeglParamSpecDouble *pspec;
90 GParamSpecDouble *dspec;
91
92 pspec = g_param_spec_internal (GEGL_TYPE_PARAM_DOUBLE,
93 name, nick, blurb, flags);
94 dspec = G_PARAM_SPEC_DOUBLE (pspec);
95
96 dspec->minimum = minimum;
97 dspec->maximum = maximum;
98 dspec->default_value = default_value;
99 pspec->ui_minimum = ui_minimum;
100 pspec->ui_maximum = ui_maximum;
101 pspec->ui_gamma = ui_gamma;
102 gegl_param_spec_double_set_steps (pspec, 0.1, 1.0);
103 gegl_param_spec_double_set_digits (pspec, 2);
104
105 return G_PARAM_SPEC (pspec);
106 }
107
108 void
gegl_param_spec_double_set_steps(GeglParamSpecDouble * pspec,gdouble step_small,gdouble step_big)109 gegl_param_spec_double_set_steps (GeglParamSpecDouble *pspec,
110 gdouble step_small,
111 gdouble step_big)
112 {
113 g_return_if_fail (GEGL_IS_PARAM_SPEC_DOUBLE (pspec));
114
115 pspec->ui_step_small = step_small;
116 pspec->ui_step_big = step_big;
117 }
118
gegl_param_spec_double_set_digits(GeglParamSpecDouble * pspec,gint digits)119 void gegl_param_spec_double_set_digits (GeglParamSpecDouble *pspec,
120 gint digits)
121 {
122 g_return_if_fail (GEGL_IS_PARAM_SPEC_DOUBLE (pspec));
123
124 pspec->ui_digits = digits;
125 }
126
127 gdouble gegl_param_spec_double_get_step_size (GeglParamSpecDouble *pspec);
128 gdouble gegl_param_spec_double_get_page_size (GeglParamSpecDouble *pspec);
129
130 static void gegl_param_int_class_init (GParamSpecClass *klass);
131 static void gegl_param_int_init (GParamSpec *pspec);
132
133 GType
gegl_param_int_get_type(void)134 gegl_param_int_get_type (void)
135 {
136 static GType type = 0;
137
138 if (!type)
139 {
140 const GTypeInfo info =
141 {
142 sizeof (GParamSpecClass),
143 NULL, NULL,
144 (GClassInitFunc) gegl_param_int_class_init,
145 NULL, NULL,
146 sizeof (GeglParamSpecInt),
147 0,
148 (GInstanceInitFunc) gegl_param_int_init
149 };
150 type = g_type_register_static (G_TYPE_PARAM_INT,
151 "GeglParamInt", &info, 0);
152 }
153 return type;
154 }
155
156 static void
gegl_param_int_class_init(GParamSpecClass * klass)157 gegl_param_int_class_init (GParamSpecClass *klass)
158 {
159 klass->value_type = G_TYPE_INT;
160 }
161
162 static void
gegl_param_int_init(GParamSpec * pspec)163 gegl_param_int_init (GParamSpec *pspec)
164 {
165 GParamSpecInt *dpspec = G_PARAM_SPEC_INT (pspec);
166 GeglParamSpecInt *gdpspec = GEGL_PARAM_SPEC_INT (pspec);
167 gdpspec->ui_minimum = dpspec->minimum;
168 gdpspec->ui_maximum = dpspec->maximum;
169 gdpspec->ui_gamma = 1.0;
170 }
171
172 GParamSpec *
gegl_param_spec_int(const gchar * name,const gchar * nick,const gchar * blurb,gint minimum,gint maximum,gint default_value,gint ui_minimum,gint ui_maximum,gdouble ui_gamma,GParamFlags flags)173 gegl_param_spec_int (const gchar *name,
174 const gchar *nick,
175 const gchar *blurb,
176 gint minimum,
177 gint maximum,
178 gint default_value,
179 gint ui_minimum,
180 gint ui_maximum,
181 gdouble ui_gamma,
182 GParamFlags flags)
183 {
184 GeglParamSpecInt *pspec;
185 GParamSpecInt *ispec;
186
187
188 pspec = g_param_spec_internal (GEGL_TYPE_PARAM_INT,
189 name, nick, blurb, flags);
190 ispec = G_PARAM_SPEC_INT (pspec);
191
192 ispec->minimum = minimum;
193 ispec->maximum = maximum;
194 ispec->default_value = default_value;
195 pspec->ui_minimum = ui_minimum;
196 pspec->ui_maximum = ui_maximum;
197 pspec->ui_gamma = ui_gamma;
198
199 gegl_param_spec_int_set_steps (pspec, 1, 5);
200 return G_PARAM_SPEC (pspec);
201 }
202
203 void
gegl_param_spec_int_set_steps(GeglParamSpecInt * pspec,gint step_small,gint step_big)204 gegl_param_spec_int_set_steps (GeglParamSpecInt *pspec,
205 gint step_small,
206 gint step_big)
207 {
208 g_return_if_fail (GEGL_IS_PARAM_SPEC_INT (pspec));
209
210 pspec->ui_step_small = step_small;
211 pspec->ui_step_big = step_big;
212 }
213
214 /*
215 * GEGL_TYPE_PARAM_STRING
216 */
217
218 static void gegl_param_string_class_init (GParamSpecClass *klass);
219 static void gegl_param_string_init (GParamSpec *pspec);
220 static gboolean gegl_param_string_validate (GParamSpec *pspec,
221 GValue *value);
222
223 GType
gegl_param_string_get_type(void)224 gegl_param_string_get_type (void)
225 {
226 static GType type = 0;
227
228 if (!type)
229 {
230 const GTypeInfo info =
231 {
232 sizeof (GParamSpecClass),
233 NULL, NULL,
234 (GClassInitFunc) gegl_param_string_class_init,
235 NULL, NULL,
236 sizeof (GeglParamSpecString),
237 0,
238 (GInstanceInitFunc) gegl_param_string_init
239 };
240
241 type = g_type_register_static (G_TYPE_PARAM_STRING,
242 "GeglParamString", &info, 0);
243 }
244
245 return type;
246 }
247
248 static void
gegl_param_string_class_init(GParamSpecClass * klass)249 gegl_param_string_class_init (GParamSpecClass *klass)
250 {
251 klass->value_type = G_TYPE_STRING;
252 klass->value_validate = gegl_param_string_validate;
253 }
254
255 static void
gegl_param_string_init(GParamSpec * pspec)256 gegl_param_string_init (GParamSpec *pspec)
257 {
258 GeglParamSpecString *sspec = GEGL_PARAM_SPEC_STRING (pspec);
259
260 sspec->no_validate = FALSE;
261 sspec->null_ok = FALSE;
262 }
263
264 static gboolean
gegl_param_string_validate(GParamSpec * pspec,GValue * value)265 gegl_param_string_validate (GParamSpec *pspec,
266 GValue *value)
267 {
268 GeglParamSpecString *sspec = GEGL_PARAM_SPEC_STRING (pspec);
269 gchar *string = value->data[0].v_pointer;
270
271 if (string)
272 {
273 gchar *s;
274
275 if (!sspec->no_validate &&
276 !g_utf8_validate (string, -1, (const gchar **) &s))
277 {
278 for (; *s; s++)
279 if (*s < ' ')
280 *s = '?';
281
282 return TRUE;
283 }
284 }
285 else if (!sspec->null_ok)
286 {
287 value->data[0].v_pointer = g_strdup ("");
288 return TRUE;
289 }
290
291 return FALSE;
292 }
293
294 GParamSpec *
gegl_param_spec_string(const gchar * name,const gchar * nick,const gchar * blurb,gboolean no_validate,gboolean null_ok,const gchar * default_value,GParamFlags flags)295 gegl_param_spec_string (const gchar *name,
296 const gchar *nick,
297 const gchar *blurb,
298 gboolean no_validate,
299 gboolean null_ok,
300 const gchar *default_value,
301 GParamFlags flags)
302 {
303 GeglParamSpecString *sspec;
304
305 sspec = g_param_spec_internal (GEGL_TYPE_PARAM_STRING,
306 name, nick, blurb, flags);
307
308 if (sspec)
309 {
310 g_free (G_PARAM_SPEC_STRING (sspec)->default_value);
311 G_PARAM_SPEC_STRING (sspec)->default_value = g_strdup (default_value);
312
313 sspec->no_validate = no_validate ? TRUE : FALSE;
314 sspec->null_ok = null_ok ? TRUE : FALSE;
315 }
316
317 return G_PARAM_SPEC (sspec);
318 }
319
320
321 /*
322 * GEGL_TYPE_PARAM_FILE_PATH
323 */
324
325 static void gegl_param_file_path_class_init (GParamSpecClass *klass);
326 static void gegl_param_file_path_init (GParamSpec *pspec);
327 static gboolean gegl_param_file_path_validate (GParamSpec *pspec,
328 GValue *value);
329
330 GType
gegl_param_file_path_get_type(void)331 gegl_param_file_path_get_type (void)
332 {
333 static GType type = 0;
334
335 if (!type)
336 {
337 const GTypeInfo info =
338 {
339 sizeof (GParamSpecClass),
340 NULL, NULL,
341 (GClassInitFunc) gegl_param_file_path_class_init,
342 NULL, NULL,
343 sizeof (GeglParamSpecString),
344 0,
345 (GInstanceInitFunc) gegl_param_file_path_init
346 };
347
348 type = g_type_register_static (G_TYPE_PARAM_STRING,
349 "GeglParamFilePath", &info, 0);
350 }
351
352 return type;
353 }
354
355 static void
gegl_param_file_path_class_init(GParamSpecClass * klass)356 gegl_param_file_path_class_init (GParamSpecClass *klass)
357 {
358 klass->value_type = G_TYPE_STRING;
359 klass->value_validate = gegl_param_file_path_validate;
360 }
361
362 static void
gegl_param_file_path_init(GParamSpec * pspec)363 gegl_param_file_path_init (GParamSpec *pspec)
364 {
365 GeglParamSpecFilePath *sspec = GEGL_PARAM_SPEC_FILE_PATH (pspec);
366
367 sspec->no_validate = FALSE;
368 sspec->null_ok = FALSE;
369 }
370
371 static gboolean
gegl_param_file_path_validate(GParamSpec * pspec,GValue * value)372 gegl_param_file_path_validate (GParamSpec *pspec,
373 GValue *value)
374 {
375 GeglParamSpecFilePath *sspec = GEGL_PARAM_SPEC_FILE_PATH (pspec);
376 gchar *path = value->data[0].v_pointer;
377
378 if (path)
379 {
380 gchar *s;
381
382 if (!sspec->no_validate &&
383 !g_utf8_validate (path, -1, (const gchar **) &s))
384 {
385 for (; *s; s++)
386 if (*s < ' ')
387 *s = '?';
388
389 return TRUE;
390 }
391 }
392 else if (!sspec->null_ok)
393 {
394 value->data[0].v_pointer = g_strdup ("");
395 return TRUE;
396 }
397
398 return FALSE;
399 }
400
401 GParamSpec *
gegl_param_spec_file_path(const gchar * name,const gchar * nick,const gchar * blurb,gboolean no_validate,gboolean null_ok,const gchar * default_value,GParamFlags flags)402 gegl_param_spec_file_path (const gchar *name,
403 const gchar *nick,
404 const gchar *blurb,
405 gboolean no_validate,
406 gboolean null_ok,
407 const gchar *default_value,
408 GParamFlags flags)
409 {
410 GeglParamSpecFilePath *sspec;
411
412 sspec = g_param_spec_internal (GEGL_TYPE_PARAM_FILE_PATH,
413 name, nick, blurb, flags);
414
415 if (sspec)
416 {
417 g_free (G_PARAM_SPEC_STRING (sspec)->default_value);
418 G_PARAM_SPEC_STRING (sspec)->default_value = g_strdup (default_value);
419
420 sspec->no_validate = no_validate ? TRUE : FALSE;
421 sspec->null_ok = null_ok ? TRUE : FALSE;
422 }
423
424 return G_PARAM_SPEC (sspec);
425 }
426
427 /*
428 * GEGL_TYPE_PARAM_ENUM
429 */
430
431 static void gegl_param_enum_class_init (GParamSpecClass *klass);
432 static void gegl_param_enum_init (GParamSpec *pspec);
433 static void gegl_param_enum_finalize (GParamSpec *pspec);
434 static gboolean gegl_param_enum_validate (GParamSpec *pspec,
435 GValue *value);
436
437 GType
gegl_param_enum_get_type(void)438 gegl_param_enum_get_type (void)
439 {
440 static GType type = 0;
441
442 if (!type)
443 {
444 const GTypeInfo info =
445 {
446 sizeof (GParamSpecClass),
447 NULL, NULL,
448 (GClassInitFunc) gegl_param_enum_class_init,
449 NULL, NULL,
450 sizeof (GeglParamSpecEnum),
451 0,
452 (GInstanceInitFunc) gegl_param_enum_init
453 };
454
455 type = g_type_register_static (G_TYPE_PARAM_ENUM,
456 "GeglParamEnum", &info, 0);
457 }
458
459 return type;
460 }
461
462 static void
gegl_param_enum_class_init(GParamSpecClass * klass)463 gegl_param_enum_class_init (GParamSpecClass *klass)
464 {
465 klass->value_type = G_TYPE_ENUM;
466 klass->finalize = gegl_param_enum_finalize;
467 klass->value_validate = gegl_param_enum_validate;
468 }
469
470 static void
gegl_param_enum_init(GParamSpec * pspec)471 gegl_param_enum_init (GParamSpec *pspec)
472 {
473 GeglParamSpecEnum *espec = GEGL_PARAM_SPEC_ENUM (pspec);
474
475 espec->excluded_values = NULL;
476 }
477
478 static void
gegl_param_enum_finalize(GParamSpec * pspec)479 gegl_param_enum_finalize (GParamSpec *pspec)
480 {
481 GeglParamSpecEnum *espec = GEGL_PARAM_SPEC_ENUM (pspec);
482 GParamSpecClass *parent_class;
483
484 parent_class = g_type_class_peek (g_type_parent (GEGL_TYPE_PARAM_ENUM));
485
486 g_slist_free (espec->excluded_values);
487
488 parent_class->finalize (pspec);
489 }
490
491 static gboolean
gegl_param_enum_validate(GParamSpec * pspec,GValue * value)492 gegl_param_enum_validate (GParamSpec *pspec,
493 GValue *value)
494 {
495 GeglParamSpecEnum *espec = GEGL_PARAM_SPEC_ENUM (pspec);
496 GParamSpecClass *parent_class;
497 GSList *list;
498
499 parent_class = g_type_class_peek (g_type_parent (GEGL_TYPE_PARAM_ENUM));
500
501 if (parent_class->value_validate (pspec, value))
502 return TRUE;
503
504 for (list = espec->excluded_values; list; list = g_slist_next (list))
505 {
506 if (GPOINTER_TO_INT (list->data) == value->data[0].v_long)
507 {
508 value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value;
509 return TRUE;
510 }
511 }
512
513 return FALSE;
514 }
515
516 GParamSpec *
gegl_param_spec_enum(const gchar * name,const gchar * nick,const gchar * blurb,GType enum_type,gint default_value,GParamFlags flags)517 gegl_param_spec_enum (const gchar *name,
518 const gchar *nick,
519 const gchar *blurb,
520 GType enum_type,
521 gint default_value,
522 GParamFlags flags)
523 {
524 GeglParamSpecEnum *espec;
525 GEnumClass *enum_class;
526
527 g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
528
529 enum_class = g_type_class_ref (enum_type);
530
531 g_return_val_if_fail (g_enum_get_value (enum_class, default_value) != NULL,
532 NULL);
533
534 espec = g_param_spec_internal (GEGL_TYPE_PARAM_ENUM,
535 name, nick, blurb, flags);
536
537 G_PARAM_SPEC_ENUM (espec)->enum_class = enum_class;
538 G_PARAM_SPEC_ENUM (espec)->default_value = default_value;
539 G_PARAM_SPEC (espec)->value_type = enum_type;
540
541 return G_PARAM_SPEC (espec);
542 }
543
544 void
gegl_param_spec_enum_exclude_value(GeglParamSpecEnum * espec,gint value)545 gegl_param_spec_enum_exclude_value (GeglParamSpecEnum *espec,
546 gint value)
547 {
548 g_return_if_fail (GEGL_IS_PARAM_SPEC_ENUM (espec));
549 g_return_if_fail (g_enum_get_value (G_PARAM_SPEC_ENUM (espec)->enum_class,
550 value) != NULL);
551
552 espec->excluded_values = g_slist_prepend (espec->excluded_values,
553 GINT_TO_POINTER (value));
554 }
555
556 /*
557 * GEGL_TYPE_PARAM_SEED
558 */
559
560 static void gegl_param_seed_class_init (GParamSpecClass *klass);
561 static void gegl_param_seed_init (GParamSpec *pspec);
562
563 GType
gegl_param_seed_get_type(void)564 gegl_param_seed_get_type (void)
565 {
566 static GType type = 0;
567
568 if (!type)
569 {
570 const GTypeInfo info =
571 {
572 sizeof (GParamSpecClass),
573 NULL, NULL,
574 (GClassInitFunc) gegl_param_seed_class_init,
575 NULL, NULL,
576 sizeof (GeglParamSpecSeed),
577 0,
578 (GInstanceInitFunc) gegl_param_seed_init
579 };
580 type = g_type_register_static (G_TYPE_PARAM_UINT,
581 "GeglParamSeed", &info, 0);
582 }
583 return type;
584 }
585
586 static void
gegl_param_seed_class_init(GParamSpecClass * klass)587 gegl_param_seed_class_init (GParamSpecClass *klass)
588 {
589 klass->value_type = G_TYPE_UINT;
590 }
591
592 static void
gegl_param_seed_init(GParamSpec * pspec)593 gegl_param_seed_init (GParamSpec *pspec)
594 {
595 GeglParamSpecSeed *gdpspec = GEGL_PARAM_SPEC_SEED (pspec);
596
597 gdpspec->ui_minimum = 0;
598 gdpspec->ui_maximum = G_MAXUINT;
599 }
600
601 GParamSpec *
gegl_param_spec_seed(const gchar * name,const gchar * nick,const gchar * blurb,GParamFlags flags)602 gegl_param_spec_seed (const gchar *name,
603 const gchar *nick,
604 const gchar *blurb,
605 GParamFlags flags)
606 {
607 GeglParamSpecSeed *pspec;
608 GParamSpecUInt *ispec;
609
610 pspec = g_param_spec_internal (GEGL_TYPE_PARAM_SEED,
611 name, nick, blurb, flags);
612 ispec = G_PARAM_SPEC_UINT (pspec);
613
614 ispec->minimum = 0;
615 ispec->maximum = G_MAXUINT;
616 ispec->default_value = 0;
617 pspec->ui_minimum = 0;
618 pspec->ui_maximum = G_MAXUINT;
619
620 return G_PARAM_SPEC (pspec);
621 }
622
623 /*
624 * GEGL_TYPE_PARAM_FORMAT
625 */
626
627 static void gegl_param_format_class_init (GParamSpecClass *klass);
628 static void gegl_param_format_init (GParamSpec *pspec);
629
630 GType
gegl_param_format_get_type(void)631 gegl_param_format_get_type (void)
632 {
633 static GType type = 0;
634
635 if (!type)
636 {
637 const GTypeInfo info =
638 {
639 sizeof (GParamSpecClass),
640 NULL, NULL,
641 (GClassInitFunc) gegl_param_format_class_init,
642 NULL, NULL,
643 sizeof (GeglParamSpecFormat),
644 0,
645 (GInstanceInitFunc) gegl_param_format_init
646 };
647 type = g_type_register_static (G_TYPE_PARAM_POINTER,
648 "GeglParamFormat", &info, 0);
649 }
650 return type;
651 }
652
653 static void
gegl_param_format_class_init(GParamSpecClass * klass)654 gegl_param_format_class_init (GParamSpecClass *klass)
655 {
656 klass->value_type = G_TYPE_POINTER;
657 }
658
659 static void
gegl_param_format_init(GParamSpec * pspec)660 gegl_param_format_init (GParamSpec *pspec)
661 {
662 }
663
664 GParamSpec *
gegl_param_spec_format(const gchar * name,const gchar * nick,const gchar * blurb,GParamFlags flags)665 gegl_param_spec_format (const gchar *name,
666 const gchar *nick,
667 const gchar *blurb,
668 GParamFlags flags)
669 {
670 GeglParamSpecFormat *pspec;
671
672 pspec = g_param_spec_internal (GEGL_TYPE_PARAM_FORMAT,
673 name, nick, blurb, flags);
674
675 return G_PARAM_SPEC (pspec);
676 }
677
678 /*
679 * GEGL_TYPE_PARAM_URI
680 */
681
682 static void gegl_param_uri_class_init (GParamSpecClass *klass);
683 static void gegl_param_uri_init (GParamSpec *pspec);
684 static gboolean gegl_param_uri_validate (GParamSpec *pspec,
685 GValue *value);
686
687 GType
gegl_param_uri_get_type(void)688 gegl_param_uri_get_type (void)
689 {
690 static GType type = 0;
691
692 if (!type)
693 {
694 const GTypeInfo info =
695 {
696 sizeof (GParamSpecClass),
697 NULL, NULL,
698 (GClassInitFunc) gegl_param_uri_class_init,
699 NULL, NULL,
700 sizeof (GeglParamSpecString),
701 0,
702 (GInstanceInitFunc) gegl_param_uri_init
703 };
704
705 type = g_type_register_static (G_TYPE_PARAM_STRING,
706 "GeglParamUri", &info, 0);
707 }
708
709 return type;
710 }
711
712 static void
gegl_param_uri_class_init(GParamSpecClass * klass)713 gegl_param_uri_class_init (GParamSpecClass *klass)
714 {
715 klass->value_type = G_TYPE_STRING;
716 klass->value_validate = gegl_param_uri_validate;
717 }
718
719 static void
gegl_param_uri_init(GParamSpec * pspec)720 gegl_param_uri_init (GParamSpec *pspec)
721 {
722 GeglParamSpecUri *sspec = GEGL_PARAM_SPEC_URI (pspec);
723
724 sspec->no_validate = FALSE;
725 sspec->null_ok = FALSE;
726 }
727
728 static gboolean
gegl_param_uri_validate(GParamSpec * pspec,GValue * value)729 gegl_param_uri_validate (GParamSpec *pspec,
730 GValue *value)
731 {
732 GeglParamSpecUri *sspec = GEGL_PARAM_SPEC_URI (pspec);
733 gchar *path = value->data[0].v_pointer;
734
735 if (path)
736 {
737 gchar *s;
738
739 if (!sspec->no_validate &&
740 !g_utf8_validate (path, -1, (const gchar **) &s))
741 {
742 for (; *s; s++)
743 if (*s < ' ')
744 *s = '?';
745
746 return TRUE;
747 }
748 }
749 else if (!sspec->null_ok)
750 {
751 value->data[0].v_pointer = g_strdup ("");
752 return TRUE;
753 }
754
755 return FALSE;
756 }
757
758 GParamSpec *
gegl_param_spec_uri(const gchar * name,const gchar * nick,const gchar * blurb,gboolean no_validate,gboolean null_ok,const gchar * default_value,GParamFlags flags)759 gegl_param_spec_uri (const gchar *name,
760 const gchar *nick,
761 const gchar *blurb,
762 gboolean no_validate,
763 gboolean null_ok,
764 const gchar *default_value,
765 GParamFlags flags)
766 {
767 GeglParamSpecUri *sspec;
768
769 sspec = g_param_spec_internal (GEGL_TYPE_PARAM_URI,
770 name, nick, blurb, flags);
771
772 if (sspec)
773 {
774 g_free (G_PARAM_SPEC_STRING (sspec)->default_value);
775 G_PARAM_SPEC_STRING (sspec)->default_value = g_strdup (default_value);
776
777 sspec->no_validate = no_validate ? TRUE : FALSE;
778 sspec->null_ok = null_ok ? TRUE : FALSE;
779 }
780
781 return G_PARAM_SPEC (sspec);
782 }
783
784