1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpcontext.c
5 * Copyright (C) 1999-2010 Michael Natterer
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 <gdk-pixbuf/gdk-pixbuf.h>
26
27 #include "libgimpbase/gimpbase.h"
28 #include "libgimpcolor/gimpcolor.h"
29 #include "libgimpconfig/gimpconfig.h"
30
31 #include "core-types.h"
32
33 #include "config/gimpcoreconfig.h"
34
35 #include "gimp.h"
36 #include "gimp-memsize.h"
37 #include "gimpbrush.h"
38 #include "gimpbuffer.h"
39 #include "gimpcontainer.h"
40 #include "gimpcontext.h"
41 #include "gimpdatafactory.h"
42 #include "gimpdynamics.h"
43 #include "gimpimagefile.h"
44 #include "gimpgradient.h"
45 #include "gimpimage.h"
46 #include "gimpmarshal.h"
47 #include "gimpmybrush.h"
48 #include "gimppaintinfo.h"
49 #include "gimppalette.h"
50 #include "gimppattern.h"
51 #include "gimptemplate.h"
52 #include "gimptoolinfo.h"
53 #include "gimptoolpreset.h"
54
55 #include "text/gimpfont.h"
56
57 #include "gimp-intl.h"
58
59
60 #define RGBA_EPSILON 1e-10
61
62 typedef void (* GimpContextCopyPropFunc) (GimpContext *src,
63 GimpContext *dest);
64
65 #define context_find_defined(context, prop) \
66 while (!(((context)->defined_props) & (1 << (prop))) && (context)->parent) \
67 (context) = (context)->parent
68
69 #define COPY_NAME(src, dest, member) \
70 g_free (dest->member); \
71 dest->member = g_strdup (src->member)
72
73
74 /* local function prototypes */
75
76 static void gimp_context_config_iface_init (GimpConfigInterface *iface);
77
78 static void gimp_context_constructed (GObject *object);
79 static void gimp_context_dispose (GObject *object);
80 static void gimp_context_finalize (GObject *object);
81 static void gimp_context_set_property (GObject *object,
82 guint property_id,
83 const GValue *value,
84 GParamSpec *pspec);
85 static void gimp_context_get_property (GObject *object,
86 guint property_id,
87 GValue *value,
88 GParamSpec *pspec);
89 static gint64 gimp_context_get_memsize (GimpObject *object,
90 gint64 *gui_size);
91
92 static gboolean gimp_context_serialize (GimpConfig *config,
93 GimpConfigWriter *writer,
94 gpointer data);
95 static gboolean gimp_context_deserialize (GimpConfig *config,
96 GScanner *scanner,
97 gint nest_level,
98 gpointer data);
99 static gboolean gimp_context_serialize_property (GimpConfig *config,
100 guint property_id,
101 const GValue *value,
102 GParamSpec *pspec,
103 GimpConfigWriter *writer);
104 static gboolean gimp_context_deserialize_property (GimpConfig *config,
105 guint property_id,
106 GValue *value,
107 GParamSpec *pspec,
108 GScanner *scanner,
109 GTokenType *expected);
110 static GimpConfig * gimp_context_duplicate (GimpConfig *config);
111 static gboolean gimp_context_copy (GimpConfig *src,
112 GimpConfig *dest,
113 GParamFlags flags);
114
115 /* image */
116 static void gimp_context_image_removed (GimpContainer *container,
117 GimpImage *image,
118 GimpContext *context);
119 static void gimp_context_real_set_image (GimpContext *context,
120 GimpImage *image);
121
122 /* display */
123 static void gimp_context_display_removed (GimpContainer *container,
124 gpointer display,
125 GimpContext *context);
126 static void gimp_context_real_set_display (GimpContext *context,
127 gpointer display);
128
129 /* tool */
130 static void gimp_context_tool_dirty (GimpToolInfo *tool_info,
131 GimpContext *context);
132 static void gimp_context_tool_removed (GimpContainer *container,
133 GimpToolInfo *tool_info,
134 GimpContext *context);
135 static void gimp_context_tool_list_thaw (GimpContainer *container,
136 GimpContext *context);
137 static void gimp_context_real_set_tool (GimpContext *context,
138 GimpToolInfo *tool_info);
139
140 /* paint info */
141 static void gimp_context_paint_info_dirty (GimpPaintInfo *paint_info,
142 GimpContext *context);
143 static void gimp_context_paint_info_removed (GimpContainer *container,
144 GimpPaintInfo *paint_info,
145 GimpContext *context);
146 static void gimp_context_paint_info_list_thaw(GimpContainer *container,
147 GimpContext *context);
148 static void gimp_context_real_set_paint_info (GimpContext *context,
149 GimpPaintInfo *paint_info);
150
151 /* foreground */
152 static void gimp_context_real_set_foreground (GimpContext *context,
153 const GimpRGB *color);
154
155 /* background */
156 static void gimp_context_real_set_background (GimpContext *context,
157 const GimpRGB *color);
158
159 /* opacity */
160 static void gimp_context_real_set_opacity (GimpContext *context,
161 gdouble opacity);
162
163 /* paint mode */
164 static void gimp_context_real_set_paint_mode (GimpContext *context,
165 GimpLayerMode paint_mode);
166
167 /* brush */
168 static void gimp_context_brush_dirty (GimpBrush *brush,
169 GimpContext *context);
170 static void gimp_context_brush_removed (GimpContainer *brush_list,
171 GimpBrush *brush,
172 GimpContext *context);
173 static void gimp_context_brush_list_thaw (GimpContainer *container,
174 GimpContext *context);
175 static void gimp_context_real_set_brush (GimpContext *context,
176 GimpBrush *brush);
177
178 /* dynamics */
179
180 static void gimp_context_dynamics_dirty (GimpDynamics *dynamics,
181 GimpContext *context);
182 static void gimp_context_dynamics_removed (GimpContainer *container,
183 GimpDynamics *dynamics,
184 GimpContext *context);
185 static void gimp_context_dynamics_list_thaw (GimpContainer *container,
186 GimpContext *context);
187 static void gimp_context_real_set_dynamics (GimpContext *context,
188 GimpDynamics *dynamics);
189
190 /* mybrush */
191 static void gimp_context_mybrush_dirty (GimpMybrush *brush,
192 GimpContext *context);
193 static void gimp_context_mybrush_removed (GimpContainer *brush_list,
194 GimpMybrush *brush,
195 GimpContext *context);
196 static void gimp_context_mybrush_list_thaw (GimpContainer *container,
197 GimpContext *context);
198 static void gimp_context_real_set_mybrush (GimpContext *context,
199 GimpMybrush *brush);
200
201 /* pattern */
202 static void gimp_context_pattern_dirty (GimpPattern *pattern,
203 GimpContext *context);
204 static void gimp_context_pattern_removed (GimpContainer *container,
205 GimpPattern *pattern,
206 GimpContext *context);
207 static void gimp_context_pattern_list_thaw (GimpContainer *container,
208 GimpContext *context);
209 static void gimp_context_real_set_pattern (GimpContext *context,
210 GimpPattern *pattern);
211
212 /* gradient */
213 static void gimp_context_gradient_dirty (GimpGradient *gradient,
214 GimpContext *context);
215 static void gimp_context_gradient_removed (GimpContainer *container,
216 GimpGradient *gradient,
217 GimpContext *context);
218 static void gimp_context_gradient_list_thaw (GimpContainer *container,
219 GimpContext *context);
220 static void gimp_context_real_set_gradient (GimpContext *context,
221 GimpGradient *gradient);
222
223 /* palette */
224 static void gimp_context_palette_dirty (GimpPalette *palette,
225 GimpContext *context);
226 static void gimp_context_palette_removed (GimpContainer *container,
227 GimpPalette *palette,
228 GimpContext *context);
229 static void gimp_context_palette_list_thaw (GimpContainer *container,
230 GimpContext *context);
231 static void gimp_context_real_set_palette (GimpContext *context,
232 GimpPalette *palette);
233
234 /* font */
235 static void gimp_context_font_dirty (GimpFont *font,
236 GimpContext *context);
237 static void gimp_context_font_removed (GimpContainer *container,
238 GimpFont *font,
239 GimpContext *context);
240 static void gimp_context_font_list_thaw (GimpContainer *container,
241 GimpContext *context);
242 static void gimp_context_real_set_font (GimpContext *context,
243 GimpFont *font);
244
245 /* tool preset */
246 static void gimp_context_tool_preset_dirty (GimpToolPreset *tool_preset,
247 GimpContext *context);
248 static void gimp_context_tool_preset_removed (GimpContainer *container,
249 GimpToolPreset *tool_preset,
250 GimpContext *context);
251 static void gimp_context_tool_preset_list_thaw (GimpContainer *container,
252 GimpContext *context);
253 static void gimp_context_real_set_tool_preset (GimpContext *context,
254 GimpToolPreset *tool_preset);
255
256 /* buffer */
257 static void gimp_context_buffer_dirty (GimpBuffer *buffer,
258 GimpContext *context);
259 static void gimp_context_buffer_removed (GimpContainer *container,
260 GimpBuffer *buffer,
261 GimpContext *context);
262 static void gimp_context_buffer_list_thaw (GimpContainer *container,
263 GimpContext *context);
264 static void gimp_context_real_set_buffer (GimpContext *context,
265 GimpBuffer *buffer);
266
267 /* imagefile */
268 static void gimp_context_imagefile_dirty (GimpImagefile *imagefile,
269 GimpContext *context);
270 static void gimp_context_imagefile_removed (GimpContainer *container,
271 GimpImagefile *imagefile,
272 GimpContext *context);
273 static void gimp_context_imagefile_list_thaw (GimpContainer *container,
274 GimpContext *context);
275 static void gimp_context_real_set_imagefile (GimpContext *context,
276 GimpImagefile *imagefile);
277
278 /* template */
279 static void gimp_context_template_dirty (GimpTemplate *template,
280 GimpContext *context);
281 static void gimp_context_template_removed (GimpContainer *container,
282 GimpTemplate *template,
283 GimpContext *context);
284 static void gimp_context_template_list_thaw (GimpContainer *container,
285 GimpContext *context);
286 static void gimp_context_real_set_template (GimpContext *context,
287 GimpTemplate *template);
288
289
290 /* utilities */
291 static gpointer gimp_context_find_object (GimpContext *context,
292 GimpContainer *container,
293 const gchar *object_name,
294 gpointer standard_object);
295
296
297 /* properties & signals */
298
299 enum
300 {
301 GIMP_CONTEXT_PROP_0,
302 GIMP_CONTEXT_PROP_GIMP
303
304 /* remaining values are in core-enums.h (GimpContextPropType) */
305 };
306
307 enum
308 {
309 DUMMY_0,
310 DUMMY_1,
311 IMAGE_CHANGED,
312 DISPLAY_CHANGED,
313 TOOL_CHANGED,
314 PAINT_INFO_CHANGED,
315 FOREGROUND_CHANGED,
316 BACKGROUND_CHANGED,
317 OPACITY_CHANGED,
318 PAINT_MODE_CHANGED,
319 BRUSH_CHANGED,
320 DYNAMICS_CHANGED,
321 MYBRUSH_CHANGED,
322 PATTERN_CHANGED,
323 GRADIENT_CHANGED,
324 PALETTE_CHANGED,
325 FONT_CHANGED,
326 TOOL_PRESET_CHANGED,
327 BUFFER_CHANGED,
328 IMAGEFILE_CHANGED,
329 TEMPLATE_CHANGED,
330 PROP_NAME_CHANGED,
331 LAST_SIGNAL
332 };
333
334 static const gchar * const gimp_context_prop_names[] =
335 {
336 NULL, /* PROP_0 */
337 "gimp",
338 "image",
339 "display",
340 "tool",
341 "paint-info",
342 "foreground",
343 "background",
344 "opacity",
345 "paint-mode",
346 "brush",
347 "dynamics",
348 "mybrush",
349 "pattern",
350 "gradient",
351 "palette",
352 "font",
353 "tool-preset",
354 "buffer",
355 "imagefile",
356 "template"
357 };
358
359 static GType gimp_context_prop_types[] =
360 {
361 G_TYPE_NONE, /* PROP_0 */
362 G_TYPE_NONE, /* PROP_GIMP */
363 0,
364 G_TYPE_NONE,
365 0,
366 0,
367 G_TYPE_NONE,
368 G_TYPE_NONE,
369 G_TYPE_NONE,
370 G_TYPE_NONE,
371 0,
372 0,
373 0,
374 0,
375 0,
376 0,
377 0,
378 0,
379 0,
380 0,
381 0
382 };
383
384
385 G_DEFINE_TYPE_WITH_CODE (GimpContext, gimp_context, GIMP_TYPE_VIEWABLE,
386 G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
387 gimp_context_config_iface_init))
388
389 #define parent_class gimp_context_parent_class
390
391 static GimpConfigInterface *parent_config_iface = NULL;
392
393 static guint gimp_context_signals[LAST_SIGNAL] = { 0 };
394
395
396 static void
gimp_context_class_init(GimpContextClass * klass)397 gimp_context_class_init (GimpContextClass *klass)
398 {
399 GObjectClass *object_class = G_OBJECT_CLASS (klass);
400 GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
401 GimpRGB black;
402 GimpRGB white;
403
404 gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
405 gimp_rgba_set (&white, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
406
407 gimp_context_signals[IMAGE_CHANGED] =
408 g_signal_new ("image-changed",
409 G_TYPE_FROM_CLASS (klass),
410 G_SIGNAL_RUN_FIRST,
411 G_STRUCT_OFFSET (GimpContextClass, image_changed),
412 NULL, NULL,
413 gimp_marshal_VOID__OBJECT,
414 G_TYPE_NONE, 1,
415 GIMP_TYPE_IMAGE);
416
417 gimp_context_signals[DISPLAY_CHANGED] =
418 g_signal_new ("display-changed",
419 G_TYPE_FROM_CLASS (klass),
420 G_SIGNAL_RUN_FIRST,
421 G_STRUCT_OFFSET (GimpContextClass, display_changed),
422 NULL, NULL,
423 gimp_marshal_VOID__OBJECT,
424 G_TYPE_NONE, 1,
425 GIMP_TYPE_OBJECT);
426
427 gimp_context_signals[TOOL_CHANGED] =
428 g_signal_new ("tool-changed",
429 G_TYPE_FROM_CLASS (klass),
430 G_SIGNAL_RUN_FIRST,
431 G_STRUCT_OFFSET (GimpContextClass, tool_changed),
432 NULL, NULL,
433 gimp_marshal_VOID__OBJECT,
434 G_TYPE_NONE, 1,
435 GIMP_TYPE_TOOL_INFO);
436
437 gimp_context_signals[PAINT_INFO_CHANGED] =
438 g_signal_new ("paint-info-changed",
439 G_TYPE_FROM_CLASS (klass),
440 G_SIGNAL_RUN_FIRST,
441 G_STRUCT_OFFSET (GimpContextClass, paint_info_changed),
442 NULL, NULL,
443 gimp_marshal_VOID__OBJECT,
444 G_TYPE_NONE, 1,
445 GIMP_TYPE_PAINT_INFO);
446
447 gimp_context_signals[FOREGROUND_CHANGED] =
448 g_signal_new ("foreground-changed",
449 G_TYPE_FROM_CLASS (klass),
450 G_SIGNAL_RUN_FIRST,
451 G_STRUCT_OFFSET (GimpContextClass, foreground_changed),
452 NULL, NULL,
453 gimp_marshal_VOID__BOXED,
454 G_TYPE_NONE, 1,
455 GIMP_TYPE_RGB | G_SIGNAL_TYPE_STATIC_SCOPE);
456
457 gimp_context_signals[BACKGROUND_CHANGED] =
458 g_signal_new ("background-changed",
459 G_TYPE_FROM_CLASS (klass),
460 G_SIGNAL_RUN_FIRST,
461 G_STRUCT_OFFSET (GimpContextClass, background_changed),
462 NULL, NULL,
463 gimp_marshal_VOID__BOXED,
464 G_TYPE_NONE, 1,
465 GIMP_TYPE_RGB | G_SIGNAL_TYPE_STATIC_SCOPE);
466
467 gimp_context_signals[OPACITY_CHANGED] =
468 g_signal_new ("opacity-changed",
469 G_TYPE_FROM_CLASS (klass),
470 G_SIGNAL_RUN_FIRST,
471 G_STRUCT_OFFSET (GimpContextClass, opacity_changed),
472 NULL, NULL,
473 gimp_marshal_VOID__DOUBLE,
474 G_TYPE_NONE, 1,
475 G_TYPE_DOUBLE);
476
477 gimp_context_signals[PAINT_MODE_CHANGED] =
478 g_signal_new ("paint-mode-changed",
479 G_TYPE_FROM_CLASS (klass),
480 G_SIGNAL_RUN_FIRST,
481 G_STRUCT_OFFSET (GimpContextClass, paint_mode_changed),
482 NULL, NULL,
483 gimp_marshal_VOID__ENUM,
484 G_TYPE_NONE, 1,
485 GIMP_TYPE_LAYER_MODE);
486
487 gimp_context_signals[BRUSH_CHANGED] =
488 g_signal_new ("brush-changed",
489 G_TYPE_FROM_CLASS (klass),
490 G_SIGNAL_RUN_FIRST,
491 G_STRUCT_OFFSET (GimpContextClass, brush_changed),
492 NULL, NULL,
493 gimp_marshal_VOID__OBJECT,
494 G_TYPE_NONE, 1,
495 GIMP_TYPE_BRUSH);
496
497 gimp_context_signals[DYNAMICS_CHANGED] =
498 g_signal_new ("dynamics-changed",
499 G_TYPE_FROM_CLASS (klass),
500 G_SIGNAL_RUN_FIRST,
501 G_STRUCT_OFFSET (GimpContextClass, dynamics_changed),
502 NULL, NULL,
503 gimp_marshal_VOID__OBJECT,
504 G_TYPE_NONE, 1,
505 GIMP_TYPE_DYNAMICS);
506
507 gimp_context_signals[MYBRUSH_CHANGED] =
508 g_signal_new ("mybrush-changed",
509 G_TYPE_FROM_CLASS (klass),
510 G_SIGNAL_RUN_FIRST,
511 G_STRUCT_OFFSET (GimpContextClass, mybrush_changed),
512 NULL, NULL,
513 gimp_marshal_VOID__OBJECT,
514 G_TYPE_NONE, 1,
515 GIMP_TYPE_MYBRUSH);
516
517 gimp_context_signals[PATTERN_CHANGED] =
518 g_signal_new ("pattern-changed",
519 G_TYPE_FROM_CLASS (klass),
520 G_SIGNAL_RUN_FIRST,
521 G_STRUCT_OFFSET (GimpContextClass, pattern_changed),
522 NULL, NULL,
523 gimp_marshal_VOID__OBJECT,
524 G_TYPE_NONE, 1,
525 GIMP_TYPE_PATTERN);
526
527 gimp_context_signals[GRADIENT_CHANGED] =
528 g_signal_new ("gradient-changed",
529 G_TYPE_FROM_CLASS (klass),
530 G_SIGNAL_RUN_FIRST,
531 G_STRUCT_OFFSET (GimpContextClass, gradient_changed),
532 NULL, NULL,
533 gimp_marshal_VOID__OBJECT,
534 G_TYPE_NONE, 1,
535 GIMP_TYPE_GRADIENT);
536
537 gimp_context_signals[PALETTE_CHANGED] =
538 g_signal_new ("palette-changed",
539 G_TYPE_FROM_CLASS (klass),
540 G_SIGNAL_RUN_FIRST,
541 G_STRUCT_OFFSET (GimpContextClass, palette_changed),
542 NULL, NULL,
543 gimp_marshal_VOID__OBJECT,
544 G_TYPE_NONE, 1,
545 GIMP_TYPE_PALETTE);
546
547 gimp_context_signals[FONT_CHANGED] =
548 g_signal_new ("font-changed",
549 G_TYPE_FROM_CLASS (klass),
550 G_SIGNAL_RUN_FIRST,
551 G_STRUCT_OFFSET (GimpContextClass, font_changed),
552 NULL, NULL,
553 gimp_marshal_VOID__OBJECT,
554 G_TYPE_NONE, 1,
555 GIMP_TYPE_FONT);
556
557 gimp_context_signals[TOOL_PRESET_CHANGED] =
558 g_signal_new ("tool-preset-changed",
559 G_TYPE_FROM_CLASS (klass),
560 G_SIGNAL_RUN_FIRST,
561 G_STRUCT_OFFSET (GimpContextClass, tool_preset_changed),
562 NULL, NULL,
563 gimp_marshal_VOID__OBJECT,
564 G_TYPE_NONE, 1,
565 GIMP_TYPE_TOOL_PRESET);
566
567 gimp_context_signals[BUFFER_CHANGED] =
568 g_signal_new ("buffer-changed",
569 G_TYPE_FROM_CLASS (klass),
570 G_SIGNAL_RUN_FIRST,
571 G_STRUCT_OFFSET (GimpContextClass, buffer_changed),
572 NULL, NULL,
573 gimp_marshal_VOID__OBJECT,
574 G_TYPE_NONE, 1,
575 GIMP_TYPE_BUFFER);
576
577 gimp_context_signals[IMAGEFILE_CHANGED] =
578 g_signal_new ("imagefile-changed",
579 G_TYPE_FROM_CLASS (klass),
580 G_SIGNAL_RUN_FIRST,
581 G_STRUCT_OFFSET (GimpContextClass, imagefile_changed),
582 NULL, NULL,
583 gimp_marshal_VOID__OBJECT,
584 G_TYPE_NONE, 1,
585 GIMP_TYPE_IMAGEFILE);
586
587 gimp_context_signals[TEMPLATE_CHANGED] =
588 g_signal_new ("template-changed",
589 G_TYPE_FROM_CLASS (klass),
590 G_SIGNAL_RUN_FIRST,
591 G_STRUCT_OFFSET (GimpContextClass, template_changed),
592 NULL, NULL,
593 gimp_marshal_VOID__OBJECT,
594 G_TYPE_NONE, 1,
595 GIMP_TYPE_TEMPLATE);
596
597 gimp_context_signals[PROP_NAME_CHANGED] =
598 g_signal_new ("prop-name-changed",
599 G_TYPE_FROM_CLASS (klass),
600 G_SIGNAL_RUN_FIRST,
601 G_STRUCT_OFFSET (GimpContextClass, prop_name_changed),
602 NULL, NULL,
603 gimp_marshal_VOID__INT,
604 G_TYPE_NONE, 1,
605 G_TYPE_INT);
606
607 object_class->constructed = gimp_context_constructed;
608 object_class->set_property = gimp_context_set_property;
609 object_class->get_property = gimp_context_get_property;
610 object_class->dispose = gimp_context_dispose;
611 object_class->finalize = gimp_context_finalize;
612
613 gimp_object_class->get_memsize = gimp_context_get_memsize;
614
615 klass->image_changed = NULL;
616 klass->display_changed = NULL;
617 klass->tool_changed = NULL;
618 klass->paint_info_changed = NULL;
619 klass->foreground_changed = NULL;
620 klass->background_changed = NULL;
621 klass->opacity_changed = NULL;
622 klass->paint_mode_changed = NULL;
623 klass->brush_changed = NULL;
624 klass->dynamics_changed = NULL;
625 klass->mybrush_changed = NULL;
626 klass->pattern_changed = NULL;
627 klass->gradient_changed = NULL;
628 klass->palette_changed = NULL;
629 klass->font_changed = NULL;
630 klass->tool_preset_changed = NULL;
631 klass->buffer_changed = NULL;
632 klass->imagefile_changed = NULL;
633 klass->template_changed = NULL;
634 klass->prop_name_changed = NULL;
635
636 gimp_context_prop_types[GIMP_CONTEXT_PROP_IMAGE] = GIMP_TYPE_IMAGE;
637 gimp_context_prop_types[GIMP_CONTEXT_PROP_TOOL] = GIMP_TYPE_TOOL_INFO;
638 gimp_context_prop_types[GIMP_CONTEXT_PROP_PAINT_INFO] = GIMP_TYPE_PAINT_INFO;
639 gimp_context_prop_types[GIMP_CONTEXT_PROP_BRUSH] = GIMP_TYPE_BRUSH;
640 gimp_context_prop_types[GIMP_CONTEXT_PROP_DYNAMICS] = GIMP_TYPE_DYNAMICS;
641 gimp_context_prop_types[GIMP_CONTEXT_PROP_MYBRUSH] = GIMP_TYPE_MYBRUSH;
642 gimp_context_prop_types[GIMP_CONTEXT_PROP_PATTERN] = GIMP_TYPE_PATTERN;
643 gimp_context_prop_types[GIMP_CONTEXT_PROP_GRADIENT] = GIMP_TYPE_GRADIENT;
644 gimp_context_prop_types[GIMP_CONTEXT_PROP_PALETTE] = GIMP_TYPE_PALETTE;
645 gimp_context_prop_types[GIMP_CONTEXT_PROP_FONT] = GIMP_TYPE_FONT;
646 gimp_context_prop_types[GIMP_CONTEXT_PROP_TOOL_PRESET] = GIMP_TYPE_TOOL_PRESET;
647 gimp_context_prop_types[GIMP_CONTEXT_PROP_BUFFER] = GIMP_TYPE_BUFFER;
648 gimp_context_prop_types[GIMP_CONTEXT_PROP_IMAGEFILE] = GIMP_TYPE_IMAGEFILE;
649 gimp_context_prop_types[GIMP_CONTEXT_PROP_TEMPLATE] = GIMP_TYPE_TEMPLATE;
650
651 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_GIMP,
652 g_param_spec_object ("gimp",
653 NULL, NULL,
654 GIMP_TYPE_GIMP,
655 GIMP_PARAM_READWRITE |
656 G_PARAM_CONSTRUCT_ONLY));
657
658 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_IMAGE,
659 g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_IMAGE],
660 NULL, NULL,
661 GIMP_TYPE_IMAGE,
662 GIMP_PARAM_READWRITE));
663
664 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_DISPLAY,
665 g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_DISPLAY],
666 NULL, NULL,
667 GIMP_TYPE_OBJECT,
668 GIMP_PARAM_READWRITE));
669
670 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_TOOL,
671 gimp_context_prop_names[GIMP_CONTEXT_PROP_TOOL],
672 NULL, NULL,
673 GIMP_TYPE_TOOL_INFO,
674 GIMP_PARAM_STATIC_STRINGS);
675
676 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PAINT_INFO,
677 gimp_context_prop_names[GIMP_CONTEXT_PROP_PAINT_INFO],
678 NULL, NULL,
679 GIMP_TYPE_PAINT_INFO,
680 GIMP_PARAM_STATIC_STRINGS);
681
682 GIMP_CONFIG_PROP_RGB (object_class, GIMP_CONTEXT_PROP_FOREGROUND,
683 gimp_context_prop_names[GIMP_CONTEXT_PROP_FOREGROUND],
684 _("Foreground"),
685 _("Foreground color"),
686 FALSE, &black,
687 GIMP_PARAM_STATIC_STRINGS);
688
689 GIMP_CONFIG_PROP_RGB (object_class, GIMP_CONTEXT_PROP_BACKGROUND,
690 gimp_context_prop_names[GIMP_CONTEXT_PROP_BACKGROUND],
691 _("Background"),
692 _("Background color"),
693 FALSE, &white,
694 GIMP_PARAM_STATIC_STRINGS);
695
696 GIMP_CONFIG_PROP_DOUBLE (object_class, GIMP_CONTEXT_PROP_OPACITY,
697 gimp_context_prop_names[GIMP_CONTEXT_PROP_OPACITY],
698 _("Opacity"),
699 _("Opacity"),
700 GIMP_OPACITY_TRANSPARENT,
701 GIMP_OPACITY_OPAQUE,
702 GIMP_OPACITY_OPAQUE,
703 GIMP_PARAM_STATIC_STRINGS);
704
705 GIMP_CONFIG_PROP_ENUM (object_class, GIMP_CONTEXT_PROP_PAINT_MODE,
706 gimp_context_prop_names[GIMP_CONTEXT_PROP_PAINT_MODE],
707 _("Paint Mode"),
708 _("Paint Mode"),
709 GIMP_TYPE_LAYER_MODE,
710 GIMP_LAYER_MODE_NORMAL,
711 GIMP_PARAM_STATIC_STRINGS);
712
713 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_BRUSH,
714 gimp_context_prop_names[GIMP_CONTEXT_PROP_BRUSH],
715 _("Brush"),
716 _("Brush"),
717 GIMP_TYPE_BRUSH,
718 GIMP_PARAM_STATIC_STRINGS);
719
720 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_DYNAMICS,
721 gimp_context_prop_names[GIMP_CONTEXT_PROP_DYNAMICS],
722 _("Dynamics"),
723 _("Paint dynamics"),
724 GIMP_TYPE_DYNAMICS,
725 GIMP_PARAM_STATIC_STRINGS);
726
727 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_MYBRUSH,
728 gimp_context_prop_names[GIMP_CONTEXT_PROP_MYBRUSH],
729 _("MyPaint Brush"),
730 _("MyPaint Brush"),
731 GIMP_TYPE_MYBRUSH,
732 GIMP_PARAM_STATIC_STRINGS);
733
734 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PATTERN,
735 gimp_context_prop_names[GIMP_CONTEXT_PROP_PATTERN],
736 _("Pattern"),
737 _("Pattern"),
738 GIMP_TYPE_PATTERN,
739 GIMP_PARAM_STATIC_STRINGS);
740
741 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_GRADIENT,
742 gimp_context_prop_names[GIMP_CONTEXT_PROP_GRADIENT],
743 _("Gradient"),
744 _("Gradient"),
745 GIMP_TYPE_GRADIENT,
746 GIMP_PARAM_STATIC_STRINGS);
747
748 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_PALETTE,
749 gimp_context_prop_names[GIMP_CONTEXT_PROP_PALETTE],
750 _("Palette"),
751 _("Palette"),
752 GIMP_TYPE_PALETTE,
753 GIMP_PARAM_STATIC_STRINGS);
754
755 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_FONT,
756 gimp_context_prop_names[GIMP_CONTEXT_PROP_FONT],
757 _("Font"),
758 _("Font"),
759 GIMP_TYPE_FONT,
760 GIMP_PARAM_STATIC_STRINGS);
761
762 GIMP_CONFIG_PROP_OBJECT (object_class, GIMP_CONTEXT_PROP_TOOL_PRESET,
763 gimp_context_prop_names[GIMP_CONTEXT_PROP_TOOL_PRESET],
764 _("Tool Preset"),
765 _("Tool Preset"),
766 GIMP_TYPE_TOOL_PRESET,
767 GIMP_PARAM_STATIC_STRINGS);
768
769 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_BUFFER,
770 g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_BUFFER],
771 NULL, NULL,
772 GIMP_TYPE_BUFFER,
773 GIMP_PARAM_READWRITE));
774
775 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_IMAGEFILE,
776 g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_IMAGEFILE],
777 NULL, NULL,
778 GIMP_TYPE_IMAGEFILE,
779 GIMP_PARAM_READWRITE));
780
781 g_object_class_install_property (object_class, GIMP_CONTEXT_PROP_TEMPLATE,
782 g_param_spec_object (gimp_context_prop_names[GIMP_CONTEXT_PROP_TEMPLATE],
783 NULL, NULL,
784 GIMP_TYPE_TEMPLATE,
785 GIMP_PARAM_READWRITE));
786 }
787
788 static void
gimp_context_init(GimpContext * context)789 gimp_context_init (GimpContext *context)
790 {
791 context->gimp = NULL;
792
793 context->parent = NULL;
794
795 context->defined_props = GIMP_CONTEXT_PROP_MASK_ALL;
796 context->serialize_props = GIMP_CONTEXT_PROP_MASK_ALL;
797
798 context->image = NULL;
799 context->display = NULL;
800
801 context->tool_info = NULL;
802 context->tool_name = NULL;
803
804 context->paint_info = NULL;
805 context->paint_name = NULL;
806
807 context->brush = NULL;
808 context->brush_name = NULL;
809
810 context->dynamics = NULL;
811 context->dynamics_name = NULL;
812
813 context->mybrush = NULL;
814 context->mybrush_name = NULL;
815
816 context->pattern = NULL;
817 context->pattern_name = NULL;
818
819 context->gradient = NULL;
820 context->gradient_name = NULL;
821
822 context->palette = NULL;
823 context->palette_name = NULL;
824
825 context->font = NULL;
826 context->font_name = NULL;
827
828 context->tool_preset = NULL;
829 context->tool_preset_name = NULL;
830
831 context->buffer = NULL;
832 context->buffer_name = NULL;
833
834 context->imagefile = NULL;
835 context->imagefile_name = NULL;
836
837 context->template = NULL;
838 context->template_name = NULL;
839 }
840
841 static void
gimp_context_config_iface_init(GimpConfigInterface * iface)842 gimp_context_config_iface_init (GimpConfigInterface *iface)
843 {
844 parent_config_iface = g_type_interface_peek_parent (iface);
845
846 if (! parent_config_iface)
847 parent_config_iface = g_type_default_interface_peek (GIMP_TYPE_CONFIG);
848
849 iface->serialize = gimp_context_serialize;
850 iface->deserialize = gimp_context_deserialize;
851 iface->serialize_property = gimp_context_serialize_property;
852 iface->deserialize_property = gimp_context_deserialize_property;
853 iface->duplicate = gimp_context_duplicate;
854 iface->copy = gimp_context_copy;
855 }
856
857 static void
gimp_context_constructed(GObject * object)858 gimp_context_constructed (GObject *object)
859 {
860 Gimp *gimp;
861 GimpContainer *container;
862
863 G_OBJECT_CLASS (parent_class)->constructed (object);
864
865 gimp = GIMP_CONTEXT (object)->gimp;
866
867 gimp_assert (GIMP_IS_GIMP (gimp));
868
869 gimp->context_list = g_list_prepend (gimp->context_list, object);
870
871 g_signal_connect_object (gimp->images, "remove",
872 G_CALLBACK (gimp_context_image_removed),
873 object, 0);
874 g_signal_connect_object (gimp->displays, "remove",
875 G_CALLBACK (gimp_context_display_removed),
876 object, 0);
877
878 g_signal_connect_object (gimp->tool_info_list, "remove",
879 G_CALLBACK (gimp_context_tool_removed),
880 object, 0);
881 g_signal_connect_object (gimp->tool_info_list, "thaw",
882 G_CALLBACK (gimp_context_tool_list_thaw),
883 object, 0);
884
885 g_signal_connect_object (gimp->paint_info_list, "remove",
886 G_CALLBACK (gimp_context_paint_info_removed),
887 object, 0);
888 g_signal_connect_object (gimp->paint_info_list, "thaw",
889 G_CALLBACK (gimp_context_paint_info_list_thaw),
890 object, 0);
891
892 container = gimp_data_factory_get_container (gimp->brush_factory);
893 g_signal_connect_object (container, "remove",
894 G_CALLBACK (gimp_context_brush_removed),
895 object, 0);
896 g_signal_connect_object (container, "thaw",
897 G_CALLBACK (gimp_context_brush_list_thaw),
898 object, 0);
899
900 container = gimp_data_factory_get_container (gimp->dynamics_factory);
901 g_signal_connect_object (container, "remove",
902 G_CALLBACK (gimp_context_dynamics_removed),
903 object, 0);
904 g_signal_connect_object (container, "thaw",
905 G_CALLBACK (gimp_context_dynamics_list_thaw),
906 object, 0);
907
908 container = gimp_data_factory_get_container (gimp->mybrush_factory);
909 g_signal_connect_object (container, "remove",
910 G_CALLBACK (gimp_context_mybrush_removed),
911 object, 0);
912 g_signal_connect_object (container, "thaw",
913 G_CALLBACK (gimp_context_mybrush_list_thaw),
914 object, 0);
915
916 container = gimp_data_factory_get_container (gimp->pattern_factory);
917 g_signal_connect_object (container, "remove",
918 G_CALLBACK (gimp_context_pattern_removed),
919 object, 0);
920 g_signal_connect_object (container, "thaw",
921 G_CALLBACK (gimp_context_pattern_list_thaw),
922 object, 0);
923
924 container = gimp_data_factory_get_container (gimp->gradient_factory);
925 g_signal_connect_object (container, "remove",
926 G_CALLBACK (gimp_context_gradient_removed),
927 object, 0);
928 g_signal_connect_object (container, "thaw",
929 G_CALLBACK (gimp_context_gradient_list_thaw),
930 object, 0);
931
932 container = gimp_data_factory_get_container (gimp->palette_factory);
933 g_signal_connect_object (container, "remove",
934 G_CALLBACK (gimp_context_palette_removed),
935 object, 0);
936 g_signal_connect_object (container, "thaw",
937 G_CALLBACK (gimp_context_palette_list_thaw),
938 object, 0);
939
940 container = gimp_data_factory_get_container (gimp->font_factory);
941 g_signal_connect_object (container, "remove",
942 G_CALLBACK (gimp_context_font_removed),
943 object, 0);
944 g_signal_connect_object (container, "thaw",
945 G_CALLBACK (gimp_context_font_list_thaw),
946 object, 0);
947
948 container = gimp_data_factory_get_container (gimp->tool_preset_factory);
949 g_signal_connect_object (container, "remove",
950 G_CALLBACK (gimp_context_tool_preset_removed),
951 object, 0);
952 g_signal_connect_object (container, "thaw",
953 G_CALLBACK (gimp_context_tool_preset_list_thaw),
954 object, 0);
955
956 g_signal_connect_object (gimp->named_buffers, "remove",
957 G_CALLBACK (gimp_context_buffer_removed),
958 object, 0);
959 g_signal_connect_object (gimp->named_buffers, "thaw",
960 G_CALLBACK (gimp_context_buffer_list_thaw),
961 object, 0);
962
963 g_signal_connect_object (gimp->documents, "remove",
964 G_CALLBACK (gimp_context_imagefile_removed),
965 object, 0);
966 g_signal_connect_object (gimp->documents, "thaw",
967 G_CALLBACK (gimp_context_imagefile_list_thaw),
968 object, 0);
969
970 g_signal_connect_object (gimp->templates, "remove",
971 G_CALLBACK (gimp_context_template_removed),
972 object, 0);
973 g_signal_connect_object (gimp->templates, "thaw",
974 G_CALLBACK (gimp_context_template_list_thaw),
975 object, 0);
976
977 gimp_context_set_paint_info (GIMP_CONTEXT (object),
978 gimp_paint_info_get_standard (gimp));
979 }
980
981 static void
gimp_context_dispose(GObject * object)982 gimp_context_dispose (GObject *object)
983 {
984 GimpContext *context = GIMP_CONTEXT (object);
985
986 gimp_context_set_parent (context, NULL);
987
988 if (context->gimp)
989 {
990 context->gimp->context_list = g_list_remove (context->gimp->context_list,
991 context);
992 context->gimp = NULL;
993 }
994
995 g_clear_object (&context->tool_info);
996 g_clear_object (&context->paint_info);
997 g_clear_object (&context->brush);
998 g_clear_object (&context->dynamics);
999 g_clear_object (&context->mybrush);
1000 g_clear_object (&context->pattern);
1001 g_clear_object (&context->gradient);
1002 g_clear_object (&context->palette);
1003 g_clear_object (&context->font);
1004 g_clear_object (&context->tool_preset);
1005 g_clear_object (&context->buffer);
1006 g_clear_object (&context->imagefile);
1007 g_clear_object (&context->template);
1008
1009 G_OBJECT_CLASS (parent_class)->dispose (object);
1010 }
1011
1012 static void
gimp_context_finalize(GObject * object)1013 gimp_context_finalize (GObject *object)
1014 {
1015 GimpContext *context = GIMP_CONTEXT (object);
1016
1017 context->parent = NULL;
1018 context->image = NULL;
1019 context->display = NULL;
1020
1021 g_clear_pointer (&context->tool_name, g_free);
1022 g_clear_pointer (&context->paint_name, g_free);
1023 g_clear_pointer (&context->brush_name, g_free);
1024 g_clear_pointer (&context->dynamics_name, g_free);
1025 g_clear_pointer (&context->mybrush_name, g_free);
1026 g_clear_pointer (&context->pattern_name, g_free);
1027 g_clear_pointer (&context->gradient_name, g_free);
1028 g_clear_pointer (&context->palette_name, g_free);
1029 g_clear_pointer (&context->font_name, g_free);
1030 g_clear_pointer (&context->tool_preset_name, g_free);
1031 g_clear_pointer (&context->buffer_name, g_free);
1032 g_clear_pointer (&context->imagefile_name, g_free);
1033 g_clear_pointer (&context->template_name, g_free);
1034
1035 G_OBJECT_CLASS (parent_class)->finalize (object);
1036 }
1037
1038 static void
gimp_context_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)1039 gimp_context_set_property (GObject *object,
1040 guint property_id,
1041 const GValue *value,
1042 GParamSpec *pspec)
1043 {
1044 GimpContext *context = GIMP_CONTEXT (object);
1045
1046 switch (property_id)
1047 {
1048 case GIMP_CONTEXT_PROP_GIMP:
1049 context->gimp = g_value_get_object (value);
1050 break;
1051 case GIMP_CONTEXT_PROP_IMAGE:
1052 gimp_context_set_image (context, g_value_get_object (value));
1053 break;
1054 case GIMP_CONTEXT_PROP_DISPLAY:
1055 gimp_context_set_display (context, g_value_get_object (value));
1056 break;
1057 case GIMP_CONTEXT_PROP_TOOL:
1058 gimp_context_set_tool (context, g_value_get_object (value));
1059 break;
1060 case GIMP_CONTEXT_PROP_PAINT_INFO:
1061 gimp_context_set_paint_info (context, g_value_get_object (value));
1062 break;
1063 case GIMP_CONTEXT_PROP_FOREGROUND:
1064 gimp_context_set_foreground (context, g_value_get_boxed (value));
1065 break;
1066 case GIMP_CONTEXT_PROP_BACKGROUND:
1067 gimp_context_set_background (context, g_value_get_boxed (value));
1068 break;
1069 case GIMP_CONTEXT_PROP_OPACITY:
1070 gimp_context_set_opacity (context, g_value_get_double (value));
1071 break;
1072 case GIMP_CONTEXT_PROP_PAINT_MODE:
1073 gimp_context_set_paint_mode (context, g_value_get_enum (value));
1074 break;
1075 case GIMP_CONTEXT_PROP_BRUSH:
1076 gimp_context_set_brush (context, g_value_get_object (value));
1077 break;
1078 case GIMP_CONTEXT_PROP_DYNAMICS:
1079 gimp_context_set_dynamics (context, g_value_get_object (value));
1080 break;
1081 case GIMP_CONTEXT_PROP_MYBRUSH:
1082 gimp_context_set_mybrush (context, g_value_get_object (value));
1083 break;
1084 case GIMP_CONTEXT_PROP_PATTERN:
1085 gimp_context_set_pattern (context, g_value_get_object (value));
1086 break;
1087 case GIMP_CONTEXT_PROP_GRADIENT:
1088 gimp_context_set_gradient (context, g_value_get_object (value));
1089 break;
1090 case GIMP_CONTEXT_PROP_PALETTE:
1091 gimp_context_set_palette (context, g_value_get_object (value));
1092 break;
1093 case GIMP_CONTEXT_PROP_FONT:
1094 gimp_context_set_font (context, g_value_get_object (value));
1095 break;
1096 case GIMP_CONTEXT_PROP_TOOL_PRESET:
1097 gimp_context_set_tool_preset (context, g_value_get_object (value));
1098 break;
1099 case GIMP_CONTEXT_PROP_BUFFER:
1100 gimp_context_set_buffer (context, g_value_get_object (value));
1101 break;
1102 case GIMP_CONTEXT_PROP_IMAGEFILE:
1103 gimp_context_set_imagefile (context, g_value_get_object (value));
1104 break;
1105 case GIMP_CONTEXT_PROP_TEMPLATE:
1106 gimp_context_set_template (context, g_value_get_object (value));
1107 break;
1108 default:
1109 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1110 break;
1111 }
1112 }
1113
1114 static void
gimp_context_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)1115 gimp_context_get_property (GObject *object,
1116 guint property_id,
1117 GValue *value,
1118 GParamSpec *pspec)
1119 {
1120 GimpContext *context = GIMP_CONTEXT (object);
1121
1122 switch (property_id)
1123 {
1124 case GIMP_CONTEXT_PROP_GIMP:
1125 g_value_set_object (value, context->gimp);
1126 break;
1127 case GIMP_CONTEXT_PROP_IMAGE:
1128 g_value_set_object (value, gimp_context_get_image (context));
1129 break;
1130 case GIMP_CONTEXT_PROP_DISPLAY:
1131 g_value_set_object (value, gimp_context_get_display (context));
1132 break;
1133 case GIMP_CONTEXT_PROP_TOOL:
1134 g_value_set_object (value, gimp_context_get_tool (context));
1135 break;
1136 case GIMP_CONTEXT_PROP_PAINT_INFO:
1137 g_value_set_object (value, gimp_context_get_paint_info (context));
1138 break;
1139 case GIMP_CONTEXT_PROP_FOREGROUND:
1140 {
1141 GimpRGB color;
1142
1143 gimp_context_get_foreground (context, &color);
1144 g_value_set_boxed (value, &color);
1145 }
1146 break;
1147 case GIMP_CONTEXT_PROP_BACKGROUND:
1148 {
1149 GimpRGB color;
1150
1151 gimp_context_get_background (context, &color);
1152 g_value_set_boxed (value, &color);
1153 }
1154 break;
1155 case GIMP_CONTEXT_PROP_OPACITY:
1156 g_value_set_double (value, gimp_context_get_opacity (context));
1157 break;
1158 case GIMP_CONTEXT_PROP_PAINT_MODE:
1159 g_value_set_enum (value, gimp_context_get_paint_mode (context));
1160 break;
1161 case GIMP_CONTEXT_PROP_BRUSH:
1162 g_value_set_object (value, gimp_context_get_brush (context));
1163 break;
1164 case GIMP_CONTEXT_PROP_DYNAMICS:
1165 g_value_set_object (value, gimp_context_get_dynamics (context));
1166 break;
1167 case GIMP_CONTEXT_PROP_MYBRUSH:
1168 g_value_set_object (value, gimp_context_get_mybrush (context));
1169 break;
1170 case GIMP_CONTEXT_PROP_PATTERN:
1171 g_value_set_object (value, gimp_context_get_pattern (context));
1172 break;
1173 case GIMP_CONTEXT_PROP_GRADIENT:
1174 g_value_set_object (value, gimp_context_get_gradient (context));
1175 break;
1176 case GIMP_CONTEXT_PROP_PALETTE:
1177 g_value_set_object (value, gimp_context_get_palette (context));
1178 break;
1179 case GIMP_CONTEXT_PROP_FONT:
1180 g_value_set_object (value, gimp_context_get_font (context));
1181 break;
1182 case GIMP_CONTEXT_PROP_TOOL_PRESET:
1183 g_value_set_object (value, gimp_context_get_tool_preset (context));
1184 break;
1185 case GIMP_CONTEXT_PROP_BUFFER:
1186 g_value_set_object (value, gimp_context_get_buffer (context));
1187 break;
1188 case GIMP_CONTEXT_PROP_IMAGEFILE:
1189 g_value_set_object (value, gimp_context_get_imagefile (context));
1190 break;
1191 case GIMP_CONTEXT_PROP_TEMPLATE:
1192 g_value_set_object (value, gimp_context_get_template (context));
1193 break;
1194 default:
1195 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1196 break;
1197 }
1198 }
1199
1200 static gint64
gimp_context_get_memsize(GimpObject * object,gint64 * gui_size)1201 gimp_context_get_memsize (GimpObject *object,
1202 gint64 *gui_size)
1203 {
1204 GimpContext *context = GIMP_CONTEXT (object);
1205 gint64 memsize = 0;
1206
1207 memsize += gimp_string_get_memsize (context->tool_name);
1208 memsize += gimp_string_get_memsize (context->paint_name);
1209 memsize += gimp_string_get_memsize (context->brush_name);
1210 memsize += gimp_string_get_memsize (context->dynamics_name);
1211 memsize += gimp_string_get_memsize (context->mybrush_name);
1212 memsize += gimp_string_get_memsize (context->pattern_name);
1213 memsize += gimp_string_get_memsize (context->palette_name);
1214 memsize += gimp_string_get_memsize (context->font_name);
1215 memsize += gimp_string_get_memsize (context->tool_preset_name);
1216 memsize += gimp_string_get_memsize (context->buffer_name);
1217 memsize += gimp_string_get_memsize (context->imagefile_name);
1218 memsize += gimp_string_get_memsize (context->template_name);
1219
1220 return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
1221 gui_size);
1222 }
1223
1224 static gboolean
gimp_context_serialize(GimpConfig * config,GimpConfigWriter * writer,gpointer data)1225 gimp_context_serialize (GimpConfig *config,
1226 GimpConfigWriter *writer,
1227 gpointer data)
1228 {
1229 return gimp_config_serialize_changed_properties (config, writer);
1230 }
1231
1232 static gboolean
gimp_context_deserialize(GimpConfig * config,GScanner * scanner,gint nest_level,gpointer data)1233 gimp_context_deserialize (GimpConfig *config,
1234 GScanner *scanner,
1235 gint nest_level,
1236 gpointer data)
1237 {
1238 GimpContext *context = GIMP_CONTEXT (config);
1239 GimpLayerMode old_paint_mode = context->paint_mode;
1240 gboolean success;
1241
1242 success = gimp_config_deserialize_properties (config, scanner, nest_level);
1243
1244 if (context->paint_mode != old_paint_mode)
1245 {
1246 if (context->paint_mode == GIMP_LAYER_MODE_OVERLAY_LEGACY)
1247 g_object_set (context,
1248 "paint-mode", GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
1249 NULL);
1250 }
1251
1252 return success;
1253 }
1254
1255 static gboolean
gimp_context_serialize_property(GimpConfig * config,guint property_id,const GValue * value,GParamSpec * pspec,GimpConfigWriter * writer)1256 gimp_context_serialize_property (GimpConfig *config,
1257 guint property_id,
1258 const GValue *value,
1259 GParamSpec *pspec,
1260 GimpConfigWriter *writer)
1261 {
1262 GimpContext *context = GIMP_CONTEXT (config);
1263 GimpObject *serialize_obj;
1264
1265 /* serialize nothing if the property is not in serialize_props */
1266 if (! ((1 << property_id) & context->serialize_props))
1267 return TRUE;
1268
1269 switch (property_id)
1270 {
1271 case GIMP_CONTEXT_PROP_TOOL:
1272 case GIMP_CONTEXT_PROP_PAINT_INFO:
1273 case GIMP_CONTEXT_PROP_BRUSH:
1274 case GIMP_CONTEXT_PROP_DYNAMICS:
1275 case GIMP_CONTEXT_PROP_MYBRUSH:
1276 case GIMP_CONTEXT_PROP_PATTERN:
1277 case GIMP_CONTEXT_PROP_GRADIENT:
1278 case GIMP_CONTEXT_PROP_PALETTE:
1279 case GIMP_CONTEXT_PROP_FONT:
1280 case GIMP_CONTEXT_PROP_TOOL_PRESET:
1281 serialize_obj = g_value_get_object (value);
1282 break;
1283
1284 default:
1285 return FALSE;
1286 }
1287
1288 gimp_config_writer_open (writer, pspec->name);
1289
1290 if (serialize_obj)
1291 gimp_config_writer_string (writer, gimp_object_get_name (serialize_obj));
1292 else
1293 gimp_config_writer_print (writer, "NULL", 4);
1294
1295 gimp_config_writer_close (writer);
1296
1297 return TRUE;
1298 }
1299
1300 static gboolean
gimp_context_deserialize_property(GimpConfig * object,guint property_id,GValue * value,GParamSpec * pspec,GScanner * scanner,GTokenType * expected)1301 gimp_context_deserialize_property (GimpConfig *object,
1302 guint property_id,
1303 GValue *value,
1304 GParamSpec *pspec,
1305 GScanner *scanner,
1306 GTokenType *expected)
1307 {
1308 GimpContext *context = GIMP_CONTEXT (object);
1309 GimpContainer *container;
1310 gpointer standard;
1311 gchar **name_loc;
1312 gchar *object_name;
1313
1314 switch (property_id)
1315 {
1316 case GIMP_CONTEXT_PROP_TOOL:
1317 container = context->gimp->tool_info_list;
1318 standard = gimp_tool_info_get_standard (context->gimp);
1319 name_loc = &context->tool_name;
1320 break;
1321
1322 case GIMP_CONTEXT_PROP_PAINT_INFO:
1323 container = context->gimp->paint_info_list;
1324 standard = gimp_paint_info_get_standard (context->gimp);
1325 name_loc = &context->paint_name;
1326 break;
1327
1328 case GIMP_CONTEXT_PROP_BRUSH:
1329 container = gimp_data_factory_get_container (context->gimp->brush_factory);
1330 standard = gimp_brush_get_standard (context);
1331 name_loc = &context->brush_name;
1332 break;
1333
1334 case GIMP_CONTEXT_PROP_DYNAMICS:
1335 container = gimp_data_factory_get_container (context->gimp->dynamics_factory);
1336 standard = gimp_dynamics_get_standard (context);
1337 name_loc = &context->dynamics_name;
1338 break;
1339
1340 case GIMP_CONTEXT_PROP_MYBRUSH:
1341 container = gimp_data_factory_get_container (context->gimp->mybrush_factory);
1342 standard = gimp_mybrush_get_standard (context);
1343 name_loc = &context->mybrush_name;
1344 break;
1345
1346 case GIMP_CONTEXT_PROP_PATTERN:
1347 container = gimp_data_factory_get_container (context->gimp->pattern_factory);
1348 standard = gimp_pattern_get_standard (context);
1349 name_loc = &context->pattern_name;
1350 break;
1351
1352 case GIMP_CONTEXT_PROP_GRADIENT:
1353 container = gimp_data_factory_get_container (context->gimp->gradient_factory);
1354 standard = gimp_gradient_get_standard (context);
1355 name_loc = &context->gradient_name;
1356 break;
1357
1358 case GIMP_CONTEXT_PROP_PALETTE:
1359 container = gimp_data_factory_get_container (context->gimp->palette_factory);
1360 standard = gimp_palette_get_standard (context);
1361 name_loc = &context->palette_name;
1362 break;
1363
1364 case GIMP_CONTEXT_PROP_FONT:
1365 container = gimp_data_factory_get_container (context->gimp->font_factory);
1366 standard = gimp_font_get_standard ();
1367 name_loc = &context->font_name;
1368 break;
1369
1370 case GIMP_CONTEXT_PROP_TOOL_PRESET:
1371 container = gimp_data_factory_get_container (context->gimp->tool_preset_factory);
1372 standard = NULL;
1373 name_loc = &context->tool_preset_name;
1374 break;
1375
1376 default:
1377 return FALSE;
1378 }
1379
1380 if (gimp_scanner_parse_identifier (scanner, "NULL"))
1381 {
1382 g_value_set_object (value, NULL);
1383 }
1384 else if (gimp_scanner_parse_string (scanner, &object_name))
1385 {
1386 GimpObject *deserialize_obj;
1387
1388 if (! object_name)
1389 object_name = g_strdup ("");
1390
1391 deserialize_obj = gimp_container_get_child_by_name (container,
1392 object_name);
1393
1394 if (! deserialize_obj)
1395 {
1396 g_value_set_object (value, standard);
1397
1398 g_free (*name_loc);
1399 *name_loc = g_strdup (object_name);
1400 }
1401 else
1402 {
1403 g_value_set_object (value, deserialize_obj);
1404 }
1405
1406 g_free (object_name);
1407 }
1408 else
1409 {
1410 *expected = G_TOKEN_STRING;
1411 }
1412
1413 return TRUE;
1414 }
1415
1416 static GimpConfig *
gimp_context_duplicate(GimpConfig * config)1417 gimp_context_duplicate (GimpConfig *config)
1418 {
1419 GimpContext *context = GIMP_CONTEXT (config);
1420 GimpContext *new;
1421
1422 new = GIMP_CONTEXT (parent_config_iface->duplicate (config));
1423
1424 COPY_NAME (context, new, tool_name);
1425 COPY_NAME (context, new, paint_name);
1426 COPY_NAME (context, new, brush_name);
1427 COPY_NAME (context, new, dynamics_name);
1428 COPY_NAME (context, new, mybrush_name);
1429 COPY_NAME (context, new, pattern_name);
1430 COPY_NAME (context, new, gradient_name);
1431 COPY_NAME (context, new, palette_name);
1432 COPY_NAME (context, new, font_name);
1433 COPY_NAME (context, new, tool_preset_name);
1434 COPY_NAME (context, new, buffer_name);
1435 COPY_NAME (context, new, imagefile_name);
1436 COPY_NAME (context, new, template_name);
1437
1438 return GIMP_CONFIG (new);
1439 }
1440
1441 static gboolean
gimp_context_copy(GimpConfig * src,GimpConfig * dest,GParamFlags flags)1442 gimp_context_copy (GimpConfig *src,
1443 GimpConfig *dest,
1444 GParamFlags flags)
1445 {
1446 GimpContext *src_context = GIMP_CONTEXT (src);
1447 GimpContext *dest_context = GIMP_CONTEXT (dest);
1448 gboolean success = parent_config_iface->copy (src, dest, flags);
1449
1450 COPY_NAME (src_context, dest_context, tool_name);
1451 COPY_NAME (src_context, dest_context, paint_name);
1452 COPY_NAME (src_context, dest_context, brush_name);
1453 COPY_NAME (src_context, dest_context, dynamics_name);
1454 COPY_NAME (src_context, dest_context, mybrush_name);
1455 COPY_NAME (src_context, dest_context, pattern_name);
1456 COPY_NAME (src_context, dest_context, gradient_name);
1457 COPY_NAME (src_context, dest_context, palette_name);
1458 COPY_NAME (src_context, dest_context, font_name);
1459 COPY_NAME (src_context, dest_context, tool_preset_name);
1460 COPY_NAME (src_context, dest_context, buffer_name);
1461 COPY_NAME (src_context, dest_context, imagefile_name);
1462 COPY_NAME (src_context, dest_context, template_name);
1463
1464 return success;
1465 }
1466
1467
1468 /*****************************************************************************/
1469 /* public functions ********************************************************/
1470
1471 GimpContext *
gimp_context_new(Gimp * gimp,const gchar * name,GimpContext * template)1472 gimp_context_new (Gimp *gimp,
1473 const gchar *name,
1474 GimpContext *template)
1475 {
1476 GimpContext *context;
1477
1478 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
1479 g_return_val_if_fail (name != NULL, NULL);
1480 g_return_val_if_fail (template == NULL || GIMP_IS_CONTEXT (template), NULL);
1481
1482 context = g_object_new (GIMP_TYPE_CONTEXT,
1483 "name", name,
1484 "gimp", gimp,
1485 NULL);
1486
1487 if (template)
1488 {
1489 context->defined_props = template->defined_props;
1490
1491 gimp_context_copy_properties (template, context,
1492 GIMP_CONTEXT_PROP_MASK_ALL);
1493 }
1494
1495 return context;
1496 }
1497
1498 GimpContext *
gimp_context_get_parent(GimpContext * context)1499 gimp_context_get_parent (GimpContext *context)
1500 {
1501 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
1502
1503 return context->parent;
1504 }
1505
1506 static void
gimp_context_parent_notify(GimpContext * parent,GParamSpec * pspec,GimpContext * context)1507 gimp_context_parent_notify (GimpContext *parent,
1508 GParamSpec *pspec,
1509 GimpContext *context)
1510 {
1511 if (pspec->owner_type == GIMP_TYPE_CONTEXT)
1512 {
1513 GimpContextPropType prop = pspec->param_id;
1514
1515 /* copy from parent if the changed property is undefined;
1516 * ignore properties that are not context properties, for
1517 * example notifications on the context's "gimp" property
1518 */
1519 if ((prop >= GIMP_CONTEXT_PROP_FIRST) &&
1520 (prop <= GIMP_CONTEXT_PROP_LAST) &&
1521 ! ((1 << prop) & context->defined_props))
1522 {
1523 gimp_context_copy_property (parent, context, prop);
1524 }
1525 }
1526 }
1527
1528 void
gimp_context_set_parent(GimpContext * context,GimpContext * parent)1529 gimp_context_set_parent (GimpContext *context,
1530 GimpContext *parent)
1531 {
1532 g_return_if_fail (GIMP_IS_CONTEXT (context));
1533 g_return_if_fail (parent == NULL || GIMP_IS_CONTEXT (parent));
1534 g_return_if_fail (parent == NULL || parent->parent != context);
1535 g_return_if_fail (context != parent);
1536
1537 if (context->parent == parent)
1538 return;
1539
1540 if (context->parent)
1541 {
1542 g_signal_handlers_disconnect_by_func (context->parent,
1543 gimp_context_parent_notify,
1544 context);
1545
1546 g_object_remove_weak_pointer (G_OBJECT (context->parent),
1547 (gpointer) &context->parent);
1548 }
1549
1550 context->parent = parent;
1551
1552 if (parent)
1553 {
1554 g_object_add_weak_pointer (G_OBJECT (context->parent),
1555 (gpointer) &context->parent);
1556
1557 /* copy all undefined properties from the new parent */
1558 gimp_context_copy_properties (parent, context,
1559 ~context->defined_props &
1560 GIMP_CONTEXT_PROP_MASK_ALL);
1561
1562 g_signal_connect_object (parent, "notify",
1563 G_CALLBACK (gimp_context_parent_notify),
1564 context,
1565 0);
1566 }
1567 }
1568
1569
1570 /* define / undefinine context properties */
1571
1572 void
gimp_context_define_property(GimpContext * context,GimpContextPropType prop,gboolean defined)1573 gimp_context_define_property (GimpContext *context,
1574 GimpContextPropType prop,
1575 gboolean defined)
1576 {
1577 GimpContextPropMask mask;
1578
1579 g_return_if_fail (GIMP_IS_CONTEXT (context));
1580 g_return_if_fail ((prop >= GIMP_CONTEXT_PROP_FIRST) &&
1581 (prop <= GIMP_CONTEXT_PROP_LAST));
1582
1583 mask = (1 << prop);
1584
1585 if (defined)
1586 {
1587 if (! (context->defined_props & mask))
1588 {
1589 context->defined_props |= mask;
1590 }
1591 }
1592 else
1593 {
1594 if (context->defined_props & mask)
1595 {
1596 context->defined_props &= ~mask;
1597
1598 if (context->parent)
1599 gimp_context_copy_property (context->parent, context, prop);
1600 }
1601 }
1602 }
1603
1604 gboolean
gimp_context_property_defined(GimpContext * context,GimpContextPropType prop)1605 gimp_context_property_defined (GimpContext *context,
1606 GimpContextPropType prop)
1607 {
1608 g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE);
1609
1610 return (context->defined_props & (1 << prop)) ? TRUE : FALSE;
1611 }
1612
1613 void
gimp_context_define_properties(GimpContext * context,GimpContextPropMask prop_mask,gboolean defined)1614 gimp_context_define_properties (GimpContext *context,
1615 GimpContextPropMask prop_mask,
1616 gboolean defined)
1617 {
1618 GimpContextPropType prop;
1619
1620 g_return_if_fail (GIMP_IS_CONTEXT (context));
1621
1622 for (prop = GIMP_CONTEXT_PROP_FIRST; prop <= GIMP_CONTEXT_PROP_LAST; prop++)
1623 if ((1 << prop) & prop_mask)
1624 gimp_context_define_property (context, prop, defined);
1625 }
1626
1627
1628 /* specify which context properties will be serialized */
1629
1630 void
gimp_context_set_serialize_properties(GimpContext * context,GimpContextPropMask props_mask)1631 gimp_context_set_serialize_properties (GimpContext *context,
1632 GimpContextPropMask props_mask)
1633 {
1634 g_return_if_fail (GIMP_IS_CONTEXT (context));
1635
1636 context->serialize_props = props_mask;
1637 }
1638
1639 GimpContextPropMask
gimp_context_get_serialize_properties(GimpContext * context)1640 gimp_context_get_serialize_properties (GimpContext *context)
1641 {
1642 g_return_val_if_fail (GIMP_IS_CONTEXT (context), 0);
1643
1644 return context->serialize_props;
1645 }
1646
1647
1648 /* copying context properties */
1649
1650 void
gimp_context_copy_property(GimpContext * src,GimpContext * dest,GimpContextPropType prop)1651 gimp_context_copy_property (GimpContext *src,
1652 GimpContext *dest,
1653 GimpContextPropType prop)
1654 {
1655 g_return_if_fail (GIMP_IS_CONTEXT (src));
1656 g_return_if_fail (GIMP_IS_CONTEXT (dest));
1657 g_return_if_fail ((prop >= GIMP_CONTEXT_PROP_FIRST) &&
1658 (prop <= GIMP_CONTEXT_PROP_LAST));
1659
1660 switch (prop)
1661 {
1662 case GIMP_CONTEXT_PROP_IMAGE:
1663 gimp_context_real_set_image (dest, src->image);
1664 break;
1665
1666 case GIMP_CONTEXT_PROP_DISPLAY:
1667 gimp_context_real_set_display (dest, src->display);
1668 break;
1669
1670 case GIMP_CONTEXT_PROP_TOOL:
1671 gimp_context_real_set_tool (dest, src->tool_info);
1672 COPY_NAME (src, dest, tool_name);
1673 break;
1674
1675 case GIMP_CONTEXT_PROP_PAINT_INFO:
1676 gimp_context_real_set_paint_info (dest, src->paint_info);
1677 COPY_NAME (src, dest, paint_name);
1678 break;
1679
1680 case GIMP_CONTEXT_PROP_FOREGROUND:
1681 gimp_context_real_set_foreground (dest, &src->foreground);
1682 break;
1683
1684 case GIMP_CONTEXT_PROP_BACKGROUND:
1685 gimp_context_real_set_background (dest, &src->background);
1686 break;
1687
1688 case GIMP_CONTEXT_PROP_OPACITY:
1689 gimp_context_real_set_opacity (dest, src->opacity);
1690 break;
1691
1692 case GIMP_CONTEXT_PROP_PAINT_MODE:
1693 gimp_context_real_set_paint_mode (dest, src->paint_mode);
1694 break;
1695
1696 case GIMP_CONTEXT_PROP_BRUSH:
1697 gimp_context_real_set_brush (dest, src->brush);
1698 COPY_NAME (src, dest, brush_name);
1699 break;
1700
1701 case GIMP_CONTEXT_PROP_DYNAMICS:
1702 gimp_context_real_set_dynamics (dest, src->dynamics);
1703 COPY_NAME (src, dest, dynamics_name);
1704 break;
1705
1706 case GIMP_CONTEXT_PROP_MYBRUSH:
1707 gimp_context_real_set_mybrush (dest, src->mybrush);
1708 COPY_NAME (src, dest, mybrush_name);
1709 break;
1710
1711 case GIMP_CONTEXT_PROP_PATTERN:
1712 gimp_context_real_set_pattern (dest, src->pattern);
1713 COPY_NAME (src, dest, pattern_name);
1714 break;
1715
1716 case GIMP_CONTEXT_PROP_GRADIENT:
1717 gimp_context_real_set_gradient (dest, src->gradient);
1718 COPY_NAME (src, dest, gradient_name);
1719 break;
1720
1721 case GIMP_CONTEXT_PROP_PALETTE:
1722 gimp_context_real_set_palette (dest, src->palette);
1723 COPY_NAME (src, dest, palette_name);
1724 break;
1725
1726 case GIMP_CONTEXT_PROP_FONT:
1727 gimp_context_real_set_font (dest, src->font);
1728 COPY_NAME (src, dest, font_name);
1729 break;
1730
1731 case GIMP_CONTEXT_PROP_TOOL_PRESET:
1732 gimp_context_real_set_tool_preset (dest, src->tool_preset);
1733 COPY_NAME (src, dest, tool_preset_name);
1734 break;
1735
1736 case GIMP_CONTEXT_PROP_BUFFER:
1737 gimp_context_real_set_buffer (dest, src->buffer);
1738 COPY_NAME (src, dest, buffer_name);
1739 break;
1740
1741 case GIMP_CONTEXT_PROP_IMAGEFILE:
1742 gimp_context_real_set_imagefile (dest, src->imagefile);
1743 COPY_NAME (src, dest, imagefile_name);
1744 break;
1745
1746 case GIMP_CONTEXT_PROP_TEMPLATE:
1747 gimp_context_real_set_template (dest, src->template);
1748 COPY_NAME (src, dest, template_name);
1749 break;
1750
1751 default:
1752 break;
1753 }
1754 }
1755
1756 void
gimp_context_copy_properties(GimpContext * src,GimpContext * dest,GimpContextPropMask prop_mask)1757 gimp_context_copy_properties (GimpContext *src,
1758 GimpContext *dest,
1759 GimpContextPropMask prop_mask)
1760 {
1761 GimpContextPropType prop;
1762
1763 g_return_if_fail (GIMP_IS_CONTEXT (src));
1764 g_return_if_fail (GIMP_IS_CONTEXT (dest));
1765
1766 for (prop = GIMP_CONTEXT_PROP_FIRST; prop <= GIMP_CONTEXT_PROP_LAST; prop++)
1767 if ((1 << prop) & prop_mask)
1768 gimp_context_copy_property (src, dest, prop);
1769 }
1770
1771
1772 /* attribute access functions */
1773
1774 /*****************************************************************************/
1775 /* manipulate by GType *****************************************************/
1776
1777 GimpContextPropType
gimp_context_type_to_property(GType type)1778 gimp_context_type_to_property (GType type)
1779 {
1780 GimpContextPropType prop;
1781
1782 for (prop = GIMP_CONTEXT_PROP_FIRST; prop <= GIMP_CONTEXT_PROP_LAST; prop++)
1783 {
1784 if (g_type_is_a (type, gimp_context_prop_types[prop]))
1785 return prop;
1786 }
1787
1788 return -1;
1789 }
1790
1791 const gchar *
gimp_context_type_to_prop_name(GType type)1792 gimp_context_type_to_prop_name (GType type)
1793 {
1794 GimpContextPropType prop;
1795
1796 for (prop = GIMP_CONTEXT_PROP_FIRST; prop <= GIMP_CONTEXT_PROP_LAST; prop++)
1797 {
1798 if (g_type_is_a (type, gimp_context_prop_types[prop]))
1799 return gimp_context_prop_names[prop];
1800 }
1801
1802 return NULL;
1803 }
1804
1805 const gchar *
gimp_context_type_to_signal_name(GType type)1806 gimp_context_type_to_signal_name (GType type)
1807 {
1808 GimpContextPropType prop;
1809
1810 for (prop = GIMP_CONTEXT_PROP_FIRST; prop <= GIMP_CONTEXT_PROP_LAST; prop++)
1811 {
1812 if (g_type_is_a (type, gimp_context_prop_types[prop]))
1813 return g_signal_name (gimp_context_signals[prop]);
1814 }
1815
1816 return NULL;
1817 }
1818
1819 GimpObject *
gimp_context_get_by_type(GimpContext * context,GType type)1820 gimp_context_get_by_type (GimpContext *context,
1821 GType type)
1822 {
1823 GimpContextPropType prop;
1824 GimpObject *object = NULL;
1825
1826 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
1827
1828 prop = gimp_context_type_to_property (type);
1829
1830 g_return_val_if_fail (prop != -1, NULL);
1831
1832 g_object_get (context,
1833 gimp_context_prop_names[prop], &object,
1834 NULL);
1835
1836 /* g_object_get() refs the object, this function however is a getter,
1837 * which usually doesn't ref it's return value
1838 */
1839 if (object)
1840 g_object_unref (object);
1841
1842 return object;
1843 }
1844
1845 void
gimp_context_set_by_type(GimpContext * context,GType type,GimpObject * object)1846 gimp_context_set_by_type (GimpContext *context,
1847 GType type,
1848 GimpObject *object)
1849 {
1850 GimpContextPropType prop;
1851 GParamSpec *pspec;
1852 GValue value = G_VALUE_INIT;
1853
1854 g_return_if_fail (GIMP_IS_CONTEXT (context));
1855 g_return_if_fail (object == NULL || G_IS_OBJECT (object));
1856
1857 prop = gimp_context_type_to_property (type);
1858
1859 g_return_if_fail (prop != -1);
1860
1861 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (context),
1862 gimp_context_prop_names[prop]);
1863
1864 g_return_if_fail (pspec != NULL);
1865
1866 g_value_init (&value, pspec->value_type);
1867 g_value_set_object (&value, object);
1868
1869 /* we use gimp_context_set_property() (which in turn only calls
1870 * gimp_context_set_foo() functions) instead of the much more obvious
1871 * g_object_set(); this avoids g_object_freeze_notify()/thaw_notify()
1872 * around the g_object_set() and makes GimpContext callbacks being
1873 * called in a much more predictable order. See bug #731279.
1874 */
1875 gimp_context_set_property (G_OBJECT (context),
1876 pspec->param_id,
1877 (const GValue *) &value,
1878 pspec);
1879
1880 g_value_unset (&value);
1881 }
1882
1883 void
gimp_context_changed_by_type(GimpContext * context,GType type)1884 gimp_context_changed_by_type (GimpContext *context,
1885 GType type)
1886 {
1887 GimpContextPropType prop;
1888 GimpObject *object;
1889
1890 g_return_if_fail (GIMP_IS_CONTEXT (context));
1891
1892 prop = gimp_context_type_to_property (type);
1893
1894 g_return_if_fail (prop != -1);
1895
1896 object = gimp_context_get_by_type (context, type);
1897
1898 g_signal_emit (context,
1899 gimp_context_signals[prop], 0,
1900 object);
1901 }
1902
1903
1904 /*****************************************************************************/
1905 /* image *******************************************************************/
1906
1907 GimpImage *
gimp_context_get_image(GimpContext * context)1908 gimp_context_get_image (GimpContext *context)
1909 {
1910 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
1911
1912 return context->image;
1913 }
1914
1915 void
gimp_context_set_image(GimpContext * context,GimpImage * image)1916 gimp_context_set_image (GimpContext *context,
1917 GimpImage *image)
1918 {
1919 g_return_if_fail (GIMP_IS_CONTEXT (context));
1920 g_return_if_fail (image == NULL || GIMP_IS_IMAGE (image));
1921
1922 context_find_defined (context, GIMP_CONTEXT_PROP_IMAGE);
1923
1924 gimp_context_real_set_image (context, image);
1925 }
1926
1927 void
gimp_context_image_changed(GimpContext * context)1928 gimp_context_image_changed (GimpContext *context)
1929 {
1930 g_return_if_fail (GIMP_IS_CONTEXT (context));
1931
1932 g_signal_emit (context,
1933 gimp_context_signals[IMAGE_CHANGED], 0,
1934 context->image);
1935 }
1936
1937 static void
gimp_context_image_removed(GimpContainer * container,GimpImage * image,GimpContext * context)1938 gimp_context_image_removed (GimpContainer *container,
1939 GimpImage *image,
1940 GimpContext *context)
1941 {
1942 if (context->image == image)
1943 gimp_context_real_set_image (context, NULL);
1944 }
1945
1946 static void
gimp_context_real_set_image(GimpContext * context,GimpImage * image)1947 gimp_context_real_set_image (GimpContext *context,
1948 GimpImage *image)
1949 {
1950 if (context->image == image)
1951 return;
1952
1953 context->image = image;
1954
1955 g_object_notify (G_OBJECT (context), "image");
1956 gimp_context_image_changed (context);
1957 }
1958
1959
1960 /*****************************************************************************/
1961 /* display *****************************************************************/
1962
1963 gpointer
gimp_context_get_display(GimpContext * context)1964 gimp_context_get_display (GimpContext *context)
1965 {
1966 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
1967
1968 return context->display;
1969 }
1970
1971 void
gimp_context_set_display(GimpContext * context,gpointer display)1972 gimp_context_set_display (GimpContext *context,
1973 gpointer display)
1974 {
1975 g_return_if_fail (GIMP_IS_CONTEXT (context));
1976 g_return_if_fail (display == NULL || GIMP_IS_OBJECT (display));
1977
1978 context_find_defined (context, GIMP_CONTEXT_PROP_DISPLAY);
1979
1980 gimp_context_real_set_display (context, display);
1981 }
1982
1983 void
gimp_context_display_changed(GimpContext * context)1984 gimp_context_display_changed (GimpContext *context)
1985 {
1986 g_return_if_fail (GIMP_IS_CONTEXT (context));
1987
1988 g_signal_emit (context,
1989 gimp_context_signals[DISPLAY_CHANGED], 0,
1990 context->display);
1991 }
1992
1993 static void
gimp_context_display_removed(GimpContainer * container,gpointer display,GimpContext * context)1994 gimp_context_display_removed (GimpContainer *container,
1995 gpointer display,
1996 GimpContext *context)
1997 {
1998 if (context->display == display)
1999 gimp_context_real_set_display (context, NULL);
2000 }
2001
2002 static void
gimp_context_real_set_display(GimpContext * context,gpointer display)2003 gimp_context_real_set_display (GimpContext *context,
2004 gpointer display)
2005 {
2006 GimpObject *old_display;
2007
2008 if (context->display == display)
2009 {
2010 /* make sure that setting a display *always* sets the image
2011 * to that display's image, even if the display already
2012 * matches
2013 */
2014 if (display)
2015 {
2016 GimpImage *image;
2017
2018 g_object_get (display, "image", &image, NULL);
2019
2020 gimp_context_real_set_image (context, image);
2021
2022 if (image)
2023 g_object_unref (image);
2024 }
2025
2026 return;
2027 }
2028
2029 old_display = context->display;
2030
2031 context->display = display;
2032
2033 if (context->display)
2034 {
2035 GimpImage *image;
2036
2037 g_object_get (display, "image", &image, NULL);
2038
2039 gimp_context_real_set_image (context, image);
2040
2041 if (image)
2042 g_object_unref (image);
2043 }
2044 else if (old_display)
2045 {
2046 gimp_context_real_set_image (context, NULL);
2047 }
2048
2049 g_object_notify (G_OBJECT (context), "display");
2050 gimp_context_display_changed (context);
2051 }
2052
2053
2054 /*****************************************************************************/
2055 /* tool ********************************************************************/
2056
2057 GimpToolInfo *
gimp_context_get_tool(GimpContext * context)2058 gimp_context_get_tool (GimpContext *context)
2059 {
2060 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2061
2062 return context->tool_info;
2063 }
2064
2065 void
gimp_context_set_tool(GimpContext * context,GimpToolInfo * tool_info)2066 gimp_context_set_tool (GimpContext *context,
2067 GimpToolInfo *tool_info)
2068 {
2069 g_return_if_fail (GIMP_IS_CONTEXT (context));
2070 g_return_if_fail (tool_info == NULL || GIMP_IS_TOOL_INFO (tool_info));
2071
2072 context_find_defined (context, GIMP_CONTEXT_PROP_TOOL);
2073
2074 gimp_context_real_set_tool (context, tool_info);
2075 }
2076
2077 void
gimp_context_tool_changed(GimpContext * context)2078 gimp_context_tool_changed (GimpContext *context)
2079 {
2080 g_return_if_fail (GIMP_IS_CONTEXT (context));
2081
2082 g_signal_emit (context,
2083 gimp_context_signals[TOOL_CHANGED], 0,
2084 context->tool_info);
2085 }
2086
2087 static void
gimp_context_tool_dirty(GimpToolInfo * tool_info,GimpContext * context)2088 gimp_context_tool_dirty (GimpToolInfo *tool_info,
2089 GimpContext *context)
2090 {
2091 g_free (context->tool_name);
2092 context->tool_name = g_strdup (gimp_object_get_name (tool_info));
2093
2094 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2095 GIMP_CONTEXT_PROP_TOOL);
2096 }
2097
2098 static void
gimp_context_tool_list_thaw(GimpContainer * container,GimpContext * context)2099 gimp_context_tool_list_thaw (GimpContainer *container,
2100 GimpContext *context)
2101 {
2102 GimpToolInfo *tool_info;
2103
2104 if (! context->tool_name)
2105 context->tool_name = g_strdup ("gimp-paintbrush-tool");
2106
2107 tool_info = gimp_context_find_object (context, container,
2108 context->tool_name,
2109 gimp_tool_info_get_standard (context->gimp));
2110
2111 gimp_context_real_set_tool (context, tool_info);
2112 }
2113
2114 static void
gimp_context_tool_removed(GimpContainer * container,GimpToolInfo * tool_info,GimpContext * context)2115 gimp_context_tool_removed (GimpContainer *container,
2116 GimpToolInfo *tool_info,
2117 GimpContext *context)
2118 {
2119 if (tool_info == context->tool_info)
2120 {
2121 g_signal_handlers_disconnect_by_func (context->tool_info,
2122 gimp_context_tool_dirty,
2123 context);
2124 g_clear_object (&context->tool_info);
2125
2126 if (! gimp_container_frozen (container))
2127 gimp_context_tool_list_thaw (container, context);
2128 }
2129 }
2130
2131 static void
gimp_context_real_set_tool(GimpContext * context,GimpToolInfo * tool_info)2132 gimp_context_real_set_tool (GimpContext *context,
2133 GimpToolInfo *tool_info)
2134 {
2135 if (context->tool_info == tool_info)
2136 return;
2137
2138 if (context->tool_name &&
2139 tool_info != gimp_tool_info_get_standard (context->gimp))
2140 {
2141 g_clear_pointer (&context->tool_name, g_free);
2142 }
2143
2144 if (context->tool_info)
2145 g_signal_handlers_disconnect_by_func (context->tool_info,
2146 gimp_context_tool_dirty,
2147 context);
2148
2149 g_set_object (&context->tool_info, tool_info);
2150
2151 if (tool_info)
2152 {
2153 g_signal_connect_object (tool_info, "name-changed",
2154 G_CALLBACK (gimp_context_tool_dirty),
2155 context,
2156 0);
2157
2158 if (tool_info != gimp_tool_info_get_standard (context->gimp))
2159 context->tool_name = g_strdup (gimp_object_get_name (tool_info));
2160
2161 if (tool_info->paint_info)
2162 gimp_context_real_set_paint_info (context, tool_info->paint_info);
2163 }
2164
2165 g_object_notify (G_OBJECT (context), "tool");
2166 gimp_context_tool_changed (context);
2167 }
2168
2169
2170 /*****************************************************************************/
2171 /* paint info **************************************************************/
2172
2173 GimpPaintInfo *
gimp_context_get_paint_info(GimpContext * context)2174 gimp_context_get_paint_info (GimpContext *context)
2175 {
2176 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2177
2178 return context->paint_info;
2179 }
2180
2181 void
gimp_context_set_paint_info(GimpContext * context,GimpPaintInfo * paint_info)2182 gimp_context_set_paint_info (GimpContext *context,
2183 GimpPaintInfo *paint_info)
2184 {
2185 g_return_if_fail (GIMP_IS_CONTEXT (context));
2186 g_return_if_fail (paint_info == NULL || GIMP_IS_PAINT_INFO (paint_info));
2187
2188 context_find_defined (context, GIMP_CONTEXT_PROP_PAINT_INFO);
2189
2190 gimp_context_real_set_paint_info (context, paint_info);
2191 }
2192
2193 void
gimp_context_paint_info_changed(GimpContext * context)2194 gimp_context_paint_info_changed (GimpContext *context)
2195 {
2196 g_return_if_fail (GIMP_IS_CONTEXT (context));
2197
2198 g_signal_emit (context,
2199 gimp_context_signals[PAINT_INFO_CHANGED], 0,
2200 context->paint_info);
2201 }
2202
2203 static void
gimp_context_paint_info_dirty(GimpPaintInfo * paint_info,GimpContext * context)2204 gimp_context_paint_info_dirty (GimpPaintInfo *paint_info,
2205 GimpContext *context)
2206 {
2207 g_free (context->paint_name);
2208 context->paint_name = g_strdup (gimp_object_get_name (paint_info));
2209
2210 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2211 GIMP_CONTEXT_PROP_PAINT_INFO);
2212 }
2213
2214 /* the global paint info list is there again after refresh */
2215 static void
gimp_context_paint_info_list_thaw(GimpContainer * container,GimpContext * context)2216 gimp_context_paint_info_list_thaw (GimpContainer *container,
2217 GimpContext *context)
2218 {
2219 GimpPaintInfo *paint_info;
2220
2221 if (! context->paint_name)
2222 context->paint_name = g_strdup ("gimp-paintbrush");
2223
2224 paint_info = gimp_context_find_object (context, container,
2225 context->paint_name,
2226 gimp_paint_info_get_standard (context->gimp));
2227
2228 gimp_context_real_set_paint_info (context, paint_info);
2229 }
2230
2231 static void
gimp_context_paint_info_removed(GimpContainer * container,GimpPaintInfo * paint_info,GimpContext * context)2232 gimp_context_paint_info_removed (GimpContainer *container,
2233 GimpPaintInfo *paint_info,
2234 GimpContext *context)
2235 {
2236 if (paint_info == context->paint_info)
2237 {
2238 g_signal_handlers_disconnect_by_func (context->paint_info,
2239 gimp_context_paint_info_dirty,
2240 context);
2241 g_clear_object (&context->paint_info);
2242
2243 if (! gimp_container_frozen (container))
2244 gimp_context_paint_info_list_thaw (container, context);
2245 }
2246 }
2247
2248 static void
gimp_context_real_set_paint_info(GimpContext * context,GimpPaintInfo * paint_info)2249 gimp_context_real_set_paint_info (GimpContext *context,
2250 GimpPaintInfo *paint_info)
2251 {
2252 if (context->paint_info == paint_info)
2253 return;
2254
2255 if (context->paint_name &&
2256 paint_info != gimp_paint_info_get_standard (context->gimp))
2257 {
2258 g_clear_pointer (&context->paint_name, g_free);
2259 }
2260
2261 if (context->paint_info)
2262 g_signal_handlers_disconnect_by_func (context->paint_info,
2263 gimp_context_paint_info_dirty,
2264 context);
2265
2266 g_set_object (&context->paint_info, paint_info);
2267
2268 if (paint_info)
2269 {
2270 g_signal_connect_object (paint_info, "name-changed",
2271 G_CALLBACK (gimp_context_paint_info_dirty),
2272 context,
2273 0);
2274
2275 if (paint_info != gimp_paint_info_get_standard (context->gimp))
2276 context->paint_name = g_strdup (gimp_object_get_name (paint_info));
2277 }
2278
2279 g_object_notify (G_OBJECT (context), "paint-info");
2280 gimp_context_paint_info_changed (context);
2281 }
2282
2283
2284 /*****************************************************************************/
2285 /* foreground color ********************************************************/
2286
2287 void
gimp_context_get_foreground(GimpContext * context,GimpRGB * color)2288 gimp_context_get_foreground (GimpContext *context,
2289 GimpRGB *color)
2290 {
2291 g_return_if_fail (GIMP_IS_CONTEXT (context));
2292 g_return_if_fail (color != NULL);
2293
2294 *color = context->foreground;
2295 }
2296
2297 void
gimp_context_set_foreground(GimpContext * context,const GimpRGB * color)2298 gimp_context_set_foreground (GimpContext *context,
2299 const GimpRGB *color)
2300 {
2301 g_return_if_fail (GIMP_IS_CONTEXT (context));
2302 g_return_if_fail (color != NULL);
2303
2304 context_find_defined (context, GIMP_CONTEXT_PROP_FOREGROUND);
2305
2306 gimp_context_real_set_foreground (context, color);
2307 }
2308
2309 void
gimp_context_foreground_changed(GimpContext * context)2310 gimp_context_foreground_changed (GimpContext *context)
2311 {
2312 g_return_if_fail (GIMP_IS_CONTEXT (context));
2313
2314 g_signal_emit (context,
2315 gimp_context_signals[FOREGROUND_CHANGED], 0,
2316 &context->foreground);
2317 }
2318
2319 static void
gimp_context_real_set_foreground(GimpContext * context,const GimpRGB * color)2320 gimp_context_real_set_foreground (GimpContext *context,
2321 const GimpRGB *color)
2322 {
2323 if (gimp_rgba_distance (&context->foreground, color) < RGBA_EPSILON)
2324 return;
2325
2326 context->foreground = *color;
2327 gimp_rgb_set_alpha (&context->foreground, GIMP_OPACITY_OPAQUE);
2328
2329 g_object_notify (G_OBJECT (context), "foreground");
2330 gimp_context_foreground_changed (context);
2331 }
2332
2333
2334 /*****************************************************************************/
2335 /* background color ********************************************************/
2336
2337 void
gimp_context_get_background(GimpContext * context,GimpRGB * color)2338 gimp_context_get_background (GimpContext *context,
2339 GimpRGB *color)
2340 {
2341 g_return_if_fail (GIMP_IS_CONTEXT (context));
2342
2343 g_return_if_fail (color != NULL);
2344
2345 *color = context->background;
2346 }
2347
2348 void
gimp_context_set_background(GimpContext * context,const GimpRGB * color)2349 gimp_context_set_background (GimpContext *context,
2350 const GimpRGB *color)
2351 {
2352 g_return_if_fail (GIMP_IS_CONTEXT (context));
2353 g_return_if_fail (color != NULL);
2354
2355 context_find_defined (context, GIMP_CONTEXT_PROP_BACKGROUND);
2356
2357 gimp_context_real_set_background (context, color);
2358 }
2359
2360 void
gimp_context_background_changed(GimpContext * context)2361 gimp_context_background_changed (GimpContext *context)
2362 {
2363 g_return_if_fail (GIMP_IS_CONTEXT (context));
2364
2365 g_signal_emit (context,
2366 gimp_context_signals[BACKGROUND_CHANGED], 0,
2367 &context->background);
2368 }
2369
2370 static void
gimp_context_real_set_background(GimpContext * context,const GimpRGB * color)2371 gimp_context_real_set_background (GimpContext *context,
2372 const GimpRGB *color)
2373 {
2374 if (gimp_rgba_distance (&context->background, color) < RGBA_EPSILON)
2375 return;
2376
2377 context->background = *color;
2378 gimp_rgb_set_alpha (&context->background, GIMP_OPACITY_OPAQUE);
2379
2380 g_object_notify (G_OBJECT (context), "background");
2381 gimp_context_background_changed (context);
2382 }
2383
2384
2385 /*****************************************************************************/
2386 /* color utility functions *************************************************/
2387
2388 void
gimp_context_set_default_colors(GimpContext * context)2389 gimp_context_set_default_colors (GimpContext *context)
2390 {
2391 GimpContext *bg_context;
2392 GimpRGB fg;
2393 GimpRGB bg;
2394
2395 g_return_if_fail (GIMP_IS_CONTEXT (context));
2396
2397 bg_context = context;
2398
2399 context_find_defined (context, GIMP_CONTEXT_PROP_FOREGROUND);
2400 context_find_defined (bg_context, GIMP_CONTEXT_PROP_BACKGROUND);
2401
2402 gimp_rgba_set (&fg, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
2403 gimp_rgba_set (&bg, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
2404
2405 gimp_context_real_set_foreground (context, &fg);
2406 gimp_context_real_set_background (bg_context, &bg);
2407 }
2408
2409 void
gimp_context_swap_colors(GimpContext * context)2410 gimp_context_swap_colors (GimpContext *context)
2411 {
2412 GimpContext *bg_context;
2413 GimpRGB fg;
2414 GimpRGB bg;
2415
2416 g_return_if_fail (GIMP_IS_CONTEXT (context));
2417
2418 bg_context = context;
2419
2420 context_find_defined (context, GIMP_CONTEXT_PROP_FOREGROUND);
2421 context_find_defined (bg_context, GIMP_CONTEXT_PROP_BACKGROUND);
2422
2423 gimp_context_get_foreground (context, &fg);
2424 gimp_context_get_background (bg_context, &bg);
2425
2426 gimp_context_real_set_foreground (context, &bg);
2427 gimp_context_real_set_background (bg_context, &fg);
2428 }
2429
2430
2431 /*****************************************************************************/
2432 /* opacity *****************************************************************/
2433
2434 gdouble
gimp_context_get_opacity(GimpContext * context)2435 gimp_context_get_opacity (GimpContext *context)
2436 {
2437 g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_OPACITY_OPAQUE);
2438
2439 return context->opacity;
2440 }
2441
2442 void
gimp_context_set_opacity(GimpContext * context,gdouble opacity)2443 gimp_context_set_opacity (GimpContext *context,
2444 gdouble opacity)
2445 {
2446 g_return_if_fail (GIMP_IS_CONTEXT (context));
2447
2448 context_find_defined (context, GIMP_CONTEXT_PROP_OPACITY);
2449
2450 gimp_context_real_set_opacity (context, opacity);
2451 }
2452
2453 void
gimp_context_opacity_changed(GimpContext * context)2454 gimp_context_opacity_changed (GimpContext *context)
2455 {
2456 g_return_if_fail (GIMP_IS_CONTEXT (context));
2457
2458 g_signal_emit (context,
2459 gimp_context_signals[OPACITY_CHANGED], 0,
2460 context->opacity);
2461 }
2462
2463 static void
gimp_context_real_set_opacity(GimpContext * context,gdouble opacity)2464 gimp_context_real_set_opacity (GimpContext *context,
2465 gdouble opacity)
2466 {
2467 if (context->opacity == opacity)
2468 return;
2469
2470 context->opacity = opacity;
2471
2472 g_object_notify (G_OBJECT (context), "opacity");
2473 gimp_context_opacity_changed (context);
2474 }
2475
2476
2477 /*****************************************************************************/
2478 /* paint mode **************************************************************/
2479
2480 GimpLayerMode
gimp_context_get_paint_mode(GimpContext * context)2481 gimp_context_get_paint_mode (GimpContext *context)
2482 {
2483 g_return_val_if_fail (GIMP_IS_CONTEXT (context), GIMP_LAYER_MODE_NORMAL);
2484
2485 return context->paint_mode;
2486 }
2487
2488 void
gimp_context_set_paint_mode(GimpContext * context,GimpLayerMode paint_mode)2489 gimp_context_set_paint_mode (GimpContext *context,
2490 GimpLayerMode paint_mode)
2491 {
2492 g_return_if_fail (GIMP_IS_CONTEXT (context));
2493
2494 context_find_defined (context, GIMP_CONTEXT_PROP_PAINT_MODE);
2495
2496 gimp_context_real_set_paint_mode (context, paint_mode);
2497 }
2498
2499 void
gimp_context_paint_mode_changed(GimpContext * context)2500 gimp_context_paint_mode_changed (GimpContext *context)
2501 {
2502 g_return_if_fail (GIMP_IS_CONTEXT (context));
2503
2504 g_signal_emit (context,
2505 gimp_context_signals[PAINT_MODE_CHANGED], 0,
2506 context->paint_mode);
2507 }
2508
2509 static void
gimp_context_real_set_paint_mode(GimpContext * context,GimpLayerMode paint_mode)2510 gimp_context_real_set_paint_mode (GimpContext *context,
2511 GimpLayerMode paint_mode)
2512 {
2513 if (context->paint_mode == paint_mode)
2514 return;
2515
2516 context->paint_mode = paint_mode;
2517
2518 g_object_notify (G_OBJECT (context), "paint-mode");
2519 gimp_context_paint_mode_changed (context);
2520 }
2521
2522
2523 /*****************************************************************************/
2524 /* brush *******************************************************************/
2525
2526 GimpBrush *
gimp_context_get_brush(GimpContext * context)2527 gimp_context_get_brush (GimpContext *context)
2528 {
2529 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2530
2531 return context->brush;
2532 }
2533
2534 void
gimp_context_set_brush(GimpContext * context,GimpBrush * brush)2535 gimp_context_set_brush (GimpContext *context,
2536 GimpBrush *brush)
2537 {
2538 g_return_if_fail (GIMP_IS_CONTEXT (context));
2539 g_return_if_fail (brush == NULL || GIMP_IS_BRUSH (brush));
2540
2541 context_find_defined (context, GIMP_CONTEXT_PROP_BRUSH);
2542
2543 gimp_context_real_set_brush (context, brush);
2544 }
2545
2546 void
gimp_context_brush_changed(GimpContext * context)2547 gimp_context_brush_changed (GimpContext *context)
2548 {
2549 g_return_if_fail (GIMP_IS_CONTEXT (context));
2550
2551 g_signal_emit (context,
2552 gimp_context_signals[BRUSH_CHANGED], 0,
2553 context->brush);
2554 }
2555
2556 static void
gimp_context_brush_dirty(GimpBrush * brush,GimpContext * context)2557 gimp_context_brush_dirty (GimpBrush *brush,
2558 GimpContext *context)
2559 {
2560 g_free (context->brush_name);
2561 context->brush_name = g_strdup (gimp_object_get_name (brush));
2562
2563 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2564 GIMP_CONTEXT_PROP_BRUSH);
2565 }
2566
2567 static void
gimp_context_brush_list_thaw(GimpContainer * container,GimpContext * context)2568 gimp_context_brush_list_thaw (GimpContainer *container,
2569 GimpContext *context)
2570 {
2571 GimpBrush *brush;
2572
2573 if (! context->brush_name)
2574 context->brush_name = g_strdup (context->gimp->config->default_brush);
2575
2576 brush = gimp_context_find_object (context, container,
2577 context->brush_name,
2578 gimp_brush_get_standard (context));
2579
2580 gimp_context_real_set_brush (context, brush);
2581 }
2582
2583 /* the active brush disappeared */
2584 static void
gimp_context_brush_removed(GimpContainer * container,GimpBrush * brush,GimpContext * context)2585 gimp_context_brush_removed (GimpContainer *container,
2586 GimpBrush *brush,
2587 GimpContext *context)
2588 {
2589 if (brush == context->brush)
2590 {
2591 g_signal_handlers_disconnect_by_func (context->brush,
2592 gimp_context_brush_dirty,
2593 context);
2594 g_clear_object (&context->brush);
2595
2596 if (! gimp_container_frozen (container))
2597 gimp_context_brush_list_thaw (container, context);
2598 }
2599 }
2600
2601 static void
gimp_context_real_set_brush(GimpContext * context,GimpBrush * brush)2602 gimp_context_real_set_brush (GimpContext *context,
2603 GimpBrush *brush)
2604 {
2605 if (context->brush == brush)
2606 return;
2607
2608 if (context->brush_name &&
2609 brush != GIMP_BRUSH (gimp_brush_get_standard (context)))
2610 {
2611 g_clear_pointer (&context->brush_name, g_free);
2612 }
2613
2614 if (context->brush)
2615 g_signal_handlers_disconnect_by_func (context->brush,
2616 gimp_context_brush_dirty,
2617 context);
2618
2619 g_set_object (&context->brush, brush);
2620
2621 if (brush)
2622 {
2623 g_signal_connect_object (brush, "name-changed",
2624 G_CALLBACK (gimp_context_brush_dirty),
2625 context,
2626 0);
2627
2628 if (brush != GIMP_BRUSH (gimp_brush_get_standard (context)))
2629 context->brush_name = g_strdup (gimp_object_get_name (brush));
2630 }
2631
2632 g_object_notify (G_OBJECT (context), "brush");
2633 gimp_context_brush_changed (context);
2634 }
2635
2636
2637 /*****************************************************************************/
2638 /* dynamics *****************************************************************/
2639
2640 GimpDynamics *
gimp_context_get_dynamics(GimpContext * context)2641 gimp_context_get_dynamics (GimpContext *context)
2642 {
2643 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2644
2645 return context->dynamics;
2646 }
2647
2648 void
gimp_context_set_dynamics(GimpContext * context,GimpDynamics * dynamics)2649 gimp_context_set_dynamics (GimpContext *context,
2650 GimpDynamics *dynamics)
2651 {
2652 g_return_if_fail (GIMP_IS_CONTEXT (context));
2653 g_return_if_fail (dynamics == NULL || GIMP_IS_DYNAMICS (dynamics));
2654
2655 context_find_defined (context, GIMP_CONTEXT_PROP_DYNAMICS);
2656
2657 gimp_context_real_set_dynamics (context, dynamics);
2658 }
2659
2660 void
gimp_context_dynamics_changed(GimpContext * context)2661 gimp_context_dynamics_changed (GimpContext *context)
2662 {
2663 g_return_if_fail (GIMP_IS_CONTEXT (context));
2664
2665 g_signal_emit (context,
2666 gimp_context_signals[DYNAMICS_CHANGED], 0,
2667 context->dynamics);
2668 }
2669
2670 static void
gimp_context_dynamics_dirty(GimpDynamics * dynamics,GimpContext * context)2671 gimp_context_dynamics_dirty (GimpDynamics *dynamics,
2672 GimpContext *context)
2673 {
2674 g_free (context->dynamics_name);
2675 context->dynamics_name = g_strdup (gimp_object_get_name (dynamics));
2676
2677 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2678 GIMP_CONTEXT_PROP_DYNAMICS);
2679 }
2680
2681 static void
gimp_context_dynamics_removed(GimpContainer * container,GimpDynamics * dynamics,GimpContext * context)2682 gimp_context_dynamics_removed (GimpContainer *container,
2683 GimpDynamics *dynamics,
2684 GimpContext *context)
2685 {
2686 if (dynamics == context->dynamics)
2687 {
2688 g_signal_handlers_disconnect_by_func (context->dynamics,
2689 gimp_context_dynamics_dirty,
2690 context);
2691 g_clear_object (&context->dynamics);
2692
2693 if (! gimp_container_frozen (container))
2694 gimp_context_dynamics_list_thaw (container, context);
2695 }
2696 }
2697
2698 static void
gimp_context_dynamics_list_thaw(GimpContainer * container,GimpContext * context)2699 gimp_context_dynamics_list_thaw (GimpContainer *container,
2700 GimpContext *context)
2701 {
2702 GimpDynamics *dynamics;
2703
2704 if (! context->dynamics_name)
2705 context->dynamics_name = g_strdup (context->gimp->config->default_dynamics);
2706
2707 dynamics = gimp_context_find_object (context, container,
2708 context->dynamics_name,
2709 gimp_dynamics_get_standard (context));
2710
2711 gimp_context_real_set_dynamics (context, dynamics);
2712 }
2713
2714 static void
gimp_context_real_set_dynamics(GimpContext * context,GimpDynamics * dynamics)2715 gimp_context_real_set_dynamics (GimpContext *context,
2716 GimpDynamics *dynamics)
2717 {
2718 if (context->dynamics == dynamics)
2719 return;
2720
2721 if (context->dynamics_name &&
2722 dynamics != GIMP_DYNAMICS (gimp_dynamics_get_standard (context)))
2723 {
2724 g_clear_pointer (&context->dynamics_name, g_free);
2725 }
2726
2727 if (context->dynamics)
2728 g_signal_handlers_disconnect_by_func (context->dynamics,
2729 gimp_context_dynamics_dirty,
2730 context);
2731
2732 g_set_object (&context->dynamics, dynamics);
2733
2734 if (dynamics)
2735 {
2736 g_signal_connect_object (dynamics, "name-changed",
2737 G_CALLBACK (gimp_context_dynamics_dirty),
2738 context,
2739 0);
2740
2741 if (dynamics != GIMP_DYNAMICS (gimp_dynamics_get_standard (context)))
2742 context->dynamics_name = g_strdup (gimp_object_get_name (dynamics));
2743 }
2744
2745 g_object_notify (G_OBJECT (context), "dynamics");
2746 gimp_context_dynamics_changed (context);
2747 }
2748
2749
2750 /*****************************************************************************/
2751 /* mybrush *****************************************************************/
2752
2753 GimpMybrush *
gimp_context_get_mybrush(GimpContext * context)2754 gimp_context_get_mybrush (GimpContext *context)
2755 {
2756 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2757
2758 return context->mybrush;
2759 }
2760
2761 void
gimp_context_set_mybrush(GimpContext * context,GimpMybrush * brush)2762 gimp_context_set_mybrush (GimpContext *context,
2763 GimpMybrush *brush)
2764 {
2765 g_return_if_fail (GIMP_IS_CONTEXT (context));
2766 g_return_if_fail (brush == NULL || GIMP_IS_MYBRUSH (brush));
2767
2768 context_find_defined (context, GIMP_CONTEXT_PROP_MYBRUSH);
2769
2770 gimp_context_real_set_mybrush (context, brush);
2771 }
2772
2773 void
gimp_context_mybrush_changed(GimpContext * context)2774 gimp_context_mybrush_changed (GimpContext *context)
2775 {
2776 g_return_if_fail (GIMP_IS_CONTEXT (context));
2777
2778 g_signal_emit (context,
2779 gimp_context_signals[MYBRUSH_CHANGED], 0,
2780 context->mybrush);
2781 }
2782
2783 static void
gimp_context_mybrush_dirty(GimpMybrush * brush,GimpContext * context)2784 gimp_context_mybrush_dirty (GimpMybrush *brush,
2785 GimpContext *context)
2786 {
2787 g_free (context->mybrush_name);
2788 context->mybrush_name = g_strdup (gimp_object_get_name (brush));
2789
2790 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2791 GIMP_CONTEXT_PROP_MYBRUSH);
2792 }
2793
2794 static void
gimp_context_mybrush_list_thaw(GimpContainer * container,GimpContext * context)2795 gimp_context_mybrush_list_thaw (GimpContainer *container,
2796 GimpContext *context)
2797 {
2798 GimpMybrush *brush;
2799
2800 if (! context->mybrush_name)
2801 context->mybrush_name = g_strdup (context->gimp->config->default_mypaint_brush);
2802
2803 brush = gimp_context_find_object (context, container,
2804 context->mybrush_name,
2805 gimp_mybrush_get_standard (context));
2806
2807 gimp_context_real_set_mybrush (context, brush);
2808 }
2809
2810 static void
gimp_context_mybrush_removed(GimpContainer * container,GimpMybrush * brush,GimpContext * context)2811 gimp_context_mybrush_removed (GimpContainer *container,
2812 GimpMybrush *brush,
2813 GimpContext *context)
2814 {
2815 if (brush == context->mybrush)
2816 {
2817 g_signal_handlers_disconnect_by_func (context->mybrush,
2818 gimp_context_mybrush_dirty,
2819 context);
2820 g_clear_object (&context->mybrush);
2821
2822 if (! gimp_container_frozen (container))
2823 gimp_context_mybrush_list_thaw (container, context);
2824 }
2825 }
2826
2827 static void
gimp_context_real_set_mybrush(GimpContext * context,GimpMybrush * brush)2828 gimp_context_real_set_mybrush (GimpContext *context,
2829 GimpMybrush *brush)
2830 {
2831 if (context->mybrush == brush)
2832 return;
2833
2834 if (context->mybrush_name &&
2835 brush != GIMP_MYBRUSH (gimp_mybrush_get_standard (context)))
2836 {
2837 g_clear_pointer (&context->mybrush_name, g_free);
2838 }
2839
2840 if (context->mybrush)
2841 g_signal_handlers_disconnect_by_func (context->mybrush,
2842 gimp_context_mybrush_dirty,
2843 context);
2844
2845 g_set_object (&context->mybrush, brush);
2846
2847 if (brush)
2848 {
2849 g_signal_connect_object (brush, "name-changed",
2850 G_CALLBACK (gimp_context_mybrush_dirty),
2851 context,
2852 0);
2853
2854 if (brush != GIMP_MYBRUSH (gimp_mybrush_get_standard (context)))
2855 context->mybrush_name = g_strdup (gimp_object_get_name (brush));
2856 }
2857
2858 g_object_notify (G_OBJECT (context), "mybrush");
2859 gimp_context_mybrush_changed (context);
2860 }
2861
2862
2863 /*****************************************************************************/
2864 /* pattern *****************************************************************/
2865
2866 GimpPattern *
gimp_context_get_pattern(GimpContext * context)2867 gimp_context_get_pattern (GimpContext *context)
2868 {
2869 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2870
2871 return context->pattern;
2872 }
2873
2874 void
gimp_context_set_pattern(GimpContext * context,GimpPattern * pattern)2875 gimp_context_set_pattern (GimpContext *context,
2876 GimpPattern *pattern)
2877 {
2878 g_return_if_fail (GIMP_IS_CONTEXT (context));
2879 g_return_if_fail (pattern == NULL || GIMP_IS_PATTERN (pattern));
2880
2881 context_find_defined (context, GIMP_CONTEXT_PROP_PATTERN);
2882
2883 gimp_context_real_set_pattern (context, pattern);
2884 }
2885
2886 void
gimp_context_pattern_changed(GimpContext * context)2887 gimp_context_pattern_changed (GimpContext *context)
2888 {
2889 g_return_if_fail (GIMP_IS_CONTEXT (context));
2890
2891 g_signal_emit (context,
2892 gimp_context_signals[PATTERN_CHANGED], 0,
2893 context->pattern);
2894 }
2895
2896 static void
gimp_context_pattern_dirty(GimpPattern * pattern,GimpContext * context)2897 gimp_context_pattern_dirty (GimpPattern *pattern,
2898 GimpContext *context)
2899 {
2900 g_free (context->pattern_name);
2901 context->pattern_name = g_strdup (gimp_object_get_name (pattern));
2902
2903 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
2904 GIMP_CONTEXT_PROP_PATTERN);
2905 }
2906
2907 static void
gimp_context_pattern_list_thaw(GimpContainer * container,GimpContext * context)2908 gimp_context_pattern_list_thaw (GimpContainer *container,
2909 GimpContext *context)
2910 {
2911 GimpPattern *pattern;
2912
2913 if (! context->pattern_name)
2914 context->pattern_name = g_strdup (context->gimp->config->default_pattern);
2915
2916 pattern = gimp_context_find_object (context, container,
2917 context->pattern_name,
2918 gimp_pattern_get_standard (context));
2919
2920 gimp_context_real_set_pattern (context, pattern);
2921 }
2922
2923 static void
gimp_context_pattern_removed(GimpContainer * container,GimpPattern * pattern,GimpContext * context)2924 gimp_context_pattern_removed (GimpContainer *container,
2925 GimpPattern *pattern,
2926 GimpContext *context)
2927 {
2928 if (pattern == context->pattern)
2929 {
2930 g_signal_handlers_disconnect_by_func (context->pattern,
2931 gimp_context_pattern_dirty,
2932 context);
2933 g_clear_object (&context->pattern);
2934
2935 if (! gimp_container_frozen (container))
2936 gimp_context_pattern_list_thaw (container, context);
2937 }
2938 }
2939
2940 static void
gimp_context_real_set_pattern(GimpContext * context,GimpPattern * pattern)2941 gimp_context_real_set_pattern (GimpContext *context,
2942 GimpPattern *pattern)
2943 {
2944 if (context->pattern == pattern)
2945 return;
2946
2947 if (context->pattern_name &&
2948 pattern != GIMP_PATTERN (gimp_pattern_get_standard (context)))
2949 {
2950 g_clear_pointer (&context->pattern_name, g_free);
2951 }
2952
2953 if (context->pattern)
2954 g_signal_handlers_disconnect_by_func (context->pattern,
2955 gimp_context_pattern_dirty,
2956 context);
2957
2958 g_set_object (&context->pattern, pattern);
2959
2960 if (pattern)
2961 {
2962 g_signal_connect_object (pattern, "name-changed",
2963 G_CALLBACK (gimp_context_pattern_dirty),
2964 context,
2965 0);
2966
2967 if (pattern != GIMP_PATTERN (gimp_pattern_get_standard (context)))
2968 context->pattern_name = g_strdup (gimp_object_get_name (pattern));
2969 }
2970
2971 g_object_notify (G_OBJECT (context), "pattern");
2972 gimp_context_pattern_changed (context);
2973 }
2974
2975
2976 /*****************************************************************************/
2977 /* gradient ****************************************************************/
2978
2979 GimpGradient *
gimp_context_get_gradient(GimpContext * context)2980 gimp_context_get_gradient (GimpContext *context)
2981 {
2982 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
2983
2984 return context->gradient;
2985 }
2986
2987 void
gimp_context_set_gradient(GimpContext * context,GimpGradient * gradient)2988 gimp_context_set_gradient (GimpContext *context,
2989 GimpGradient *gradient)
2990 {
2991 g_return_if_fail (GIMP_IS_CONTEXT (context));
2992 g_return_if_fail (gradient == NULL || GIMP_IS_GRADIENT (gradient));
2993
2994 context_find_defined (context, GIMP_CONTEXT_PROP_GRADIENT);
2995
2996 gimp_context_real_set_gradient (context, gradient);
2997 }
2998
2999 void
gimp_context_gradient_changed(GimpContext * context)3000 gimp_context_gradient_changed (GimpContext *context)
3001 {
3002 g_return_if_fail (GIMP_IS_CONTEXT (context));
3003
3004 g_signal_emit (context,
3005 gimp_context_signals[GRADIENT_CHANGED], 0,
3006 context->gradient);
3007 }
3008
3009 static void
gimp_context_gradient_dirty(GimpGradient * gradient,GimpContext * context)3010 gimp_context_gradient_dirty (GimpGradient *gradient,
3011 GimpContext *context)
3012 {
3013 g_free (context->gradient_name);
3014 context->gradient_name = g_strdup (gimp_object_get_name (gradient));
3015
3016 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3017 GIMP_CONTEXT_PROP_GRADIENT);
3018 }
3019
3020 static void
gimp_context_gradient_list_thaw(GimpContainer * container,GimpContext * context)3021 gimp_context_gradient_list_thaw (GimpContainer *container,
3022 GimpContext *context)
3023 {
3024 GimpGradient *gradient;
3025
3026 if (! context->gradient_name)
3027 context->gradient_name = g_strdup (context->gimp->config->default_gradient);
3028
3029 gradient = gimp_context_find_object (context, container,
3030 context->gradient_name,
3031 gimp_gradient_get_standard (context));
3032
3033 gimp_context_real_set_gradient (context, gradient);
3034 }
3035
3036 static void
gimp_context_gradient_removed(GimpContainer * container,GimpGradient * gradient,GimpContext * context)3037 gimp_context_gradient_removed (GimpContainer *container,
3038 GimpGradient *gradient,
3039 GimpContext *context)
3040 {
3041 if (gradient == context->gradient)
3042 {
3043 g_signal_handlers_disconnect_by_func (context->gradient,
3044 gimp_context_gradient_dirty,
3045 context);
3046 g_clear_object (&context->gradient);
3047
3048 if (! gimp_container_frozen (container))
3049 gimp_context_gradient_list_thaw (container, context);
3050 }
3051 }
3052
3053 static void
gimp_context_real_set_gradient(GimpContext * context,GimpGradient * gradient)3054 gimp_context_real_set_gradient (GimpContext *context,
3055 GimpGradient *gradient)
3056 {
3057 if (context->gradient == gradient)
3058 return;
3059
3060 if (context->gradient_name &&
3061 gradient != GIMP_GRADIENT (gimp_gradient_get_standard (context)))
3062 {
3063 g_clear_pointer (&context->gradient_name, g_free);
3064 }
3065
3066 if (context->gradient)
3067 g_signal_handlers_disconnect_by_func (context->gradient,
3068 gimp_context_gradient_dirty,
3069 context);
3070
3071 g_set_object (&context->gradient, gradient);
3072
3073 if (gradient)
3074 {
3075 g_signal_connect_object (gradient, "name-changed",
3076 G_CALLBACK (gimp_context_gradient_dirty),
3077 context,
3078 0);
3079
3080 if (gradient != GIMP_GRADIENT (gimp_gradient_get_standard (context)))
3081 context->gradient_name = g_strdup (gimp_object_get_name (gradient));
3082 }
3083
3084 g_object_notify (G_OBJECT (context), "gradient");
3085 gimp_context_gradient_changed (context);
3086 }
3087
3088
3089 /*****************************************************************************/
3090 /* palette *****************************************************************/
3091
3092 GimpPalette *
gimp_context_get_palette(GimpContext * context)3093 gimp_context_get_palette (GimpContext *context)
3094 {
3095 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3096
3097 return context->palette;
3098 }
3099
3100 void
gimp_context_set_palette(GimpContext * context,GimpPalette * palette)3101 gimp_context_set_palette (GimpContext *context,
3102 GimpPalette *palette)
3103 {
3104 g_return_if_fail (GIMP_IS_CONTEXT (context));
3105 g_return_if_fail (palette == NULL || GIMP_IS_PALETTE (palette));
3106
3107 context_find_defined (context, GIMP_CONTEXT_PROP_PALETTE);
3108
3109 gimp_context_real_set_palette (context, palette);
3110 }
3111
3112 void
gimp_context_palette_changed(GimpContext * context)3113 gimp_context_palette_changed (GimpContext *context)
3114 {
3115 g_return_if_fail (GIMP_IS_CONTEXT (context));
3116
3117 g_signal_emit (context,
3118 gimp_context_signals[PALETTE_CHANGED], 0,
3119 context->palette);
3120 }
3121
3122 static void
gimp_context_palette_dirty(GimpPalette * palette,GimpContext * context)3123 gimp_context_palette_dirty (GimpPalette *palette,
3124 GimpContext *context)
3125 {
3126 g_free (context->palette_name);
3127 context->palette_name = g_strdup (gimp_object_get_name (palette));
3128
3129 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3130 GIMP_CONTEXT_PROP_PALETTE);
3131 }
3132
3133 static void
gimp_context_palette_list_thaw(GimpContainer * container,GimpContext * context)3134 gimp_context_palette_list_thaw (GimpContainer *container,
3135 GimpContext *context)
3136 {
3137 GimpPalette *palette;
3138
3139 if (! context->palette_name)
3140 context->palette_name = g_strdup (context->gimp->config->default_palette);
3141
3142 palette = gimp_context_find_object (context, container,
3143 context->palette_name,
3144 gimp_palette_get_standard (context));
3145
3146 gimp_context_real_set_palette (context, palette);
3147 }
3148
3149 static void
gimp_context_palette_removed(GimpContainer * container,GimpPalette * palette,GimpContext * context)3150 gimp_context_palette_removed (GimpContainer *container,
3151 GimpPalette *palette,
3152 GimpContext *context)
3153 {
3154 if (palette == context->palette)
3155 {
3156 g_signal_handlers_disconnect_by_func (context->palette,
3157 gimp_context_palette_dirty,
3158 context);
3159 g_clear_object (&context->palette);
3160
3161 if (! gimp_container_frozen (container))
3162 gimp_context_palette_list_thaw (container, context);
3163 }
3164 }
3165
3166 static void
gimp_context_real_set_palette(GimpContext * context,GimpPalette * palette)3167 gimp_context_real_set_palette (GimpContext *context,
3168 GimpPalette *palette)
3169 {
3170 if (context->palette == palette)
3171 return;
3172
3173 if (context->palette_name &&
3174 palette != GIMP_PALETTE (gimp_palette_get_standard (context)))
3175 {
3176 g_clear_pointer (&context->palette_name, g_free);
3177 }
3178
3179 if (context->palette)
3180 g_signal_handlers_disconnect_by_func (context->palette,
3181 gimp_context_palette_dirty,
3182 context);
3183
3184 g_set_object (&context->palette, palette);
3185
3186 if (palette)
3187 {
3188 g_signal_connect_object (palette, "name-changed",
3189 G_CALLBACK (gimp_context_palette_dirty),
3190 context,
3191 0);
3192
3193 if (palette != GIMP_PALETTE (gimp_palette_get_standard (context)))
3194 context->palette_name = g_strdup (gimp_object_get_name (palette));
3195 }
3196
3197 g_object_notify (G_OBJECT (context), "palette");
3198 gimp_context_palette_changed (context);
3199 }
3200
3201
3202 /*****************************************************************************/
3203 /* font *****************************************************************/
3204
3205 GimpFont *
gimp_context_get_font(GimpContext * context)3206 gimp_context_get_font (GimpContext *context)
3207 {
3208 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3209
3210 return context->font;
3211 }
3212
3213 void
gimp_context_set_font(GimpContext * context,GimpFont * font)3214 gimp_context_set_font (GimpContext *context,
3215 GimpFont *font)
3216 {
3217 g_return_if_fail (GIMP_IS_CONTEXT (context));
3218 g_return_if_fail (font == NULL || GIMP_IS_FONT (font));
3219
3220 context_find_defined (context, GIMP_CONTEXT_PROP_FONT);
3221
3222 gimp_context_real_set_font (context, font);
3223 }
3224
3225 const gchar *
gimp_context_get_font_name(GimpContext * context)3226 gimp_context_get_font_name (GimpContext *context)
3227 {
3228 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3229
3230 return context->font_name;
3231 }
3232
3233 void
gimp_context_set_font_name(GimpContext * context,const gchar * name)3234 gimp_context_set_font_name (GimpContext *context,
3235 const gchar *name)
3236 {
3237 GimpContainer *container;
3238 GimpObject *font;
3239
3240 g_return_if_fail (GIMP_IS_CONTEXT (context));
3241
3242 container = gimp_data_factory_get_container (context->gimp->font_factory);
3243 font = gimp_container_get_child_by_name (container, name);
3244
3245 if (font)
3246 {
3247 gimp_context_set_font (context, GIMP_FONT (font));
3248 }
3249 else
3250 {
3251 /* No font with this name exists, use the standard font, but
3252 * keep the intended name around
3253 */
3254 gimp_context_set_font (context, GIMP_FONT (gimp_font_get_standard ()));
3255
3256 g_free (context->font_name);
3257 context->font_name = g_strdup (name);
3258 }
3259 }
3260
3261 void
gimp_context_font_changed(GimpContext * context)3262 gimp_context_font_changed (GimpContext *context)
3263 {
3264 g_return_if_fail (GIMP_IS_CONTEXT (context));
3265
3266 g_signal_emit (context,
3267 gimp_context_signals[FONT_CHANGED], 0,
3268 context->font);
3269 }
3270
3271 static void
gimp_context_font_dirty(GimpFont * font,GimpContext * context)3272 gimp_context_font_dirty (GimpFont *font,
3273 GimpContext *context)
3274 {
3275 g_free (context->font_name);
3276 context->font_name = g_strdup (gimp_object_get_name (font));
3277
3278 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3279 GIMP_CONTEXT_PROP_FONT);
3280 }
3281
3282 static void
gimp_context_font_list_thaw(GimpContainer * container,GimpContext * context)3283 gimp_context_font_list_thaw (GimpContainer *container,
3284 GimpContext *context)
3285 {
3286 GimpFont *font;
3287
3288 if (! context->font_name)
3289 context->font_name = g_strdup (context->gimp->config->default_font);
3290
3291 font = gimp_context_find_object (context, container,
3292 context->font_name,
3293 gimp_font_get_standard ());
3294
3295 gimp_context_real_set_font (context, font);
3296 }
3297
3298 static void
gimp_context_font_removed(GimpContainer * container,GimpFont * font,GimpContext * context)3299 gimp_context_font_removed (GimpContainer *container,
3300 GimpFont *font,
3301 GimpContext *context)
3302 {
3303 if (font == context->font)
3304 {
3305 g_signal_handlers_disconnect_by_func (context->font,
3306 gimp_context_font_dirty,
3307 context);
3308 g_clear_object (&context->font);
3309
3310 if (! gimp_container_frozen (container))
3311 gimp_context_font_list_thaw (container, context);
3312 }
3313 }
3314
3315 static void
gimp_context_real_set_font(GimpContext * context,GimpFont * font)3316 gimp_context_real_set_font (GimpContext *context,
3317 GimpFont *font)
3318 {
3319 if (context->font == font)
3320 return;
3321
3322 if (context->font_name &&
3323 font != GIMP_FONT (gimp_font_get_standard ()))
3324 {
3325 g_clear_pointer (&context->font_name, g_free);
3326 }
3327
3328 if (context->font)
3329 g_signal_handlers_disconnect_by_func (context->font,
3330 gimp_context_font_dirty,
3331 context);
3332
3333 g_set_object (&context->font, font);
3334
3335 if (font)
3336 {
3337 g_signal_connect_object (font, "name-changed",
3338 G_CALLBACK (gimp_context_font_dirty),
3339 context,
3340 0);
3341
3342 if (font != GIMP_FONT (gimp_font_get_standard ()))
3343 context->font_name = g_strdup (gimp_object_get_name (font));
3344 }
3345
3346 g_object_notify (G_OBJECT (context), "font");
3347 gimp_context_font_changed (context);
3348 }
3349
3350
3351 /********************************************************************************/
3352 /* tool preset *****************************************************************/
3353
3354 GimpToolPreset *
gimp_context_get_tool_preset(GimpContext * context)3355 gimp_context_get_tool_preset (GimpContext *context)
3356 {
3357 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3358
3359 return context->tool_preset;
3360 }
3361
3362 void
gimp_context_set_tool_preset(GimpContext * context,GimpToolPreset * tool_preset)3363 gimp_context_set_tool_preset (GimpContext *context,
3364 GimpToolPreset *tool_preset)
3365 {
3366 g_return_if_fail (GIMP_IS_CONTEXT (context));
3367 g_return_if_fail (tool_preset == NULL || GIMP_IS_TOOL_PRESET (tool_preset));
3368
3369 context_find_defined (context, GIMP_CONTEXT_PROP_TOOL_PRESET);
3370
3371 gimp_context_real_set_tool_preset (context, tool_preset);
3372 }
3373
3374 void
gimp_context_tool_preset_changed(GimpContext * context)3375 gimp_context_tool_preset_changed (GimpContext *context)
3376 {
3377 g_return_if_fail (GIMP_IS_CONTEXT (context));
3378
3379 g_signal_emit (context,
3380 gimp_context_signals[TOOL_PRESET_CHANGED], 0,
3381 context->tool_preset);
3382 }
3383
3384 static void
gimp_context_tool_preset_dirty(GimpToolPreset * tool_preset,GimpContext * context)3385 gimp_context_tool_preset_dirty (GimpToolPreset *tool_preset,
3386 GimpContext *context)
3387 {
3388 g_free (context->tool_preset_name);
3389 context->tool_preset_name = g_strdup (gimp_object_get_name (tool_preset));
3390
3391 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3392 GIMP_CONTEXT_PROP_TOOL_PRESET);
3393 }
3394
3395 static void
gimp_context_tool_preset_removed(GimpContainer * container,GimpToolPreset * tool_preset,GimpContext * context)3396 gimp_context_tool_preset_removed (GimpContainer *container,
3397 GimpToolPreset *tool_preset,
3398 GimpContext *context)
3399 {
3400 if (tool_preset == context->tool_preset)
3401 {
3402 g_signal_handlers_disconnect_by_func (context->tool_preset,
3403 gimp_context_tool_preset_dirty,
3404 context);
3405 g_clear_object (&context->tool_preset);
3406
3407 if (! gimp_container_frozen (container))
3408 gimp_context_tool_preset_list_thaw (container, context);
3409 }
3410 }
3411
3412 static void
gimp_context_tool_preset_list_thaw(GimpContainer * container,GimpContext * context)3413 gimp_context_tool_preset_list_thaw (GimpContainer *container,
3414 GimpContext *context)
3415 {
3416 GimpToolPreset *tool_preset;
3417
3418 tool_preset = gimp_context_find_object (context, container,
3419 context->tool_preset_name,
3420 NULL);
3421
3422 gimp_context_real_set_tool_preset (context, tool_preset);
3423 }
3424
3425 static void
gimp_context_real_set_tool_preset(GimpContext * context,GimpToolPreset * tool_preset)3426 gimp_context_real_set_tool_preset (GimpContext *context,
3427 GimpToolPreset *tool_preset)
3428 {
3429 if (context->tool_preset == tool_preset)
3430 return;
3431
3432 if (context->tool_preset_name)
3433 {
3434 g_clear_pointer (&context->tool_preset_name, g_free);
3435 }
3436
3437 if (context->tool_preset)
3438 g_signal_handlers_disconnect_by_func (context->tool_preset,
3439 gimp_context_tool_preset_dirty,
3440 context);
3441
3442 g_set_object (&context->tool_preset, tool_preset);
3443
3444 if (tool_preset)
3445 {
3446 g_signal_connect_object (tool_preset, "name-changed",
3447 G_CALLBACK (gimp_context_tool_preset_dirty),
3448 context,
3449 0);
3450
3451 context->tool_preset_name = g_strdup (gimp_object_get_name (tool_preset));
3452 }
3453
3454 g_object_notify (G_OBJECT (context), "tool-preset");
3455 gimp_context_tool_preset_changed (context);
3456 }
3457
3458
3459 /*****************************************************************************/
3460 /* buffer ******************************************************************/
3461
3462 GimpBuffer *
gimp_context_get_buffer(GimpContext * context)3463 gimp_context_get_buffer (GimpContext *context)
3464 {
3465 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3466
3467 return context->buffer;
3468 }
3469
3470 void
gimp_context_set_buffer(GimpContext * context,GimpBuffer * buffer)3471 gimp_context_set_buffer (GimpContext *context,
3472 GimpBuffer *buffer)
3473 {
3474 g_return_if_fail (GIMP_IS_CONTEXT (context));
3475 g_return_if_fail (buffer == NULL || GIMP_IS_BUFFER (buffer));
3476
3477 context_find_defined (context, GIMP_CONTEXT_PROP_BUFFER);
3478
3479 gimp_context_real_set_buffer (context, buffer);
3480 }
3481
3482 void
gimp_context_buffer_changed(GimpContext * context)3483 gimp_context_buffer_changed (GimpContext *context)
3484 {
3485 g_return_if_fail (GIMP_IS_CONTEXT (context));
3486
3487 g_signal_emit (context,
3488 gimp_context_signals[BUFFER_CHANGED], 0,
3489 context->buffer);
3490 }
3491
3492 static void
gimp_context_buffer_dirty(GimpBuffer * buffer,GimpContext * context)3493 gimp_context_buffer_dirty (GimpBuffer *buffer,
3494 GimpContext *context)
3495 {
3496 g_free (context->buffer_name);
3497 context->buffer_name = g_strdup (gimp_object_get_name (buffer));
3498
3499 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3500 GIMP_CONTEXT_PROP_BUFFER);
3501 }
3502
3503 static void
gimp_context_buffer_list_thaw(GimpContainer * container,GimpContext * context)3504 gimp_context_buffer_list_thaw (GimpContainer *container,
3505 GimpContext *context)
3506 {
3507 GimpBuffer *buffer;
3508
3509 buffer = gimp_context_find_object (context, container,
3510 context->buffer_name,
3511 NULL);
3512
3513 if (buffer)
3514 {
3515 gimp_context_real_set_buffer (context, buffer);
3516 }
3517 else
3518 {
3519 g_object_notify (G_OBJECT (context), "buffer");
3520 gimp_context_buffer_changed (context);
3521 }
3522 }
3523
3524 static void
gimp_context_buffer_removed(GimpContainer * container,GimpBuffer * buffer,GimpContext * context)3525 gimp_context_buffer_removed (GimpContainer *container,
3526 GimpBuffer *buffer,
3527 GimpContext *context)
3528 {
3529 if (buffer == context->buffer)
3530 {
3531 g_signal_handlers_disconnect_by_func (context->buffer,
3532 gimp_context_buffer_dirty,
3533 context);
3534 g_clear_object (&context->buffer);
3535
3536 if (! gimp_container_frozen (container))
3537 gimp_context_buffer_list_thaw (container, context);
3538 }
3539 }
3540
3541 static void
gimp_context_real_set_buffer(GimpContext * context,GimpBuffer * buffer)3542 gimp_context_real_set_buffer (GimpContext *context,
3543 GimpBuffer *buffer)
3544 {
3545 if (context->buffer == buffer)
3546 return;
3547
3548 if (context->buffer_name)
3549 {
3550 g_clear_pointer (&context->buffer_name, g_free);
3551 }
3552
3553 if (context->buffer)
3554 g_signal_handlers_disconnect_by_func (context->buffer,
3555 gimp_context_buffer_dirty,
3556 context);
3557
3558 g_set_object (&context->buffer, buffer);
3559
3560 if (buffer)
3561 {
3562 g_signal_connect_object (buffer, "name-changed",
3563 G_CALLBACK (gimp_context_buffer_dirty),
3564 context,
3565 0);
3566
3567 context->buffer_name = g_strdup (gimp_object_get_name (buffer));
3568 }
3569
3570 g_object_notify (G_OBJECT (context), "buffer");
3571 gimp_context_buffer_changed (context);
3572 }
3573
3574
3575 /*****************************************************************************/
3576 /* imagefile ***************************************************************/
3577
3578 GimpImagefile *
gimp_context_get_imagefile(GimpContext * context)3579 gimp_context_get_imagefile (GimpContext *context)
3580 {
3581 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3582
3583 return context->imagefile;
3584 }
3585
3586 void
gimp_context_set_imagefile(GimpContext * context,GimpImagefile * imagefile)3587 gimp_context_set_imagefile (GimpContext *context,
3588 GimpImagefile *imagefile)
3589 {
3590 g_return_if_fail (GIMP_IS_CONTEXT (context));
3591 g_return_if_fail (imagefile == NULL || GIMP_IS_IMAGEFILE (imagefile));
3592
3593 context_find_defined (context, GIMP_CONTEXT_PROP_IMAGEFILE);
3594
3595 gimp_context_real_set_imagefile (context, imagefile);
3596 }
3597
3598 void
gimp_context_imagefile_changed(GimpContext * context)3599 gimp_context_imagefile_changed (GimpContext *context)
3600 {
3601 g_return_if_fail (GIMP_IS_CONTEXT (context));
3602
3603 g_signal_emit (context,
3604 gimp_context_signals[IMAGEFILE_CHANGED], 0,
3605 context->imagefile);
3606 }
3607
3608 static void
gimp_context_imagefile_dirty(GimpImagefile * imagefile,GimpContext * context)3609 gimp_context_imagefile_dirty (GimpImagefile *imagefile,
3610 GimpContext *context)
3611 {
3612 g_free (context->imagefile_name);
3613 context->imagefile_name = g_strdup (gimp_object_get_name (imagefile));
3614
3615 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3616 GIMP_CONTEXT_PROP_IMAGEFILE);
3617 }
3618
3619 static void
gimp_context_imagefile_list_thaw(GimpContainer * container,GimpContext * context)3620 gimp_context_imagefile_list_thaw (GimpContainer *container,
3621 GimpContext *context)
3622 {
3623 GimpImagefile *imagefile;
3624
3625 imagefile = gimp_context_find_object (context, container,
3626 context->imagefile_name,
3627 NULL);
3628
3629 if (imagefile)
3630 {
3631 gimp_context_real_set_imagefile (context, imagefile);
3632 }
3633 else
3634 {
3635 g_object_notify (G_OBJECT (context), "imagefile");
3636 gimp_context_imagefile_changed (context);
3637 }
3638 }
3639
3640 static void
gimp_context_imagefile_removed(GimpContainer * container,GimpImagefile * imagefile,GimpContext * context)3641 gimp_context_imagefile_removed (GimpContainer *container,
3642 GimpImagefile *imagefile,
3643 GimpContext *context)
3644 {
3645 if (imagefile == context->imagefile)
3646 {
3647 g_signal_handlers_disconnect_by_func (context->imagefile,
3648 gimp_context_imagefile_dirty,
3649 context);
3650 g_clear_object (&context->imagefile);
3651
3652 if (! gimp_container_frozen (container))
3653 gimp_context_imagefile_list_thaw (container, context);
3654 }
3655 }
3656
3657 static void
gimp_context_real_set_imagefile(GimpContext * context,GimpImagefile * imagefile)3658 gimp_context_real_set_imagefile (GimpContext *context,
3659 GimpImagefile *imagefile)
3660 {
3661 if (context->imagefile == imagefile)
3662 return;
3663
3664 if (context->imagefile_name)
3665 {
3666 g_clear_pointer (&context->imagefile_name, g_free);
3667 }
3668
3669 if (context->imagefile)
3670 g_signal_handlers_disconnect_by_func (context->imagefile,
3671 gimp_context_imagefile_dirty,
3672 context);
3673
3674 g_set_object (&context->imagefile, imagefile);
3675
3676 if (imagefile)
3677 {
3678 g_signal_connect_object (imagefile, "name-changed",
3679 G_CALLBACK (gimp_context_imagefile_dirty),
3680 context,
3681 0);
3682
3683 context->imagefile_name = g_strdup (gimp_object_get_name (imagefile));
3684 }
3685
3686 g_object_notify (G_OBJECT (context), "imagefile");
3687 gimp_context_imagefile_changed (context);
3688 }
3689
3690
3691 /*****************************************************************************/
3692 /* template ***************************************************************/
3693
3694 GimpTemplate *
gimp_context_get_template(GimpContext * context)3695 gimp_context_get_template (GimpContext *context)
3696 {
3697 g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
3698
3699 return context->template;
3700 }
3701
3702 void
gimp_context_set_template(GimpContext * context,GimpTemplate * template)3703 gimp_context_set_template (GimpContext *context,
3704 GimpTemplate *template)
3705 {
3706 g_return_if_fail (GIMP_IS_CONTEXT (context));
3707 g_return_if_fail (template == NULL || GIMP_IS_TEMPLATE (template));
3708
3709 context_find_defined (context, GIMP_CONTEXT_PROP_TEMPLATE);
3710
3711 gimp_context_real_set_template (context, template);
3712 }
3713
3714 void
gimp_context_template_changed(GimpContext * context)3715 gimp_context_template_changed (GimpContext *context)
3716 {
3717 g_return_if_fail (GIMP_IS_CONTEXT (context));
3718
3719 g_signal_emit (context,
3720 gimp_context_signals[TEMPLATE_CHANGED], 0,
3721 context->template);
3722 }
3723
3724 static void
gimp_context_template_dirty(GimpTemplate * template,GimpContext * context)3725 gimp_context_template_dirty (GimpTemplate *template,
3726 GimpContext *context)
3727 {
3728 g_free (context->template_name);
3729 context->template_name = g_strdup (gimp_object_get_name (template));
3730
3731 g_signal_emit (context, gimp_context_signals[PROP_NAME_CHANGED], 0,
3732 GIMP_CONTEXT_PROP_TEMPLATE);
3733 }
3734
3735 static void
gimp_context_template_list_thaw(GimpContainer * container,GimpContext * context)3736 gimp_context_template_list_thaw (GimpContainer *container,
3737 GimpContext *context)
3738 {
3739 GimpTemplate *template;
3740
3741 template = gimp_context_find_object (context, container,
3742 context->template_name,
3743 NULL);
3744
3745 if (template)
3746 {
3747 gimp_context_real_set_template (context, template);
3748 }
3749 else
3750 {
3751 g_object_notify (G_OBJECT (context), "template");
3752 gimp_context_template_changed (context);
3753 }
3754 }
3755
3756 static void
gimp_context_template_removed(GimpContainer * container,GimpTemplate * template,GimpContext * context)3757 gimp_context_template_removed (GimpContainer *container,
3758 GimpTemplate *template,
3759 GimpContext *context)
3760 {
3761 if (template == context->template)
3762 {
3763 g_signal_handlers_disconnect_by_func (context->template,
3764 gimp_context_template_dirty,
3765 context);
3766 g_clear_object (&context->template);
3767
3768 if (! gimp_container_frozen (container))
3769 gimp_context_template_list_thaw (container, context);
3770 }
3771 }
3772
3773 static void
gimp_context_real_set_template(GimpContext * context,GimpTemplate * template)3774 gimp_context_real_set_template (GimpContext *context,
3775 GimpTemplate *template)
3776 {
3777 if (context->template == template)
3778 return;
3779
3780 if (context->template_name)
3781 {
3782 g_clear_pointer (&context->template_name, g_free);
3783 }
3784
3785 if (context->template)
3786 g_signal_handlers_disconnect_by_func (context->template,
3787 gimp_context_template_dirty,
3788 context);
3789
3790 g_set_object (&context->template, template);
3791
3792 if (template)
3793 {
3794 g_signal_connect_object (template, "name-changed",
3795 G_CALLBACK (gimp_context_template_dirty),
3796 context,
3797 0);
3798
3799 context->template_name = g_strdup (gimp_object_get_name (template));
3800 }
3801
3802 g_object_notify (G_OBJECT (context), "template");
3803 gimp_context_template_changed (context);
3804 }
3805
3806
3807 /*****************************************************************************/
3808 /* utility functions *******************************************************/
3809
3810 static gpointer
gimp_context_find_object(GimpContext * context,GimpContainer * container,const gchar * object_name,gpointer standard_object)3811 gimp_context_find_object (GimpContext *context,
3812 GimpContainer *container,
3813 const gchar *object_name,
3814 gpointer standard_object)
3815 {
3816 GimpObject *object = NULL;
3817
3818 if (object_name)
3819 object = gimp_container_get_child_by_name (container, object_name);
3820
3821 if (! object && ! gimp_container_is_empty (container))
3822 object = gimp_container_get_child_by_index (container, 0);
3823
3824 if (! object)
3825 object = standard_object;
3826
3827 return object;
3828 }
3829