1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 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 <gegl.h>
21 #include <gtk/gtk.h>
22
23 #include "libgimpwidgets/gimpwidgets.h"
24
25 #include "actions-types.h"
26
27 #include "config/gimpguiconfig.h"
28
29 #include "gegl/gimp-babl.h"
30
31 #include "core/gimp.h"
32 #include "core/gimpchannel.h"
33 #include "core/gimpcontext.h"
34 #include "core/gimpimage.h"
35 #include "core/gimpimage-color-profile.h"
36 #include "core/gimpitemstack.h"
37
38 #include "widgets/gimpactiongroup.h"
39 #include "widgets/gimphelp-ids.h"
40
41 #include "actions.h"
42 #include "image-actions.h"
43 #include "image-commands.h"
44
45 #include "gimp-intl.h"
46
47
48 static const GimpActionEntry image_actions[] =
49 {
50 { "image-menubar", NULL,
51 NC_("image-action", "Image Menu"), NULL, NULL, NULL,
52 GIMP_HELP_IMAGE_WINDOW },
53
54 { "image-popup", NULL,
55 NC_("image-action", "Image Menu"), NULL, NULL, NULL,
56 GIMP_HELP_IMAGE_WINDOW },
57
58 { "image-menu", NULL, NC_("image-action", "_Image") },
59 { "image-mode-menu", NULL, NC_("image-action", "_Mode") },
60 { "image-precision-menu", NULL, NC_("image-action", "Pr_ecision") },
61 #if PENDING_TRANSLATION
62 { "image-precision-menu", NULL, NC_("image-action", "_Encoding") },
63 #endif
64 { "image-color-management-menu", NULL, NC_("image-action",
65 "Color Ma_nagement") },
66 { "image-transform-menu", NULL, NC_("image-action", "_Transform") },
67 { "image-guides-menu", NULL, NC_("image-action", "_Guides") },
68 { "image-metadata-menu", NULL, NC_("image-action", "Meta_data") },
69
70 { "colors-menu", NULL, NC_("image-action", "_Colors") },
71 { "colors-info-menu", NULL, NC_("image-action", "I_nfo") },
72 { "colors-auto-menu", NULL, NC_("image-action", "_Auto") },
73 { "colors-map-menu", NULL, NC_("image-action", "_Map") },
74 { "colors-tone-mapping-menu", NULL, NC_("image-action", "_Tone Mapping") },
75 { "colors-components-menu", NULL, NC_("image-action", "C_omponents") },
76 { "colors-desaturate-menu", NULL, NC_("image-action", "D_esaturate") },
77
78 { "image-new", GIMP_ICON_DOCUMENT_NEW,
79 NC_("image-action", "_New..."), "<primary>N",
80 NC_("image-action", "Create a new image"),
81 image_new_cmd_callback,
82 GIMP_HELP_FILE_NEW },
83
84 { "image-duplicate", GIMP_ICON_OBJECT_DUPLICATE,
85 NC_("image-action", "_Duplicate"), "<primary>D",
86 NC_("image-action", "Create a duplicate of this image"),
87 image_duplicate_cmd_callback,
88 GIMP_HELP_IMAGE_DUPLICATE },
89
90 { "image-color-profile-assign", NULL,
91 NC_("image-action", "_Assign Color Profile..."), NULL,
92 NC_("image-action", "Set a color profile on the image"),
93 image_color_profile_assign_cmd_callback,
94 GIMP_HELP_IMAGE_COLOR_PROFILE_ASSIGN },
95
96 { "image-color-profile-convert", NULL,
97 NC_("image-action", "_Convert to Color Profile..."), NULL,
98 NC_("image-action", "Apply a color profile to the image"),
99 image_color_profile_convert_cmd_callback,
100 GIMP_HELP_IMAGE_COLOR_PROFILE_CONVERT },
101
102 { "image-color-profile-discard", NULL,
103 NC_("image-action", "_Discard Color Profile"), NULL,
104 NC_("image-action", "Remove the image's color profile"),
105 image_color_profile_discard_cmd_callback,
106 GIMP_HELP_IMAGE_COLOR_PROFILE_DISCARD },
107
108 { "image-color-profile-save", NULL,
109 NC_("image-action", "_Save Color Profile to File..."), NULL,
110 NC_("image-action", "Save the image's color profile to an ICC file"),
111 image_color_profile_save_cmd_callback,
112 GIMP_HELP_IMAGE_COLOR_PROFILE_SAVE },
113
114 { "image-resize", GIMP_ICON_OBJECT_RESIZE,
115 NC_("image-action", "Can_vas Size..."), NULL,
116 NC_("image-action", "Adjust the image dimensions"),
117 image_resize_cmd_callback,
118 GIMP_HELP_IMAGE_RESIZE },
119
120 { "image-resize-to-layers", NULL,
121 NC_("image-action", "Fit Canvas to L_ayers"), NULL,
122 NC_("image-action", "Resize the image to enclose all layers"),
123 image_resize_to_layers_cmd_callback,
124 GIMP_HELP_IMAGE_RESIZE_TO_LAYERS },
125
126 { "image-resize-to-selection", NULL,
127 NC_("image-action", "F_it Canvas to Selection"), NULL,
128 NC_("image-action", "Resize the image to the extents of the selection"),
129 image_resize_to_selection_cmd_callback,
130 GIMP_HELP_IMAGE_RESIZE_TO_SELECTION },
131
132 { "image-print-size", GIMP_ICON_DOCUMENT_PRINT_RESOLUTION,
133 NC_("image-action", "_Print Size..."), NULL,
134 NC_("image-action", "Adjust the print resolution"),
135 image_print_size_cmd_callback,
136 GIMP_HELP_IMAGE_PRINT_SIZE },
137
138 { "image-scale", GIMP_ICON_OBJECT_SCALE,
139 NC_("image-action", "_Scale Image..."), NULL,
140 NC_("image-action", "Change the size of the image content"),
141 image_scale_cmd_callback,
142 GIMP_HELP_IMAGE_SCALE },
143
144 { "image-crop-to-selection", GIMP_ICON_TOOL_CROP,
145 NC_("image-action", "_Crop to Selection"), NULL,
146 NC_("image-action", "Crop the image to the extents of the selection"),
147 image_crop_to_selection_cmd_callback,
148 GIMP_HELP_IMAGE_CROP },
149
150 { "image-crop-to-content", GIMP_ICON_TOOL_CROP,
151 NC_("image-action", "Crop to C_ontent"), NULL,
152 NC_("image-action", "Crop the image to the extents of its content (remove empty borders from the image)"),
153 image_crop_to_content_cmd_callback,
154 GIMP_HELP_IMAGE_CROP },
155
156 { "image-merge-layers", NULL,
157 NC_("image-action", "Merge Visible _Layers..."), "<primary>M",
158 NC_("image-action", "Merge all visible layers into one layer"),
159 image_merge_layers_cmd_callback,
160 GIMP_HELP_IMAGE_MERGE_LAYERS },
161
162 { "image-flatten", NULL,
163 NC_("image-action", "_Flatten Image"), NULL,
164 NC_("image-action", "Merge all layers into one and remove transparency"),
165 image_flatten_image_cmd_callback,
166 GIMP_HELP_IMAGE_FLATTEN },
167
168 { "image-configure-grid", GIMP_ICON_GRID,
169 NC_("image-action", "Configure G_rid..."), NULL,
170 NC_("image-action", "Configure the grid for this image"),
171 image_configure_grid_cmd_callback,
172 GIMP_HELP_IMAGE_GRID },
173
174 { "image-properties", "dialog-information",
175 NC_("image-action", "Image Pr_operties"), "<alt>Return",
176 NC_("image-action", "Display information about this image"),
177 image_properties_cmd_callback,
178 GIMP_HELP_IMAGE_PROPERTIES }
179 };
180
181 static const GimpToggleActionEntry image_toggle_actions[] =
182 {
183 { "image-color-management-enabled", NULL,
184 NC_("image-action", "_Enable Color Management"), NULL,
185 NC_("image-action", "Whether the image is color managed. Disabling "
186 "color management is equivalent to assigning a built-in sRGB "
187 "color profile. Better leave color management enabled."),
188 image_color_management_enabled_cmd_callback,
189 TRUE,
190 GIMP_HELP_IMAGE_COLOR_MANAGEMENT_ENABLED }
191 };
192
193 static const GimpRadioActionEntry image_convert_base_type_actions[] =
194 {
195 { "image-convert-rgb", GIMP_ICON_CONVERT_RGB,
196 NC_("image-convert-action", "_RGB"), NULL,
197 NC_("image-convert-action", "Convert the image to the RGB colorspace"),
198 GIMP_RGB, GIMP_HELP_IMAGE_CONVERT_RGB },
199
200 { "image-convert-grayscale", GIMP_ICON_CONVERT_GRAYSCALE,
201 NC_("image-convert-action", "_Grayscale"), NULL,
202 NC_("image-convert-action", "Convert the image to grayscale"),
203 GIMP_GRAY, GIMP_HELP_IMAGE_CONVERT_GRAYSCALE },
204
205 { "image-convert-indexed", GIMP_ICON_CONVERT_INDEXED,
206 NC_("image-convert-action", "_Indexed..."), NULL,
207 NC_("image-convert-action", "Convert the image to indexed colors"),
208 GIMP_INDEXED, GIMP_HELP_IMAGE_CONVERT_INDEXED }
209 };
210
211 static const GimpRadioActionEntry image_convert_precision_actions[] =
212 {
213 { "image-convert-u8", NULL,
214 NC_("image-convert-action", "8 bit integer"), NULL,
215 NC_("image-convert-action",
216 "Convert the image to 8 bit integer"),
217 GIMP_COMPONENT_TYPE_U8, GIMP_HELP_IMAGE_CONVERT_U8 },
218
219 { "image-convert-u16", NULL,
220 NC_("image-convert-action", "16 bit integer"), NULL,
221 NC_("image-convert-action",
222 "Convert the image to 16 bit integer"),
223 GIMP_COMPONENT_TYPE_U16, GIMP_HELP_IMAGE_CONVERT_U16 },
224
225 { "image-convert-u32", NULL,
226 NC_("image-convert-action", "32 bit integer"), NULL,
227 NC_("image-convert-action",
228 "Convert the image to 32 bit integer"),
229 GIMP_COMPONENT_TYPE_U32, GIMP_HELP_IMAGE_CONVERT_U32 },
230
231 { "image-convert-half", NULL,
232 NC_("image-convert-action", "16 bit floating point"), NULL,
233 NC_("image-convert-action",
234 "Convert the image to 16 bit floating point"),
235 GIMP_COMPONENT_TYPE_HALF, GIMP_HELP_IMAGE_CONVERT_HALF },
236
237 { "image-convert-float", NULL,
238 NC_("image-convert-action", "32 bit floating point"), NULL,
239 NC_("image-convert-action",
240 "Convert the image to 32 bit floating point"),
241 GIMP_COMPONENT_TYPE_FLOAT, GIMP_HELP_IMAGE_CONVERT_FLOAT },
242
243 { "image-convert-double", NULL,
244 NC_("image-convert-action", "64 bit floating point"), NULL,
245 NC_("image-convert-action",
246 "Convert the image to 64 bit floating point"),
247 GIMP_COMPONENT_TYPE_DOUBLE, GIMP_HELP_IMAGE_CONVERT_DOUBLE }
248 };
249
250 static const GimpRadioActionEntry image_convert_gamma_actions[] =
251 {
252 { "image-convert-gamma", NULL,
253 NC_("image-convert-action", "Perceptual gamma (sRGB)"), NULL,
254 NC_("image-convert-action",
255 "Convert the image to perceptual (sRGB) gamma"),
256 FALSE, GIMP_HELP_IMAGE_CONVERT_GAMMA },
257
258 { "image-convert-linear", NULL,
259 NC_("image-convert-action", "Linear light"), NULL,
260 NC_("image-convert-action",
261 "Convert the image to linear light"),
262 TRUE, GIMP_HELP_IMAGE_CONVERT_GAMMA }
263 };
264
265 static const GimpEnumActionEntry image_flip_actions[] =
266 {
267 { "image-flip-horizontal", GIMP_ICON_OBJECT_FLIP_HORIZONTAL,
268 NC_("image-action", "Flip _Horizontally"), NULL,
269 NC_("image-action", "Flip image horizontally"),
270 GIMP_ORIENTATION_HORIZONTAL, FALSE,
271 GIMP_HELP_IMAGE_FLIP_HORIZONTAL },
272
273 { "image-flip-vertical", GIMP_ICON_OBJECT_FLIP_VERTICAL,
274 NC_("image-action", "Flip _Vertically"), NULL,
275 NC_("image-action", "Flip image vertically"),
276 GIMP_ORIENTATION_VERTICAL, FALSE,
277 GIMP_HELP_IMAGE_FLIP_VERTICAL }
278 };
279
280 static const GimpEnumActionEntry image_rotate_actions[] =
281 {
282 { "image-rotate-90", GIMP_ICON_OBJECT_ROTATE_90,
283 NC_("image-action", "Rotate 90° _clockwise"), NULL,
284 NC_("image-action", "Rotate the image 90 degrees to the right"),
285 GIMP_ROTATE_90, FALSE,
286 GIMP_HELP_IMAGE_ROTATE_90 },
287
288 { "image-rotate-180", GIMP_ICON_OBJECT_ROTATE_180,
289 NC_("image-action", "Rotate _180°"), NULL,
290 NC_("image-action", "Turn the image upside-down"),
291 GIMP_ROTATE_180, FALSE,
292 GIMP_HELP_IMAGE_ROTATE_180 },
293
294 { "image-rotate-270", GIMP_ICON_OBJECT_ROTATE_270,
295 NC_("image-action", "Rotate 90° counter-clock_wise"), NULL,
296 NC_("image-action", "Rotate the image 90 degrees to the left"),
297 GIMP_ROTATE_270, FALSE,
298 GIMP_HELP_IMAGE_ROTATE_270 }
299 };
300
301
302 void
image_actions_setup(GimpActionGroup * group)303 image_actions_setup (GimpActionGroup *group)
304 {
305 gimp_action_group_add_actions (group, "image-action",
306 image_actions,
307 G_N_ELEMENTS (image_actions));
308
309 gimp_action_group_add_toggle_actions (group, "image-action",
310 image_toggle_actions,
311 G_N_ELEMENTS (image_toggle_actions));
312
313 gimp_action_group_add_radio_actions (group, "image-convert-action",
314 image_convert_base_type_actions,
315 G_N_ELEMENTS (image_convert_base_type_actions),
316 NULL, 0,
317 image_convert_base_type_cmd_callback);
318
319 gimp_action_group_add_radio_actions (group, "image-convert-action",
320 image_convert_precision_actions,
321 G_N_ELEMENTS (image_convert_precision_actions),
322 NULL, 0,
323 image_convert_precision_cmd_callback);
324
325 gimp_action_group_add_radio_actions (group, "image-convert-action",
326 image_convert_gamma_actions,
327 G_N_ELEMENTS (image_convert_gamma_actions),
328 NULL, 0,
329 image_convert_gamma_cmd_callback);
330
331 gimp_action_group_add_enum_actions (group, "image-action",
332 image_flip_actions,
333 G_N_ELEMENTS (image_flip_actions),
334 image_flip_cmd_callback);
335
336 gimp_action_group_add_enum_actions (group, "image-action",
337 image_rotate_actions,
338 G_N_ELEMENTS (image_rotate_actions),
339 image_rotate_cmd_callback);
340
341 #define SET_ALWAYS_SHOW_IMAGE(action,show) \
342 gimp_action_group_set_action_always_show_image (group, action, show)
343
344 SET_ALWAYS_SHOW_IMAGE ("image-rotate-90", TRUE);
345 SET_ALWAYS_SHOW_IMAGE ("image-rotate-180", TRUE);
346 SET_ALWAYS_SHOW_IMAGE ("image-rotate-270", TRUE);
347
348 #undef SET_ALWAYS_SHOW_IMAGE
349 }
350
351 void
image_actions_update(GimpActionGroup * group,gpointer data)352 image_actions_update (GimpActionGroup *group,
353 gpointer data)
354 {
355 GimpImage *image = action_data_get_image (data);
356 gboolean is_indexed = FALSE;
357 gboolean is_u8_gamma = FALSE;
358 gboolean is_double = FALSE;
359 gboolean aux = FALSE;
360 gboolean lp = FALSE;
361 gboolean sel = FALSE;
362 gboolean groups = FALSE;
363 gboolean color_managed = FALSE;
364 gboolean profile = FALSE;
365
366 if (image)
367 {
368 GimpContainer *layers;
369 const gchar *action = NULL;
370 GimpImageBaseType base_type;
371 GimpPrecision precision;
372 GimpComponentType component_type;
373
374 base_type = gimp_image_get_base_type (image);
375 precision = gimp_image_get_precision (image);
376 component_type = gimp_image_get_component_type (image);
377
378 switch (base_type)
379 {
380 case GIMP_RGB: action = "image-convert-rgb"; break;
381 case GIMP_GRAY: action = "image-convert-grayscale"; break;
382 case GIMP_INDEXED: action = "image-convert-indexed"; break;
383 }
384
385 gimp_action_group_set_action_active (group, action, TRUE);
386
387 switch (component_type)
388 {
389 case GIMP_COMPONENT_TYPE_U8: action = "image-convert-u8"; break;
390 case GIMP_COMPONENT_TYPE_U16: action = "image-convert-u16"; break;
391 case GIMP_COMPONENT_TYPE_U32: action = "image-convert-u32"; break;
392 case GIMP_COMPONENT_TYPE_HALF: action = "image-convert-half"; break;
393 case GIMP_COMPONENT_TYPE_FLOAT: action = "image-convert-float"; break;
394 case GIMP_COMPONENT_TYPE_DOUBLE: action = "image-convert-double"; break;
395 }
396
397 gimp_action_group_set_action_active (group, action, TRUE);
398
399 if (gimp_babl_format_get_linear (gimp_image_get_layer_format (image,
400 FALSE)))
401 {
402 gimp_action_group_set_action_active (group, "image-convert-linear",
403 TRUE);
404 }
405 else
406 {
407 gimp_action_group_set_action_active (group, "image-convert-gamma",
408 TRUE);
409 }
410
411 is_indexed = (base_type == GIMP_INDEXED);
412 is_u8_gamma = (precision == GIMP_PRECISION_U8_GAMMA);
413 is_double = (component_type == GIMP_COMPONENT_TYPE_DOUBLE);
414 aux = (gimp_image_get_active_channel (image) != NULL);
415 lp = ! gimp_image_is_empty (image);
416 sel = ! gimp_channel_is_empty (gimp_image_get_mask (image));
417
418 layers = gimp_image_get_layers (image);
419
420 groups = ! gimp_item_stack_is_flat (GIMP_ITEM_STACK (layers));
421
422 color_managed = gimp_image_get_is_color_managed (image);
423 profile = (gimp_image_get_color_profile (image) != NULL);
424 }
425
426 #define SET_LABEL(action,label) \
427 gimp_action_group_set_action_label (group, action, (label))
428 #define SET_SENSITIVE(action,condition) \
429 gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
430 #define SET_ACTIVE(action,condition) \
431 gimp_action_group_set_action_active (group, action, (condition) != 0)
432 #define SET_VISIBLE(action,condition) \
433 gimp_action_group_set_action_visible (group, action, (condition) != 0)
434
435 SET_SENSITIVE ("image-duplicate", image);
436
437 if (profile)
438 {
439 SET_LABEL ("image-convert-rgb",
440 C_("image-convert-action", "_RGB..."));
441 SET_LABEL ("image-convert-grayscale",
442 C_("image-convert-action", "_Grayscale..."));
443 }
444 else
445 {
446 SET_LABEL ("image-convert-rgb",
447 C_("image-convert-action", "_RGB"));
448 SET_LABEL ("image-convert-grayscale",
449 C_("image-convert-action", "_Grayscale"));
450 }
451
452 SET_SENSITIVE ("image-convert-rgb", image);
453 SET_SENSITIVE ("image-convert-grayscale", image);
454 SET_SENSITIVE ("image-convert-indexed", image && !groups && is_u8_gamma);
455
456 SET_SENSITIVE ("image-convert-u8", image);
457 SET_SENSITIVE ("image-convert-u16", image && !is_indexed);
458 SET_SENSITIVE ("image-convert-u32", image && !is_indexed);
459 SET_SENSITIVE ("image-convert-half", image && !is_indexed);
460 SET_SENSITIVE ("image-convert-float", image && !is_indexed);
461 SET_SENSITIVE ("image-convert-double", image && !is_indexed);
462 SET_VISIBLE ("image-convert-double", is_double);
463
464 SET_SENSITIVE ("image-convert-gamma", image);
465 SET_SENSITIVE ("image-convert-linear", image && !is_indexed);
466
467 SET_SENSITIVE ("image-color-management-enabled", image);
468 SET_ACTIVE ("image-color-management-enabled", image && color_managed);
469
470 SET_SENSITIVE ("image-color-profile-assign", image);
471 SET_SENSITIVE ("image-color-profile-convert", image);
472 SET_SENSITIVE ("image-color-profile-discard", image && profile);
473 SET_SENSITIVE ("image-color-profile-save", image);
474
475 SET_SENSITIVE ("image-flip-horizontal", image);
476 SET_SENSITIVE ("image-flip-vertical", image);
477 SET_SENSITIVE ("image-rotate-90", image);
478 SET_SENSITIVE ("image-rotate-180", image);
479 SET_SENSITIVE ("image-rotate-270", image);
480
481 SET_SENSITIVE ("image-resize", image);
482 SET_SENSITIVE ("image-resize-to-layers", image);
483 SET_SENSITIVE ("image-resize-to-selection", image && sel);
484 SET_SENSITIVE ("image-print-size", image);
485 SET_SENSITIVE ("image-scale", image);
486 SET_SENSITIVE ("image-crop-to-selection", image && sel);
487 SET_SENSITIVE ("image-crop-to-content", image);
488 SET_SENSITIVE ("image-merge-layers", image && !aux && lp);
489 SET_SENSITIVE ("image-flatten", image && !aux && lp);
490 SET_SENSITIVE ("image-configure-grid", image);
491 SET_SENSITIVE ("image-properties", image);
492
493 #undef SET_LABEL
494 #undef SET_SENSITIVE
495 #undef SET_ACTIVE
496 #undef SET_VISIBLE
497 }
498