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 "core/gimpimage.h"
28 #include "core/gimpitem.h"
29 
30 #include "widgets/gimpactiongroup.h"
31 #include "widgets/gimpcomponenteditor.h"
32 #include "widgets/gimphelp-ids.h"
33 
34 #include "actions.h"
35 #include "channels-actions.h"
36 #include "channels-commands.h"
37 #include "items-actions.h"
38 
39 #include "gimp-intl.h"
40 
41 
42 static const GimpActionEntry channels_actions[] =
43 {
44   { "channels-popup", GIMP_ICON_DIALOG_CHANNELS,
45     NC_("channels-action", "Channels Menu"), NULL, NULL, NULL,
46     GIMP_HELP_CHANNEL_DIALOG },
47 
48   { "channels-color-tag-menu", NULL,
49     NC_("channels-action", "Color Tag"), NULL, NULL, NULL,
50     GIMP_HELP_CHANNEL_COLOR_TAG },
51 
52   { "channels-edit-attributes", GIMP_ICON_EDIT,
53     NC_("channels-action", "_Edit Channel Attributes..."), NULL,
54     NC_("channels-action", "Edit the channel's name, color and opacity"),
55     channels_edit_attributes_cmd_callback,
56     GIMP_HELP_CHANNEL_EDIT },
57 
58   { "channels-new", GIMP_ICON_DOCUMENT_NEW,
59     NC_("channels-action", "_New Channel..."), NULL,
60     NC_("channels-action", "Create a new channel"),
61     channels_new_cmd_callback,
62     GIMP_HELP_CHANNEL_NEW },
63 
64   { "channels-new-last-values", GIMP_ICON_DOCUMENT_NEW,
65     NC_("channels-action", "_New Channel"), NULL,
66     NC_("channels-action", "Create a new channel with last used values"),
67     channels_new_last_vals_cmd_callback,
68     GIMP_HELP_CHANNEL_NEW },
69 
70   { "channels-duplicate", GIMP_ICON_OBJECT_DUPLICATE,
71     NC_("channels-action", "D_uplicate Channel"), NULL,
72     NC_("channels-action",
73         "Create a duplicate of this channel and add it to the image"),
74     channels_duplicate_cmd_callback,
75     GIMP_HELP_CHANNEL_DUPLICATE },
76 
77   { "channels-delete", GIMP_ICON_EDIT_DELETE,
78     NC_("channels-action", "_Delete Channel"), NULL,
79     NC_("channels-action", "Delete this channel"),
80     channels_delete_cmd_callback,
81     GIMP_HELP_CHANNEL_DELETE },
82 
83   { "channels-raise", GIMP_ICON_GO_UP,
84     NC_("channels-action", "_Raise Channel"), NULL,
85     NC_("channels-action", "Raise this channel one step in the channel stack"),
86     channels_raise_cmd_callback,
87     GIMP_HELP_CHANNEL_RAISE },
88 
89   { "channels-raise-to-top", GIMP_ICON_GO_TOP,
90     NC_("channels-action", "Raise Channel to _Top"), NULL,
91     NC_("channels-action",
92         "Raise this channel to the top of the channel stack"),
93     channels_raise_to_top_cmd_callback,
94     GIMP_HELP_CHANNEL_RAISE_TO_TOP },
95 
96   { "channels-lower", GIMP_ICON_GO_DOWN,
97     NC_("channels-action", "_Lower Channel"), NULL,
98     NC_("channels-action", "Lower this channel one step in the channel stack"),
99     channels_lower_cmd_callback,
100     GIMP_HELP_CHANNEL_LOWER },
101 
102   { "channels-lower-to-bottom", GIMP_ICON_GO_BOTTOM,
103     NC_("channels-action", "Lower Channel to _Bottom"), NULL,
104     NC_("channels-action",
105         "Lower this channel to the bottom of the channel stack"),
106     channels_lower_to_bottom_cmd_callback,
107     GIMP_HELP_CHANNEL_LOWER_TO_BOTTOM }
108 };
109 
110 static const GimpToggleActionEntry channels_toggle_actions[] =
111 {
112   { "channels-visible", GIMP_ICON_VISIBLE,
113     NC_("channels-action", "Toggle Channel _Visibility"), NULL, NULL,
114     channels_visible_cmd_callback,
115     FALSE,
116     GIMP_HELP_CHANNEL_VISIBLE },
117 
118   { "channels-linked", GIMP_ICON_LINKED,
119     NC_("channels-action", "Toggle Channel _Linked State"), NULL, NULL,
120     channels_linked_cmd_callback,
121     FALSE,
122     GIMP_HELP_CHANNEL_LINKED },
123 
124   { "channels-lock-content", NULL /* GIMP_ICON_LOCK */,
125     NC_("channels-action", "L_ock Pixels of Channel"), NULL, NULL,
126     channels_lock_content_cmd_callback,
127     FALSE,
128     GIMP_HELP_CHANNEL_LOCK_PIXELS },
129 
130   { "channels-lock-position", GIMP_ICON_TOOL_MOVE,
131     NC_("channels-action", "L_ock Position of Channel"), NULL, NULL,
132     channels_lock_position_cmd_callback,
133     FALSE,
134     GIMP_HELP_CHANNEL_LOCK_POSITION }
135 };
136 
137 static const GimpEnumActionEntry channels_color_tag_actions[] =
138 {
139   { "channels-color-tag-none", GIMP_ICON_EDIT_CLEAR,
140     NC_("channels-action", "None"), NULL,
141     NC_("channels-action", "Channel Color Tag: Clear"),
142     GIMP_COLOR_TAG_NONE, FALSE,
143     GIMP_HELP_CHANNEL_COLOR_TAG },
144 
145   { "channels-color-tag-blue", NULL,
146     NC_("channels-action", "Blue"), NULL,
147     NC_("channels-action", "Channel Color Tag: Set to Blue"),
148     GIMP_COLOR_TAG_BLUE, FALSE,
149     GIMP_HELP_CHANNEL_COLOR_TAG },
150 
151   { "channels-color-tag-green", NULL,
152     NC_("channels-action", "Green"), NULL,
153     NC_("channels-action", "Channel Color Tag: Set to Green"),
154     GIMP_COLOR_TAG_GREEN, FALSE,
155     GIMP_HELP_CHANNEL_COLOR_TAG },
156 
157   { "channels-color-tag-yellow", NULL,
158     NC_("channels-action", "Yellow"), NULL,
159     NC_("channels-action", "Channel Color Tag: Set to Yellow"),
160     GIMP_COLOR_TAG_YELLOW, FALSE,
161     GIMP_HELP_CHANNEL_COLOR_TAG },
162 
163   { "channels-color-tag-orange", NULL,
164     NC_("channels-action", "Orange"), NULL,
165     NC_("channels-action", "Channel Color Tag: Set to Orange"),
166     GIMP_COLOR_TAG_ORANGE, FALSE,
167     GIMP_HELP_CHANNEL_COLOR_TAG },
168 
169   { "channels-color-tag-brown", NULL,
170     NC_("channels-action", "Brown"), NULL,
171     NC_("channels-action", "Channel Color Tag: Set to Brown"),
172     GIMP_COLOR_TAG_BROWN, FALSE,
173     GIMP_HELP_CHANNEL_COLOR_TAG },
174 
175   { "channels-color-tag-red", NULL,
176     NC_("channels-action", "Red"), NULL,
177     NC_("channels-action", "Channel Color Tag: Set to Red"),
178     GIMP_COLOR_TAG_RED, FALSE,
179     GIMP_HELP_CHANNEL_COLOR_TAG },
180 
181   { "channels-color-tag-violet", NULL,
182     NC_("channels-action", "Violet"), NULL,
183     NC_("channels-action", "Channel Color Tag: Set to Violet"),
184     GIMP_COLOR_TAG_VIOLET, FALSE,
185     GIMP_HELP_CHANNEL_COLOR_TAG },
186 
187   { "channels-color-tag-gray", NULL,
188     NC_("channels-action", "Gray"), NULL,
189     NC_("channels-action", "Channel Color Tag: Set to Gray"),
190     GIMP_COLOR_TAG_GRAY, FALSE,
191     GIMP_HELP_CHANNEL_COLOR_TAG }
192 };
193 
194 static const GimpEnumActionEntry channels_to_selection_actions[] =
195 {
196   { "channels-selection-replace", GIMP_ICON_SELECTION_REPLACE,
197     NC_("channels-action", "Channel to Sele_ction"), NULL,
198     NC_("channels-action", "Replace the selection with this channel"),
199     GIMP_CHANNEL_OP_REPLACE, FALSE,
200     GIMP_HELP_CHANNEL_SELECTION_REPLACE },
201 
202   { "channels-selection-add", GIMP_ICON_SELECTION_ADD,
203     NC_("channels-action", "_Add to Selection"), NULL,
204     NC_("channels-action", "Add this channel to the current selection"),
205     GIMP_CHANNEL_OP_ADD, FALSE,
206     GIMP_HELP_CHANNEL_SELECTION_ADD },
207 
208   { "channels-selection-subtract", GIMP_ICON_SELECTION_SUBTRACT,
209     NC_("channels-action", "_Subtract from Selection"), NULL,
210     NC_("channels-action", "Subtract this channel from the current selection"),
211     GIMP_CHANNEL_OP_SUBTRACT, FALSE,
212     GIMP_HELP_CHANNEL_SELECTION_SUBTRACT },
213 
214   { "channels-selection-intersect", GIMP_ICON_SELECTION_INTERSECT,
215     NC_("channels-action", "_Intersect with Selection"), NULL,
216     NC_("channels-action", "Intersect this channel with the current selection"),
217     GIMP_CHANNEL_OP_INTERSECT, FALSE,
218     GIMP_HELP_CHANNEL_SELECTION_INTERSECT }
219 };
220 
221 static const GimpEnumActionEntry channels_select_actions[] =
222 {
223   { "channels-select-top", NULL,
224     NC_("channels-action", "Select _Top Channel"), NULL,
225     NC_("channels-action", "Select the topmost channel"),
226     GIMP_ACTION_SELECT_FIRST, FALSE,
227     GIMP_HELP_CHANNEL_TOP },
228 
229   { "channels-select-bottom", NULL,
230     NC_("channels-action", "Select _Bottom Channel"), NULL,
231     NC_("channels-action", "Select the bottommost channel"),
232     GIMP_ACTION_SELECT_LAST, FALSE,
233     GIMP_HELP_CHANNEL_BOTTOM },
234 
235   { "channels-select-previous", NULL,
236     NC_("channels-action", "Select _Previous Channel"), NULL,
237     NC_("channels-action", "Select the channel above the current channel"),
238     GIMP_ACTION_SELECT_PREVIOUS, FALSE,
239     GIMP_HELP_CHANNEL_PREVIOUS },
240 
241   { "channels-select-next", NULL,
242     NC_("channels-action", "Select _Next Channel"), NULL,
243     NC_("channels-action", "Select the channel below the current channel"),
244     GIMP_ACTION_SELECT_NEXT, FALSE,
245     GIMP_HELP_CHANNEL_NEXT }
246 };
247 
248 
249 void
channels_actions_setup(GimpActionGroup * group)250 channels_actions_setup (GimpActionGroup *group)
251 {
252   gimp_action_group_add_actions (group, "channels-action",
253                                  channels_actions,
254                                  G_N_ELEMENTS (channels_actions));
255 
256   gimp_action_group_add_toggle_actions (group, "channels-action",
257                                         channels_toggle_actions,
258                                         G_N_ELEMENTS (channels_toggle_actions));
259 
260   gimp_action_group_add_enum_actions (group, "channels-action",
261                                       channels_color_tag_actions,
262                                       G_N_ELEMENTS (channels_color_tag_actions),
263                                       channels_color_tag_cmd_callback);
264 
265   gimp_action_group_add_enum_actions (group, "channels-action",
266                                       channels_to_selection_actions,
267                                       G_N_ELEMENTS (channels_to_selection_actions),
268                                       channels_to_selection_cmd_callback);
269 
270   gimp_action_group_add_enum_actions (group, "channels-action",
271                                       channels_select_actions,
272                                       G_N_ELEMENTS (channels_select_actions),
273                                       channels_select_cmd_callback);
274 
275   items_actions_setup (group, "channels");
276 }
277 
278 void
channels_actions_update(GimpActionGroup * group,gpointer data)279 channels_actions_update (GimpActionGroup *group,
280                          gpointer         data)
281 {
282   GimpImage   *image     = action_data_get_image (data);
283   GimpChannel *channel   = NULL;
284   gboolean     fs        = FALSE;
285   gboolean     component = FALSE;
286   GList       *next      = NULL;
287   GList       *prev      = NULL;
288 
289   if (image)
290     {
291       fs = (gimp_image_get_floating_selection (image) != NULL);
292 
293       if (GIMP_IS_COMPONENT_EDITOR (data))
294         {
295           if (GIMP_COMPONENT_EDITOR (data)->clicked_component != -1)
296             component = TRUE;
297         }
298       else
299         {
300           channel = gimp_image_get_active_channel (image);
301 
302           if (channel)
303             {
304               GList *channel_list;
305               GList *list;
306 
307               channel_list = gimp_item_get_container_iter (GIMP_ITEM (channel));
308 
309               list = g_list_find (channel_list, channel);
310 
311               if (list)
312                 {
313                   prev = g_list_previous (list);
314                   next = g_list_next (list);
315                 }
316             }
317         }
318     }
319 
320 #define SET_SENSITIVE(action,condition) \
321         gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
322 
323   SET_SENSITIVE ("channels-edit-attributes", !fs && channel);
324 
325   SET_SENSITIVE ("channels-new",             !fs && image);
326   SET_SENSITIVE ("channels-new-last-values", !fs && image);
327   SET_SENSITIVE ("channels-duplicate",       !fs && (channel || component));
328   SET_SENSITIVE ("channels-delete",          !fs && channel);
329 
330   SET_SENSITIVE ("channels-raise",           !fs && channel && prev);
331   SET_SENSITIVE ("channels-raise-to-top",    !fs && channel && prev);
332   SET_SENSITIVE ("channels-lower",           !fs && channel && next);
333   SET_SENSITIVE ("channels-lower-to-bottom", !fs && channel && next);
334 
335   SET_SENSITIVE ("channels-selection-replace",   !fs && (channel || component));
336   SET_SENSITIVE ("channels-selection-add",       !fs && (channel || component));
337   SET_SENSITIVE ("channels-selection-subtract",  !fs && (channel || component));
338   SET_SENSITIVE ("channels-selection-intersect", !fs && (channel || component));
339 
340   SET_SENSITIVE ("channels-select-top",      !fs && channel && prev);
341   SET_SENSITIVE ("channels-select-bottom",   !fs && channel && next);
342   SET_SENSITIVE ("channels-select-previous", !fs && channel && prev);
343   SET_SENSITIVE ("channels-select-next",     !fs && channel && next);
344 
345 #undef SET_SENSITIVE
346 
347   items_actions_update (group, "channels", GIMP_ITEM (channel));
348 }
349