[gimp/wip/Jehan/layers-dockable-refresh: 45/58] app: channel selection actions now multi-channel aware.




commit 7c509cae2c5afd829dcfce28c5e881ba8701846e
Author: Jehan <jehan girinstud io>
Date:   Sun Jun 20 15:27:40 2021 +0200

    app: channel selection actions now multi-channel aware.

 app/actions/actions.c           |  4 ++-
 app/actions/channels-actions.c  | 75 +++++++++++++++++++++++------------------
 app/actions/channels-commands.c | 43 ++++++++++++++++++-----
 3 files changed, 79 insertions(+), 43 deletions(-)
---
diff --git a/app/actions/actions.c b/app/actions/actions.c
index 47f6dcf3d1..caaedd8e4f 100644
--- a/app/actions/actions.c
+++ b/app/actions/actions.c
@@ -665,7 +665,9 @@ action_select_object (GimpActionSelectType  select_type,
   g_return_val_if_fail (GIMP_IS_CONTAINER (container), NULL);
   g_return_val_if_fail (current == NULL || GIMP_IS_OBJECT (current), NULL);
 
-  if (! current)
+  if (! current                               &&
+      select_type != GIMP_ACTION_SELECT_FIRST &&
+      select_type != GIMP_ACTION_SELECT_LAST)
     return NULL;
 
   n_children = gimp_container_get_n_children (container);
diff --git a/app/actions/channels-actions.c b/app/actions/channels-actions.c
index 081cddb31f..7a05302320 100644
--- a/app/actions/channels-actions.c
+++ b/app/actions/channels-actions.c
@@ -234,13 +234,13 @@ static const GimpEnumActionEntry channels_select_actions[] =
 
   { "channels-select-previous", NULL,
     NC_("channels-action", "Select _Previous Channel"), NULL,
-    NC_("channels-action", "Select the channel above the current channel"),
+    NC_("channels-action", "Select the channels above the selected channels"),
     GIMP_ACTION_SELECT_PREVIOUS, FALSE,
     GIMP_HELP_CHANNEL_PREVIOUS },
 
   { "channels-select-next", NULL,
-    NC_("channels-action", "Select _Next Channel"), NULL,
-    NC_("channels-action", "Select the channel below the current channel"),
+    NC_("channels-action", "Select _Next Channels"), NULL,
+    NC_("channels-action", "Select the channels below the selected channels"),
     GIMP_ACTION_SELECT_NEXT, FALSE,
     GIMP_HELP_CHANNEL_NEXT }
 };
@@ -279,13 +279,14 @@ void
 channels_actions_update (GimpActionGroup *group,
                          gpointer         data)
 {
-  GimpImage   *image      = action_data_get_image (data);
-  GList       *channels   = NULL;
-  gboolean     fs         = FALSE;
-  gboolean     component  = FALSE;
-  GList       *next       = NULL;
-  GList       *prev       = NULL;
-  gint         n_channels = 0;
+  GimpImage   *image               = action_data_get_image (data);
+  gboolean     fs                  = FALSE;
+  gboolean     component           = FALSE;
+  GList       *selected_channels   = NULL;
+  gint         n_selected_channels = 0;
+  gint         n_channels          = 0;
+  gboolean     have_prev           = FALSE; /* At least 1 selected channel has a previous sibling. */
+  gboolean     have_next           = FALSE; /* At least 1 selected channel has a next sibling.     */
 
   if (image)
     {
@@ -298,23 +299,31 @@ channels_actions_update (GimpActionGroup *group,
         }
       else
         {
-          channels = gimp_image_get_selected_channels (image);
-          n_channels = g_list_length (channels);
+          GList *iter;
 
-          if (n_channels == 1)
+          selected_channels   = gimp_image_get_selected_channels (image);
+          n_selected_channels = g_list_length (selected_channels);
+          n_channels          = gimp_image_get_n_channels (image);
+
+          for (iter = selected_channels; iter; iter = iter->next)
             {
               GList *channel_list;
               GList *list;
 
-              channel_list = gimp_item_get_container_iter (GIMP_ITEM (channels->data));
+              channel_list = gimp_item_get_container_iter (GIMP_ITEM (iter->data));
 
-              list = g_list_find (channel_list, channels->data);
+              list = g_list_find (channel_list, iter->data);
 
               if (list)
                 {
-                  prev = g_list_previous (list);
-                  next = g_list_next (list);
+                  if (g_list_previous (list))
+                    have_prev = TRUE;
+                  if (g_list_next (list))
+                    have_next = TRUE;
                 }
+
+              if (have_prev && have_next)
+                break;
             }
         }
     }
@@ -322,29 +331,29 @@ channels_actions_update (GimpActionGroup *group,
 #define SET_SENSITIVE(action,condition) \
         gimp_action_group_set_action_sensitive (group, action, (condition) != 0, NULL)
 
-  SET_SENSITIVE ("channels-edit-attributes", !fs && n_channels == 1);
+  SET_SENSITIVE ("channels-edit-attributes", !fs && n_selected_channels == 1);
 
   SET_SENSITIVE ("channels-new",             !fs && image);
   SET_SENSITIVE ("channels-new-last-values", !fs && image);
-  SET_SENSITIVE ("channels-duplicate",       !fs && (n_channels == 1 || component));
-  SET_SENSITIVE ("channels-delete",          !fs && n_channels > 0);
+  SET_SENSITIVE ("channels-duplicate",       !fs && (n_selected_channels == 1 || component));
+  SET_SENSITIVE ("channels-delete",          !fs && n_selected_channels > 0);
 
-  SET_SENSITIVE ("channels-raise",           !fs && n_channels == 1 && prev);
-  SET_SENSITIVE ("channels-raise-to-top",    !fs && n_channels == 1 && prev);
-  SET_SENSITIVE ("channels-lower",           !fs && n_channels == 1 && next);
-  SET_SENSITIVE ("channels-lower-to-bottom", !fs && n_channels == 1 && next);
+  SET_SENSITIVE ("channels-raise",           !fs && n_selected_channels == 1 && have_prev);
+  SET_SENSITIVE ("channels-raise-to-top",    !fs && n_selected_channels == 1 && have_prev);
+  SET_SENSITIVE ("channels-lower",           !fs && n_selected_channels == 1 && have_next);
+  SET_SENSITIVE ("channels-lower-to-bottom", !fs && n_selected_channels == 1 && have_next);
 
-  SET_SENSITIVE ("channels-selection-replace",   !fs && (n_channels == 1 || component));
-  SET_SENSITIVE ("channels-selection-add",       !fs && (n_channels == 1 || component));
-  SET_SENSITIVE ("channels-selection-subtract",  !fs && (n_channels == 1 || component));
-  SET_SENSITIVE ("channels-selection-intersect", !fs && (n_channels == 1 || component));
+  SET_SENSITIVE ("channels-selection-replace",   !fs && (n_selected_channels == 1 || component));
+  SET_SENSITIVE ("channels-selection-add",       !fs && (n_selected_channels == 1 || component));
+  SET_SENSITIVE ("channels-selection-subtract",  !fs && (n_selected_channels == 1 || component));
+  SET_SENSITIVE ("channels-selection-intersect", !fs && (n_selected_channels == 1 || component));
 
-  SET_SENSITIVE ("channels-select-top",      !fs && n_channels == 1 && prev);
-  SET_SENSITIVE ("channels-select-bottom",   !fs && n_channels == 1 && next);
-  SET_SENSITIVE ("channels-select-previous", !fs && n_channels == 1 && prev);
-  SET_SENSITIVE ("channels-select-next",     !fs && n_channels == 1 && next);
+  SET_SENSITIVE ("channels-select-top",      !fs && n_channels > 0 && (n_selected_channels == 0 || 
have_prev));
+  SET_SENSITIVE ("channels-select-bottom",   !fs && n_channels > 0 && (n_selected_channels == 0 || 
have_next));
+  SET_SENSITIVE ("channels-select-previous", !fs && n_selected_channels > 0 && have_prev);
+  SET_SENSITIVE ("channels-select-next",     !fs && n_selected_channels > 0 && have_next);
 
 #undef SET_SENSITIVE
 
-  items_actions_update (group, "channels", channels);
+  items_actions_update (group, "channels", selected_channels);
 }
diff --git a/app/actions/channels-commands.c b/app/actions/channels-commands.c
index 6701242e20..6833fca565 100644
--- a/app/actions/channels-commands.c
+++ b/app/actions/channels-commands.c
@@ -33,6 +33,7 @@
 #include "core/gimp.h"
 #include "core/gimpchannel.h"
 #include "core/gimpchannel-select.h"
+#include "core/gimpcontainer.h"
 #include "core/gimpcontext.h"
 #include "core/gimpdrawable-fill.h"
 #include "core/gimpimage.h"
@@ -429,23 +430,47 @@ channels_select_cmd_callback (GimpAction *action,
                               gpointer    data)
 {
   GimpImage            *image;
-  GimpChannel          *channel;
-  GimpChannel          *channel2;
-  GimpContainer        *container;
+  GList                *channels;
+  GList                *new_channels = NULL;
+  GList                *iter;
   GimpActionSelectType  select_type;
-  return_if_no_channel (image, channel, data);
+  gboolean              run_once;
+  return_if_no_image (image, data);
 
   select_type = (GimpActionSelectType) g_variant_get_int32 (value);
 
-  container = gimp_image_get_channels (image);
-  channel2 = (GimpChannel *) action_select_object (select_type, container,
-                                                   (GimpObject *) channel);
+  channels = gimp_image_get_selected_channels (image);
+  run_once = (g_list_length (channels) == 0);
+
+  for (iter = channels; iter || run_once; iter = iter ? iter->next : NULL)
+    {
+      GimpChannel   *new_channel = NULL;
+      GimpContainer *container;
+
+      if (iter)
+        {
+          container = gimp_item_get_container (GIMP_ITEM (iter->data));
+        }
+      else /* run_once */
+        {
+          container = gimp_image_get_channels (image);
+          run_once  = FALSE;
+        }
+      new_channel = (GimpChannel *) action_select_object (select_type,
+                                                          container,
+                                                          iter ? iter->data : NULL);
+
+      if (new_channel)
+        new_channels = g_list_prepend (new_channels, new_channel);
+    }
 
-  if (channel2 && channel2 != channel)
+  if (new_channels)
     {
-      gimp_image_set_active_channel (image, channel2);
+      gimp_image_set_selected_channels (image, new_channels);
       gimp_image_flush (image);
     }
+
+  g_list_free (new_channels);
 }
 
 /*  private functions  */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]