app: adds multi-selection support to "layers-delete" action.

This commit is contained in:
Jehan 2020-03-21 14:22:58 +01:00
parent 0593cf4c9e
commit 178f32f6a5
3 changed files with 68 additions and 14 deletions

View File

@ -136,8 +136,8 @@ static const GimpActionEntry layers_actions[] =
GIMP_HELP_LAYER_DUPLICATE },
{ "layers-delete", GIMP_ICON_EDIT_DELETE,
NC_("layers-action", "_Delete Layer"), NULL,
NC_("layers-action", "Delete this layer"),
NC_("layers-action", "_Delete Layers"), NULL,
NC_("layers-action", "Delete selected layers"),
layers_delete_cmd_callback,
GIMP_HELP_LAYER_DELETE },
@ -763,6 +763,7 @@ layers_actions_update (GimpActionGroup *group,
{
GimpImage *image = action_data_get_image (data);
GimpLayer *layer = NULL;
GList *layers = NULL;
GimpLayerMask *mask = NULL; /* layer mask */
gboolean fs = FALSE; /* floating sel */
gboolean ac = FALSE; /* active channel */
@ -793,6 +794,7 @@ layers_actions_update (GimpActionGroup *group,
indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED);
layer = gimp_image_get_active_layer (image);
layers = gimp_image_get_selected_layers (image);
if (layer)
{
@ -935,7 +937,7 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-new-from-visible", image);
SET_SENSITIVE ("layers-new-group", image && !indexed);
SET_SENSITIVE ("layers-duplicate", layer && !fs && !ac);
SET_SENSITIVE ("layers-delete", layer && !ac);
SET_SENSITIVE ("layers-delete", g_list_length (layers) > 0 && !ac);
SET_SENSITIVE ("layers-mode-first", layer && !ac && prev_mode);
SET_SENSITIVE ("layers-mode-last", layer && !ac && next_mode);

View File

@ -627,10 +627,52 @@ layers_delete_cmd_callback (GimpAction *action,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
return_if_no_layer (image, layer, data);
GList *layers;
GList *removed_layers;
gimp_image_remove_layer (image, layer, TRUE, NULL);
return_if_no_image (image, data);
layers = gimp_image_get_selected_layers (image);
/*TODO: we should have a failsafe to determine when we are going to
* delete all layers (i.e. all layers of first level at least) and
* forbid it. */
/* Copy of the original selection. */
removed_layers = g_list_copy (layers);
if (g_list_length (removed_layers) > 1)
{
gchar *undo_name;
undo_name = g_strdup_printf (C_("undo-type", "Remove %d Layers"),
g_list_length (removed_layers));
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_ITEM_REMOVE,
undo_name);
}
while (layers)
{
/* Stop when the selected layers contain a layer which was not in
* the originally selected list (it means we delete them all).
*/
if (g_list_find (removed_layers, layers->data) == NULL)
break;
gimp_image_remove_layer (image, layers->data, TRUE, NULL);
/* Instead of iterating, I re-check the selected layers after each
* removal, because the selection may have changed, in particular
* in case a layer group got removed and some of its children were
* also selected.
*/
layers = gimp_image_get_selected_layers (image);
}
if (g_list_length (removed_layers) > 1)
gimp_image_undo_group_end (image);
g_list_free (removed_layers);
gimp_image_flush (image);
}

View File

@ -4282,17 +4282,24 @@ gimp_image_set_selected_layers (GimpImage *image,
GimpLayer *floating_sel;
GimpLayer *active_layer;
GList *selected_layers;
GList *layers2;
GList *iter;
gboolean selection_changed = TRUE;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
layers2 = g_list_copy (layers);
for (iter = layers; iter; iter = iter->next)
{
g_return_val_if_fail (GIMP_IS_LAYER (iter->data), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (iter->data)) &&
gimp_item_get_image (GIMP_ITEM (iter->data)) == image,
NULL);
g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (iter->data)) == image, NULL);
/* Silently remove non-attached layers from selection. Do not
* error out on it as it may happen for instance when selection
* changes while in the process of removing a layer group.
*/
if (! gimp_item_is_attached (GIMP_ITEM (iter->data)))
layers2 = g_list_remove (layers2, iter->data);
}
private = GIMP_IMAGE_GET_PRIVATE (image);
@ -4300,16 +4307,16 @@ gimp_image_set_selected_layers (GimpImage *image,
floating_sel = gimp_image_get_floating_selection (image);
/* Make sure the floating_sel always is the active layer */
if (floating_sel && (g_list_length (layers) != 1 || layers->data != floating_sel))
if (floating_sel && (g_list_length (layers2) != 1 || layers2->data != floating_sel))
return g_list_prepend (NULL, floating_sel);
selected_layers = gimp_image_get_selected_layers (image);
active_layer = gimp_image_get_active_layer (image);
if (g_list_length (layers) == g_list_length (selected_layers))
if (g_list_length (layers2) == g_list_length (selected_layers))
{
selection_changed = FALSE;
for (iter = layers; iter; iter = iter->next)
for (iter = layers2; iter; iter = iter->next)
{
if (g_list_find (selected_layers, iter->data) == NULL)
{
@ -4325,8 +4332,11 @@ gimp_image_set_selected_layers (GimpImage *image,
if (active_layer)
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (active_layer));
gimp_item_tree_set_selected_items (private->layers,
g_list_copy (layers));
gimp_item_tree_set_selected_items (private->layers, layers2);
}
else
{
g_list_free (layers2);
}
return g_list_copy (gimp_image_get_selected_layers (image));