1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <string.h>
21
22 #include <gegl.h>
23 #include <gtk/gtk.h>
24
25 #include "libgimpmath/gimpmath.h"
26 #include "libgimpbase/gimpbase.h"
27 #include "libgimpconfig/gimpconfig.h"
28 #include "libgimpwidgets/gimpwidgets.h"
29
30 #include "widgets-types.h"
31
32 #include "config/gimpcoreconfig.h"
33
34 #include "gegl/gimp-babl.h"
35
36 #include "core/gimp.h"
37 #include "core/gimptemplate.h"
38
39 #include "gimppropwidgets.h"
40 #include "gimptemplateeditor.h"
41 #include "gimpwidgets-utils.h"
42
43 #include "gimp-intl.h"
44
45
46 #define SB_WIDTH 8
47 #define MAX_COMMENT_LENGTH 512 /* arbitrary */
48
49
50 enum
51 {
52 PROP_0,
53 PROP_GIMP,
54 PROP_TEMPLATE
55 };
56
57
58 typedef struct _GimpTemplateEditorPrivate GimpTemplateEditorPrivate;
59
60 struct _GimpTemplateEditorPrivate
61 {
62 Gimp *gimp;
63
64 GimpTemplate *template;
65
66 GtkWidget *aspect_button;
67 gboolean block_aspect;
68
69 GtkWidget *expander;
70 GtkWidget *size_se;
71 GtkWidget *memsize_label;
72 GtkWidget *pixel_label;
73 GtkWidget *more_label;
74 GtkWidget *resolution_se;
75 GtkWidget *chain_button;
76 GtkWidget *precision_combo;
77 GtkWidget *profile_combo;
78 };
79
80 #define GET_PRIVATE(editor) \
81 ((GimpTemplateEditorPrivate *) gimp_template_editor_get_instance_private ((GimpTemplateEditor *) (editor)))
82
83
84 static void gimp_template_editor_constructed (GObject *object);
85 static void gimp_template_editor_finalize (GObject *object);
86 static void gimp_template_editor_set_property (GObject *object,
87 guint property_id,
88 const GValue *value,
89 GParamSpec *pspec);
90 static void gimp_template_editor_get_property (GObject *object,
91 guint property_id,
92 GValue *value,
93 GParamSpec *pspec);
94
95 static void gimp_template_editor_precision_changed (GtkWidget *widget,
96 GimpTemplateEditor *editor);
97 static void gimp_template_editor_aspect_callback (GtkWidget *widget,
98 GimpTemplateEditor *editor);
99 static void gimp_template_editor_template_notify (GimpTemplate *template,
100 GParamSpec *param_spec,
101 GimpTemplateEditor *editor);
102
103
G_DEFINE_TYPE_WITH_PRIVATE(GimpTemplateEditor,gimp_template_editor,GTK_TYPE_BOX)104 G_DEFINE_TYPE_WITH_PRIVATE (GimpTemplateEditor, gimp_template_editor,
105 GTK_TYPE_BOX)
106
107 #define parent_class gimp_template_editor_parent_class
108
109
110 static void
111 gimp_template_editor_class_init (GimpTemplateEditorClass *klass)
112 {
113 GObjectClass *object_class = G_OBJECT_CLASS (klass);
114
115 object_class->constructed = gimp_template_editor_constructed;
116 object_class->finalize = gimp_template_editor_finalize;
117 object_class->set_property = gimp_template_editor_set_property;
118 object_class->get_property = gimp_template_editor_get_property;
119
120 g_object_class_install_property (object_class, PROP_GIMP,
121 g_param_spec_object ("gimp", NULL, NULL,
122 GIMP_TYPE_GIMP,
123 GIMP_PARAM_READWRITE |
124 G_PARAM_CONSTRUCT_ONLY));
125
126 g_object_class_install_property (object_class, PROP_TEMPLATE,
127 g_param_spec_object ("template", NULL, NULL,
128 GIMP_TYPE_TEMPLATE,
129 GIMP_PARAM_READWRITE |
130 G_PARAM_CONSTRUCT_ONLY));
131 }
132
133 static void
gimp_template_editor_init(GimpTemplateEditor * editor)134 gimp_template_editor_init (GimpTemplateEditor *editor)
135 {
136 gtk_orientable_set_orientation (GTK_ORIENTABLE (editor),
137 GTK_ORIENTATION_VERTICAL);
138
139 gtk_box_set_spacing (GTK_BOX (editor), 12);
140 }
141
142 static void
gimp_template_editor_constructed(GObject * object)143 gimp_template_editor_constructed (GObject *object)
144 {
145 GimpTemplateEditor *editor = GIMP_TEMPLATE_EDITOR (object);
146 GimpTemplateEditorPrivate *private = GET_PRIVATE (object);
147 GimpTemplate *template;
148 GtkWidget *aspect_box;
149 GtkWidget *frame;
150 GtkWidget *hbox;
151 GtkWidget *vbox;
152 GtkWidget *table;
153 GtkWidget *label;
154 GtkAdjustment *adjustment;
155 GtkWidget *width;
156 GtkWidget *height;
157 GtkWidget *xres;
158 GtkWidget *yres;
159 GtkWidget *combo;
160 GtkWidget *toggle;
161 GtkWidget *scrolled_window;
162 GtkWidget *text_view;
163 GtkTextBuffer *text_buffer;
164 GtkListStore *store;
165 GList *focus_chain = NULL;
166 gchar *text;
167 gint row;
168
169 G_OBJECT_CLASS (parent_class)->constructed (object);
170
171 gimp_assert (private->gimp != NULL);
172 gimp_assert (private->template != NULL);
173
174 template = private->template;
175
176 /* Image size frame */
177 frame = gimp_frame_new (_("Image Size"));
178 gtk_box_pack_start (GTK_BOX (editor), frame, FALSE, FALSE, 0);
179 gtk_widget_show (frame);
180
181 table = gtk_table_new (3, 2, FALSE);
182 gtk_table_set_col_spacing (GTK_TABLE (table), 0, 6);
183 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
184 gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
185 gtk_container_add (GTK_CONTAINER (frame), table);
186 gtk_widget_show (table);
187
188 adjustment = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
189 width = gimp_spin_button_new (adjustment, 1.0, 2);
190 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (width), TRUE);
191 gtk_entry_set_width_chars (GTK_ENTRY (width), SB_WIDTH);
192
193 adjustment = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
194 height = gimp_spin_button_new (adjustment, 1.0, 2);
195 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (height), TRUE);
196 gtk_entry_set_width_chars (GTK_ENTRY (height), SB_WIDTH);
197
198 /* the image size labels */
199 label = gtk_label_new_with_mnemonic (_("_Width:"));
200 gtk_label_set_xalign (GTK_LABEL (label), 0.0);
201 gtk_label_set_mnemonic_widget (GTK_LABEL (label), width);
202 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
203 GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
204 gtk_widget_show (label);
205
206 label = gtk_label_new_with_mnemonic (_("H_eight:"));
207 gtk_label_set_xalign (GTK_LABEL (label), 0.0);
208 gtk_label_set_mnemonic_widget (GTK_LABEL (label), height);
209 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
210 GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
211 gtk_widget_show (label);
212
213 /* create the sizeentry which keeps it all together */
214 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
215 gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, 0, 2);
216 gtk_widget_show (hbox);
217
218 private->size_se = gimp_size_entry_new (0,
219 gimp_template_get_unit (template),
220 _("%p"),
221 TRUE, FALSE, FALSE, SB_WIDTH,
222 GIMP_SIZE_ENTRY_UPDATE_SIZE);
223
224 gtk_table_set_row_spacing (GTK_TABLE (private->size_se), 0, 2);
225 gtk_table_set_col_spacing (GTK_TABLE (private->size_se), 1, 6);
226
227 gtk_box_pack_start (GTK_BOX (hbox), private->size_se, FALSE, FALSE, 0);
228 gtk_widget_show (private->size_se);
229
230 gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->size_se),
231 GTK_SPIN_BUTTON (height), NULL);
232 gtk_table_attach_defaults (GTK_TABLE (private->size_se), height, 0, 1, 1, 2);
233 gtk_widget_show (height);
234
235 gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->size_se),
236 GTK_SPIN_BUTTON (width), NULL);
237 gtk_table_attach_defaults (GTK_TABLE (private->size_se), width, 0, 1, 0, 1);
238 gtk_widget_show (width);
239
240 gimp_prop_coordinates_connect (G_OBJECT (template),
241 "width", "height", "unit",
242 private->size_se, NULL,
243 gimp_template_get_resolution_x (template),
244 gimp_template_get_resolution_y (template));
245
246 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
247 gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 3, 2, 3);
248 gtk_widget_show (hbox);
249
250 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
251 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
252 gtk_widget_show (vbox);
253
254 aspect_box = gimp_enum_icon_box_new (GIMP_TYPE_ASPECT_TYPE,
255 "gimp", GTK_ICON_SIZE_MENU,
256 G_CALLBACK (gimp_template_editor_aspect_callback),
257 editor,
258 &private->aspect_button);
259 gtk_widget_hide (private->aspect_button); /* hide "square" */
260
261 gtk_box_pack_start (GTK_BOX (vbox), aspect_box, FALSE, FALSE, 0);
262 gtk_widget_show (aspect_box);
263
264 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
265 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
266 gtk_widget_show (vbox);
267
268 private->pixel_label = gtk_label_new (NULL);
269 gimp_label_set_attributes (GTK_LABEL (private->pixel_label),
270 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
271 -1);
272 gtk_label_set_xalign (GTK_LABEL (private->pixel_label), 0.0);
273 gtk_box_pack_start (GTK_BOX (vbox), private->pixel_label, FALSE, FALSE, 0);
274 gtk_widget_show (private->pixel_label);
275
276 private->more_label = gtk_label_new (NULL);
277 gimp_label_set_attributes (GTK_LABEL (private->more_label),
278 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
279 -1);
280 gtk_label_set_xalign (GTK_LABEL (private->more_label), 0.0);
281 gtk_box_pack_start (GTK_BOX (vbox), private->more_label, FALSE, FALSE, 0);
282 gtk_widget_show (private->more_label);
283
284 #ifdef ENABLE_MEMSIZE_LABEL
285 private->memsize_label = gtk_label_new (NULL);
286 gimp_label_set_attributes (GTK_LABEL (private->memsize_label),
287 PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
288 PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
289 -1);
290 gtk_label_set_xalign (GTK_LABEL (private->memsize_label), 0.0);
291 gtk_box_pack_start (GTK_BOX (vbox), private->memsize_label, FALSE, FALSE, 0);
292 gtk_widget_show (private->memsize_label);
293 #endif
294
295 text = g_strdup_printf ("<b>%s</b>", _("_Advanced Options"));
296 private->expander = g_object_new (GTK_TYPE_EXPANDER,
297 "label", text,
298 "use-markup", TRUE,
299 "use-underline", TRUE,
300 NULL);
301 g_free (text);
302
303 gtk_box_pack_start (GTK_BOX (editor), private->expander, TRUE, TRUE, 0);
304 gtk_widget_show (private->expander);
305
306 frame = gimp_frame_new ("<expander>");
307 gtk_container_add (GTK_CONTAINER (private->expander), frame);
308 gtk_widget_show (frame);
309
310 table = gtk_table_new (9, 2, FALSE);
311 gtk_table_set_col_spacing (GTK_TABLE (table), 0, 6);
312 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
313 gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
314 gtk_container_add (GTK_CONTAINER (frame), table);
315 gtk_widget_show (table);
316
317 adjustment = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
318 xres = gimp_spin_button_new (adjustment, 1.0, 2);
319 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (xres), TRUE);
320 gtk_entry_set_width_chars (GTK_ENTRY (xres), SB_WIDTH);
321
322 adjustment = (GtkAdjustment *) gtk_adjustment_new (1, 1, 1, 1, 10, 0);
323 yres = gimp_spin_button_new (adjustment, 1.0, 2);
324 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (yres), TRUE);
325 gtk_entry_set_width_chars (GTK_ENTRY (yres), SB_WIDTH);
326
327 /* the resolution labels */
328 label = gtk_label_new_with_mnemonic (_("_X resolution:"));
329 gtk_label_set_xalign (GTK_LABEL (label), 0.0);
330 gtk_label_set_mnemonic_widget (GTK_LABEL (label), xres);
331 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
332 GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
333 gtk_widget_show (label);
334
335 label = gtk_label_new_with_mnemonic (_("_Y resolution:"));
336 gtk_label_set_xalign (GTK_LABEL (label), 0.0);
337 gtk_label_set_mnemonic_widget (GTK_LABEL (label), yres);
338 gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
339 GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
340 gtk_widget_show (label);
341
342 /* the resolution sizeentry */
343 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
344 gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, 0, 2);
345 gtk_widget_show (hbox);
346
347 private->resolution_se =
348 gimp_size_entry_new (0,
349 gimp_template_get_resolution_unit (template),
350 _("pixels/%s"),
351 FALSE, FALSE, FALSE, SB_WIDTH,
352 GIMP_SIZE_ENTRY_UPDATE_RESOLUTION);
353
354 gtk_table_set_row_spacing (GTK_TABLE (private->resolution_se), 0, 2);
355 gtk_table_set_col_spacing (GTK_TABLE (private->resolution_se), 1, 2);
356 gtk_table_set_col_spacing (GTK_TABLE (private->resolution_se), 2, 2);
357
358 gtk_box_pack_start (GTK_BOX (hbox), private->resolution_se, FALSE, FALSE, 0);
359 gtk_widget_show (private->resolution_se);
360
361 gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->resolution_se),
362 GTK_SPIN_BUTTON (yres), NULL);
363 gtk_table_attach_defaults (GTK_TABLE (private->resolution_se), yres,
364 0, 1, 1, 2);
365 gtk_widget_show (yres);
366
367 gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->resolution_se),
368 GTK_SPIN_BUTTON (xres), NULL);
369 gtk_table_attach_defaults (GTK_TABLE (private->resolution_se), xres,
370 0, 1, 0, 1);
371 gtk_widget_show (xres);
372
373 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 0,
374 gimp_template_get_resolution_x (template),
375 FALSE);
376 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 1,
377 gimp_template_get_resolution_y (template),
378 FALSE);
379
380 /* the resolution chainbutton */
381 private->chain_button = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
382 gtk_table_attach_defaults (GTK_TABLE (private->resolution_se),
383 private->chain_button, 1, 2, 0, 2);
384 gtk_widget_show (private->chain_button);
385
386 gimp_prop_coordinates_connect (G_OBJECT (template),
387 "xresolution", "yresolution",
388 "resolution-unit",
389 private->resolution_se, private->chain_button,
390 1.0, 1.0);
391
392 focus_chain = g_list_prepend (focus_chain,
393 GIMP_SIZE_ENTRY (private->resolution_se)->unitmenu);
394 focus_chain = g_list_prepend (focus_chain, private->chain_button);
395 focus_chain = g_list_prepend (focus_chain, yres);
396 focus_chain = g_list_prepend (focus_chain, xres);
397
398 gtk_container_set_focus_chain (GTK_CONTAINER (private->resolution_se),
399 focus_chain);
400 g_list_free (focus_chain);
401
402 row = 2;
403
404 combo = gimp_prop_enum_combo_box_new (G_OBJECT (template),
405 "image-type",
406 GIMP_RGB, GIMP_GRAY);
407 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
408 _("Color _space:"), 0.0, 0.5,
409 combo, 1, FALSE);
410
411 /* construct the precision combo manually, instead of using
412 * gimp_prop_enum_combo_box_new(), so that we only reset the gamma combo when
413 * the precision is changed through the ui. see issue #3025.
414 */
415 store = gimp_enum_store_new_with_range (GIMP_TYPE_COMPONENT_TYPE,
416 GIMP_COMPONENT_TYPE_U8,
417 GIMP_COMPONENT_TYPE_FLOAT);
418
419 private->precision_combo = g_object_new (GIMP_TYPE_ENUM_COMBO_BOX,
420 "model", store,
421 NULL);
422 g_object_unref (store);
423
424 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
425 _("_Precision:"), 0.0, 0.5,
426 private->precision_combo, 1, FALSE);
427
428 gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (private->precision_combo),
429 gimp_babl_component_type (
430 gimp_template_get_precision (template)));
431
432 g_signal_connect (private->precision_combo, "changed",
433 G_CALLBACK (gimp_template_editor_precision_changed),
434 editor);
435
436 combo = gimp_prop_boolean_combo_box_new (G_OBJECT (template),
437 "linear",
438 _("Linear light"),
439 _("Perceptual gamma (sRGB)"));
440 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
441 _("_Gamma:"), 0.0, 0.5,
442 combo, 1, FALSE);
443
444 toggle = gimp_prop_check_button_new (G_OBJECT (template),
445 "color-managed",
446 _("Color _manage this image"));
447 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
448 NULL, 0.0, 0.5,
449 toggle, 1, FALSE);
450
451 private->profile_combo =
452 gimp_prop_profile_combo_box_new (G_OBJECT (template),
453 "color-profile",
454 NULL,
455 _("Choose A Color Profile"),
456 G_OBJECT (private->gimp->config),
457 "color-profile-path");
458 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
459 _("Co_lor profile:"), 0.0, 0.5,
460 private->profile_combo, 1, FALSE);
461
462 combo = gimp_prop_enum_combo_box_new (G_OBJECT (template),
463 "fill-type",
464 0, 0);
465 gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
466 _("_Fill with:"), 0.0, 0.5,
467 combo, 1, FALSE);
468
469 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
470 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
471 GTK_SHADOW_IN);
472 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
473 GTK_POLICY_AUTOMATIC,
474 GTK_POLICY_AUTOMATIC);
475 label = gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
476 _("Comme_nt:"), 0.0, 0.0,
477 scrolled_window, 1, FALSE);
478
479 text_buffer = gimp_prop_text_buffer_new (G_OBJECT (template),
480 "comment", MAX_COMMENT_LENGTH);
481
482 text_view = gtk_text_view_new_with_buffer (text_buffer);
483 g_object_unref (text_buffer);
484
485 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
486 gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
487 gtk_widget_show (text_view);
488
489 gtk_label_set_mnemonic_widget (GTK_LABEL (label), text_view);
490
491 g_signal_connect_object (template, "notify",
492 G_CALLBACK (gimp_template_editor_template_notify),
493 editor, 0);
494
495 /* call the notify callback once to get the labels set initially */
496 gimp_template_editor_template_notify (template, NULL, editor);
497 }
498
499 static void
gimp_template_editor_finalize(GObject * object)500 gimp_template_editor_finalize (GObject *object)
501 {
502 GimpTemplateEditorPrivate *private = GET_PRIVATE (object);
503
504 g_clear_object (&private->template);
505
506 G_OBJECT_CLASS (parent_class)->finalize (object);
507 }
508
509 static void
gimp_template_editor_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)510 gimp_template_editor_set_property (GObject *object,
511 guint property_id,
512 const GValue *value,
513 GParamSpec *pspec)
514 {
515 GimpTemplateEditorPrivate *private = GET_PRIVATE (object);
516
517 switch (property_id)
518 {
519 case PROP_GIMP:
520 private->gimp = g_value_get_object (value); /* don't ref */
521 break;
522
523 case PROP_TEMPLATE:
524 private->template = g_value_dup_object (value);
525 break;
526
527 default:
528 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
529 break;
530 }
531 }
532
533 static void
gimp_template_editor_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)534 gimp_template_editor_get_property (GObject *object,
535 guint property_id,
536 GValue *value,
537 GParamSpec *pspec)
538 {
539 GimpTemplateEditorPrivate *private = GET_PRIVATE (object);
540
541 switch (property_id)
542 {
543 case PROP_GIMP:
544 g_value_set_object (value, private->gimp);
545 break;
546
547 case PROP_TEMPLATE:
548 g_value_set_object (value, private->template);
549 break;
550
551 default:
552 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
553 break;
554 }
555 }
556
557 GtkWidget *
gimp_template_editor_new(GimpTemplate * template,Gimp * gimp,gboolean edit_template)558 gimp_template_editor_new (GimpTemplate *template,
559 Gimp *gimp,
560 gboolean edit_template)
561 {
562 GimpTemplateEditor *editor;
563 GimpTemplateEditorPrivate *private;
564
565 g_return_val_if_fail (GIMP_IS_TEMPLATE (template), NULL);
566 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
567
568 editor = g_object_new (GIMP_TYPE_TEMPLATE_EDITOR,
569 "gimp", gimp,
570 "template", template,
571 NULL);
572
573 private = GET_PRIVATE (editor);
574
575 if (edit_template)
576 {
577 GtkWidget *table;
578 GtkWidget *entry;
579 GtkWidget *icon_picker;
580
581 table = gtk_table_new (2, 2, FALSE);
582 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
583 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
584 gtk_box_pack_start (GTK_BOX (editor), table, FALSE, FALSE, 0);
585 gtk_box_reorder_child (GTK_BOX (editor), table, 0);
586 gtk_widget_show (table);
587
588 entry = gimp_prop_entry_new (G_OBJECT (private->template), "name", 128);
589
590 gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
591 _("_Name:"), 1.0, 0.5,
592 entry, 1, FALSE);
593
594 icon_picker = gimp_prop_icon_picker_new (GIMP_VIEWABLE (private->template),
595 gimp);
596 gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
597 _("_Icon:"), 1.0, 0.5,
598 icon_picker, 1, TRUE);
599 }
600
601 return GTK_WIDGET (editor);
602 }
603
604 GimpTemplate *
gimp_template_editor_get_template(GimpTemplateEditor * editor)605 gimp_template_editor_get_template (GimpTemplateEditor *editor)
606 {
607 g_return_val_if_fail (GIMP_IS_TEMPLATE_EDITOR (editor), NULL);
608
609 return GET_PRIVATE (editor)->template;
610 }
611
612 void
gimp_template_editor_show_advanced(GimpTemplateEditor * editor,gboolean expanded)613 gimp_template_editor_show_advanced (GimpTemplateEditor *editor,
614 gboolean expanded)
615 {
616 GimpTemplateEditorPrivate *private;
617
618 g_return_if_fail (GIMP_IS_TEMPLATE_EDITOR (editor));
619
620 private = GET_PRIVATE (editor);
621
622 gtk_expander_set_expanded (GTK_EXPANDER (private->expander), expanded);
623 }
624
625 GtkWidget *
gimp_template_editor_get_size_se(GimpTemplateEditor * editor)626 gimp_template_editor_get_size_se (GimpTemplateEditor *editor)
627 {
628 g_return_val_if_fail (GIMP_IS_TEMPLATE_EDITOR (editor), NULL);
629
630 return GET_PRIVATE (editor)->size_se;
631 }
632
633 GtkWidget *
gimp_template_editor_get_resolution_se(GimpTemplateEditor * editor)634 gimp_template_editor_get_resolution_se (GimpTemplateEditor *editor)
635 {
636 g_return_val_if_fail (GIMP_IS_TEMPLATE_EDITOR (editor), NULL);
637
638 return GET_PRIVATE (editor)->resolution_se;
639 }
640
641 GtkWidget *
gimp_template_editor_get_resolution_chain(GimpTemplateEditor * editor)642 gimp_template_editor_get_resolution_chain (GimpTemplateEditor *editor)
643 {
644 g_return_val_if_fail (GIMP_IS_TEMPLATE_EDITOR (editor), NULL);
645
646 return GET_PRIVATE (editor)->chain_button;
647 }
648
649
650 /* private functions */
651
652 static void
gimp_template_editor_precision_changed(GtkWidget * widget,GimpTemplateEditor * editor)653 gimp_template_editor_precision_changed (GtkWidget *widget,
654 GimpTemplateEditor *editor)
655 {
656 GimpTemplateEditorPrivate *private = GET_PRIVATE (editor);
657 GimpComponentType component_type;
658
659 gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget),
660 (gint *) &component_type);
661
662 g_object_set (private->template,
663 "component-type", component_type,
664 NULL);
665
666 /* when changing this logic, also change the same switch()
667 * in convert-precision-dialog.c
668 */
669 switch (component_type)
670 {
671 case GIMP_COMPONENT_TYPE_U8:
672 /* default to gamma for 8 bit */
673 g_object_set (private->template,
674 "linear", FALSE,
675 NULL);
676 break;
677
678 case GIMP_COMPONENT_TYPE_U16:
679 case GIMP_COMPONENT_TYPE_U32:
680 default:
681 /* leave gamma alone by default for 16/32 bit int */
682 break;
683
684 case GIMP_COMPONENT_TYPE_HALF:
685 case GIMP_COMPONENT_TYPE_FLOAT:
686 case GIMP_COMPONENT_TYPE_DOUBLE:
687 /* default to linear for floating point */
688 g_object_set (private->template,
689 "linear", TRUE,
690 NULL);
691 break;
692 }
693 }
694
695 static void
gimp_template_editor_set_pixels(GimpTemplateEditor * editor,GimpTemplate * template)696 gimp_template_editor_set_pixels (GimpTemplateEditor *editor,
697 GimpTemplate *template)
698 {
699 GimpTemplateEditorPrivate *private = GET_PRIVATE (editor);
700 gchar *text;
701
702 text = g_strdup_printf (ngettext ("%d × %d pixel",
703 "%d × %d pixels",
704 gimp_template_get_height (template)),
705 gimp_template_get_width (template),
706 gimp_template_get_height (template));
707 gtk_label_set_text (GTK_LABEL (private->pixel_label), text);
708 g_free (text);
709 }
710
711 static void
gimp_template_editor_aspect_callback(GtkWidget * widget,GimpTemplateEditor * editor)712 gimp_template_editor_aspect_callback (GtkWidget *widget,
713 GimpTemplateEditor *editor)
714 {
715 GimpTemplateEditorPrivate *private = GET_PRIVATE (editor);
716
717 if (! private->block_aspect &&
718 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
719 {
720 GimpTemplate *template = private->template;
721 gint width = gimp_template_get_width (template);
722 gint height = gimp_template_get_height (template);
723 gdouble xresolution = gimp_template_get_resolution_x (template);
724 gdouble yresolution = gimp_template_get_resolution_y (template);
725
726 if (width == height)
727 {
728 private->block_aspect = TRUE;
729 gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (private->aspect_button),
730 GIMP_ASPECT_SQUARE);
731 private->block_aspect = FALSE;
732 return;
733 }
734
735 g_signal_handlers_block_by_func (template,
736 gimp_template_editor_template_notify,
737 editor);
738
739 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 0,
740 yresolution, FALSE);
741 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 1,
742 xresolution, FALSE);
743
744 g_object_set (template,
745 "width", height,
746 "height", width,
747 "xresolution", yresolution,
748 "yresolution", xresolution,
749 NULL);
750
751 g_signal_handlers_unblock_by_func (template,
752 gimp_template_editor_template_notify,
753 editor);
754
755 gimp_template_editor_set_pixels (editor, template);
756 }
757 }
758
759 static void
gimp_template_editor_template_notify(GimpTemplate * template,GParamSpec * param_spec,GimpTemplateEditor * editor)760 gimp_template_editor_template_notify (GimpTemplate *template,
761 GParamSpec *param_spec,
762 GimpTemplateEditor *editor)
763 {
764 GimpTemplateEditorPrivate *private = GET_PRIVATE (editor);
765 GimpAspectType aspect;
766 const gchar *desc;
767 gchar *text;
768 gint width;
769 gint height;
770 gint xres;
771 gint yres;
772
773 if (param_spec)
774 {
775 if (! strcmp (param_spec->name, "xresolution"))
776 {
777 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 0,
778 gimp_template_get_resolution_x (template),
779 FALSE);
780 }
781 else if (! strcmp (param_spec->name, "yresolution"))
782 {
783 gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->size_se), 1,
784 gimp_template_get_resolution_y (template),
785 FALSE);
786 }
787 else if (! strcmp (param_spec->name, "component-type"))
788 {
789 g_signal_handlers_block_by_func (private->precision_combo,
790 gimp_template_editor_precision_changed,
791 editor);
792
793 gimp_int_combo_box_set_active (
794 GIMP_INT_COMBO_BOX (private->precision_combo),
795 gimp_babl_component_type (gimp_template_get_precision (template)));
796
797 g_signal_handlers_unblock_by_func (private->precision_combo,
798 gimp_template_editor_precision_changed,
799 editor);
800 }
801 }
802
803 #ifdef ENABLE_MEMSIZE_LABEL
804 text = g_format_size (gimp_template_get_initial_size (template));
805 gtk_label_set_text (GTK_LABEL (private->memsize_label), text);
806 g_free (text);
807 #endif
808
809 gimp_template_editor_set_pixels (editor, template);
810
811 width = gimp_template_get_width (template);
812 height = gimp_template_get_height (template);
813
814 if (width > height)
815 aspect = GIMP_ASPECT_LANDSCAPE;
816 else if (height > width)
817 aspect = GIMP_ASPECT_PORTRAIT;
818 else
819 aspect = GIMP_ASPECT_SQUARE;
820
821 private->block_aspect = TRUE;
822 gimp_int_radio_group_set_active (GTK_RADIO_BUTTON (private->aspect_button),
823 aspect);
824 private->block_aspect = FALSE;
825
826 gimp_enum_get_value (GIMP_TYPE_IMAGE_BASE_TYPE,
827 gimp_template_get_base_type (template),
828 NULL, NULL, &desc, NULL);
829
830 xres = ROUND (gimp_template_get_resolution_x (template));
831 yres = ROUND (gimp_template_get_resolution_y (template));
832
833 if (xres != yres)
834 text = g_strdup_printf (_("%d × %d ppi, %s"), xres, yres, desc);
835 else
836 text = g_strdup_printf (_("%d ppi, %s"), yres, desc);
837
838 gtk_label_set_text (GTK_LABEL (private->more_label), text);
839 g_free (text);
840
841 if (! param_spec ||
842 ! strcmp (param_spec->name, "image-type") ||
843 ! strcmp (param_spec->name, "precision"))
844 {
845 GtkListStore *profile_store;
846 GFile *profile;
847 gchar *filename;
848
849 filename = gimp_personal_rc_file ("profilerc");
850 profile_store = gimp_color_profile_store_new (filename);
851 g_free (filename);
852
853 gimp_color_profile_store_add_defaults (GIMP_COLOR_PROFILE_STORE (profile_store),
854 private->gimp->config->color_management,
855 gimp_template_get_base_type (template),
856 gimp_template_get_precision (template),
857 NULL);
858
859 gtk_combo_box_set_model (GTK_COMBO_BOX (private->profile_combo),
860 GTK_TREE_MODEL (profile_store));
861 g_object_unref (profile_store);
862
863 g_object_get (template,
864 "color-profile", &profile,
865 NULL);
866
867 gimp_color_profile_combo_box_set_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (private->profile_combo),
868 profile, NULL);
869
870 if (profile)
871 g_object_unref (profile);
872 }
873 }
874