1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpparamspecs-duplicate.c
5 * Copyright (C) 2008-2014 Michael Natterer <mitch@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 3 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, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <cairo.h>
24 #include <gegl.h>
25 #include <gegl-paramspecs.h>
26 #include <gdk-pixbuf/gdk-pixbuf.h>
27
28 #include "libgimpcolor/gimpcolor.h"
29 #include "libgimpconfig/gimpconfig.h"
30
31 #include "core-types.h"
32
33 #include "gegl/gimp-gegl-utils.h"
34
35 #include "gimpparamspecs.h"
36 #include "gimpparamspecs-duplicate.h"
37
38
39 /* FIXME: this code is not yet general as it should be (gegl tool only atm) */
40
41 GParamSpec *
gimp_param_spec_duplicate(GParamSpec * pspec)42 gimp_param_spec_duplicate (GParamSpec *pspec)
43 {
44 GParamSpec *copy = NULL;
45 GParamFlags flags;
46
47 g_return_val_if_fail (pspec != NULL, NULL);
48
49 flags = pspec->flags;
50
51 if (! gimp_gegl_param_spec_has_key (pspec, "role", "output-extent"))
52 flags |= GIMP_CONFIG_PARAM_SERIALIZE;
53
54 if (G_IS_PARAM_SPEC_STRING (pspec))
55 {
56 GParamSpecString *spec = G_PARAM_SPEC_STRING (pspec);
57
58 if (GEGL_IS_PARAM_SPEC_FILE_PATH (pspec))
59 {
60 copy = gimp_param_spec_config_path (pspec->name,
61 g_param_spec_get_nick (pspec),
62 g_param_spec_get_blurb (pspec),
63 GIMP_CONFIG_PATH_FILE,
64 spec->default_value,
65 flags);
66 }
67 else
68 {
69 copy = g_param_spec_string (pspec->name,
70 g_param_spec_get_nick (pspec),
71 g_param_spec_get_blurb (pspec),
72 spec->default_value,
73 flags);
74 }
75 }
76 else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
77 {
78 GParamSpecBoolean *spec = G_PARAM_SPEC_BOOLEAN (pspec);
79
80 copy = g_param_spec_boolean (pspec->name,
81 g_param_spec_get_nick (pspec),
82 g_param_spec_get_blurb (pspec),
83 spec->default_value,
84 flags);
85 }
86 else if (G_IS_PARAM_SPEC_ENUM (pspec))
87 {
88 GParamSpecEnum *spec = G_PARAM_SPEC_ENUM (pspec);
89
90 copy = g_param_spec_enum (pspec->name,
91 g_param_spec_get_nick (pspec),
92 g_param_spec_get_blurb (pspec),
93 G_TYPE_FROM_CLASS (spec->enum_class),
94 spec->default_value,
95 flags);
96 }
97 else if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
98 {
99 GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);
100 GParamSpecDouble *spec = G_PARAM_SPEC_DOUBLE (pspec);
101
102 copy = gegl_param_spec_double (pspec->name,
103 g_param_spec_get_nick (pspec),
104 g_param_spec_get_blurb (pspec),
105 spec->minimum,
106 spec->maximum,
107 spec->default_value,
108 gspec->ui_minimum,
109 gspec->ui_maximum,
110 gspec->ui_gamma,
111 flags);
112 gegl_param_spec_double_set_steps (GEGL_PARAM_SPEC_DOUBLE (copy),
113 gspec->ui_step_small,
114 gspec->ui_step_big);
115 gegl_param_spec_double_set_digits (GEGL_PARAM_SPEC_DOUBLE (copy),
116 gspec->ui_digits);
117 }
118 else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
119 {
120 GParamSpecDouble *spec = G_PARAM_SPEC_DOUBLE (pspec);
121
122 copy = g_param_spec_double (pspec->name,
123 g_param_spec_get_nick (pspec),
124 g_param_spec_get_blurb (pspec),
125 spec->minimum,
126 spec->maximum,
127 spec->default_value,
128 flags);
129 }
130 else if (G_IS_PARAM_SPEC_FLOAT (pspec))
131 {
132 GParamSpecFloat *spec = G_PARAM_SPEC_FLOAT (pspec);
133
134 copy = g_param_spec_float (pspec->name,
135 g_param_spec_get_nick (pspec),
136 g_param_spec_get_blurb (pspec),
137 spec->minimum,
138 spec->maximum,
139 spec->default_value,
140 flags);
141 }
142 else if (GEGL_IS_PARAM_SPEC_INT (pspec))
143 {
144 GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);
145 GParamSpecInt *spec = G_PARAM_SPEC_INT (pspec);
146
147 copy = gegl_param_spec_int (pspec->name,
148 g_param_spec_get_nick (pspec),
149 g_param_spec_get_blurb (pspec),
150 spec->minimum,
151 spec->maximum,
152 spec->default_value,
153 gspec->ui_minimum,
154 gspec->ui_maximum,
155 gspec->ui_gamma,
156 flags);
157 gegl_param_spec_int_set_steps (GEGL_PARAM_SPEC_INT (copy),
158 gspec->ui_step_small,
159 gspec->ui_step_big);
160 }
161 else if (GEGL_IS_PARAM_SPEC_SEED (pspec))
162 {
163 GParamSpecUInt *spec = G_PARAM_SPEC_UINT (pspec);
164 GeglParamSpecSeed *gspec = GEGL_PARAM_SPEC_SEED (pspec);
165
166 copy = gegl_param_spec_seed (pspec->name,
167 g_param_spec_get_nick (pspec),
168 g_param_spec_get_blurb (pspec),
169 pspec->flags |
170 GIMP_CONFIG_PARAM_SERIALIZE);
171
172 G_PARAM_SPEC_UINT (copy)->minimum = spec->minimum;
173 G_PARAM_SPEC_UINT (copy)->maximum = spec->maximum;
174
175 GEGL_PARAM_SPEC_SEED (copy)->ui_minimum = gspec->ui_minimum;
176 GEGL_PARAM_SPEC_SEED (copy)->ui_maximum = gspec->ui_maximum;
177 }
178 else if (G_IS_PARAM_SPEC_INT (pspec))
179 {
180 GParamSpecInt *spec = G_PARAM_SPEC_INT (pspec);
181
182 copy = g_param_spec_int (pspec->name,
183 g_param_spec_get_nick (pspec),
184 g_param_spec_get_blurb (pspec),
185 spec->minimum,
186 spec->maximum,
187 spec->default_value,
188 flags);
189 }
190 else if (G_IS_PARAM_SPEC_UINT (pspec))
191 {
192 GParamSpecUInt *spec = G_PARAM_SPEC_UINT (pspec);
193
194 copy = g_param_spec_uint (pspec->name,
195 g_param_spec_get_nick (pspec),
196 g_param_spec_get_blurb (pspec),
197 spec->minimum,
198 spec->maximum,
199 spec->default_value,
200 flags);
201 }
202 else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
203 {
204 GValue value = G_VALUE_INIT;
205 GimpRGB color;
206
207 g_value_init (&value, GIMP_TYPE_RGB);
208 g_param_value_set_default (pspec, &value);
209 gimp_value_get_rgb (&value, &color);
210 g_value_unset (&value);
211
212 copy = gimp_param_spec_rgb (pspec->name,
213 g_param_spec_get_nick (pspec),
214 g_param_spec_get_blurb (pspec),
215 gimp_param_spec_rgb_has_alpha (pspec),
216 &color,
217 flags);
218 }
219 else if (GEGL_IS_PARAM_SPEC_COLOR (pspec))
220 {
221 GeglColor *gegl_color;
222 GimpRGB gimp_color;
223 gdouble r = 0.0;
224 gdouble g = 0.0;
225 gdouble b = 0.0;
226 gdouble a = 1.0;
227 GValue value = G_VALUE_INIT;
228
229 g_value_init (&value, GEGL_TYPE_COLOR);
230 g_param_value_set_default (pspec, &value);
231
232 gegl_color = g_value_get_object (&value);
233 if (gegl_color)
234 gegl_color_get_rgba (gegl_color, &r, &g, &b, &a);
235
236 gimp_rgba_set (&gimp_color, r, g, b, a);
237
238 g_value_unset (&value);
239
240 copy = gimp_param_spec_rgb (pspec->name,
241 g_param_spec_get_nick (pspec),
242 g_param_spec_get_blurb (pspec),
243 TRUE,
244 &gimp_color,
245 flags);
246 }
247 else if (G_IS_PARAM_SPEC_OBJECT (pspec) ||
248 G_IS_PARAM_SPEC_POINTER (pspec))
249 {
250 /* silently ignore object properties */
251 }
252 else
253 {
254 g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
255 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
256 }
257
258 if (copy)
259 {
260 GQuark quark = g_quark_from_static_string ("gegl-property-keys");
261 GHashTable *keys = g_param_spec_get_qdata (pspec, quark);
262
263 if (keys)
264 g_param_spec_set_qdata_full (copy, quark, g_hash_table_ref (keys),
265 (GDestroyNotify) g_hash_table_unref);
266 }
267
268 return copy;
269 }
270