app: "active item" concept => "selected items".

After much thought, tests and discussions with Aryeom, we decided adding
back an active item concept additionally to the selected items ones is a
bad idea as it makes only usage unecessarily complex.
We will just have selected layers. Some kind of operations will work
when more than one item (layers, channels, vectors) are selected while
others will require exacty one item.

In particular, let's replace instances of gimp_image_(s|g)et_active_*()
by corresponding gimp_image_(s|g)et_selected_*(). Also replace single
item in various undo classes by GList of items.
Also "active-*-changed" GimpImage signals are no more, fully replaced by
"selected-*s-changed".

This is still work-in-progress.
This commit is contained in:
Jehan 2020-04-04 02:49:51 +02:00
parent 309ccf71b4
commit bcacf6e2ae
25 changed files with 499 additions and 307 deletions

View File

@ -34,11 +34,12 @@ enum
PROP_0,
PROP_PREV_PARENT,
PROP_PREV_POSITION,
PROP_PREV_CHANNEL
PROP_PREV_CHANNELS
};
static void gimp_channel_undo_constructed (GObject *object);
static void gimp_channel_undo_finalize (GObject *object);
static void gimp_channel_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -69,6 +70,7 @@ gimp_channel_undo_class_init (GimpChannelUndoClass *klass)
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_channel_undo_constructed;
object_class->finalize = gimp_channel_undo_finalize;
object_class->set_property = gimp_channel_undo_set_property;
object_class->get_property = gimp_channel_undo_get_property;
@ -90,17 +92,17 @@ gimp_channel_undo_class_init (GimpChannelUndoClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_CHANNEL,
g_param_spec_object ("prev-channel",
NULL, NULL,
GIMP_TYPE_CHANNEL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_CHANNELS,
g_param_spec_pointer ("prev-channels",
NULL, NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_channel_undo_init (GimpChannelUndo *undo)
{
undo->prev_channels = NULL;
}
static void
@ -111,6 +113,16 @@ gimp_channel_undo_constructed (GObject *object)
gimp_assert (GIMP_IS_CHANNEL (GIMP_ITEM_UNDO (object)->item));
}
static void
gimp_channel_undo_finalize (GObject *object)
{
GimpChannelUndo *channel_undo = GIMP_CHANNEL_UNDO (object);
g_clear_pointer (&channel_undo->prev_channels, g_list_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_channel_undo_set_property (GObject *object,
guint property_id,
@ -127,8 +139,8 @@ gimp_channel_undo_set_property (GObject *object,
case PROP_PREV_POSITION:
channel_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_CHANNEL:
channel_undo->prev_channel = g_value_get_object (value);
case PROP_PREV_CHANNELS:
channel_undo->prev_channels = g_list_copy (g_value_get_pointer (value));
break;
default:
@ -153,8 +165,8 @@ gimp_channel_undo_get_property (GObject *object,
case PROP_PREV_POSITION:
g_value_set_int (value, channel_undo->prev_position);
break;
case PROP_PREV_CHANNEL:
g_value_set_object (value, channel_undo->prev_channel);
case PROP_PREV_CHANNELS:
g_value_set_pointer (value, channel_undo->prev_channels);
break;
default:
@ -200,14 +212,15 @@ gimp_channel_undo_pop (GimpUndo *undo,
channel_undo->prev_position = gimp_item_get_index (GIMP_ITEM (channel));
gimp_image_remove_channel (undo->image, channel, FALSE,
channel_undo->prev_channel);
channel_undo->prev_channels);
}
else
{
/* restore channel */
/* record the active channel */
channel_undo->prev_channel = gimp_image_get_active_channel (undo->image);
g_clear_pointer (&channel_undo->prev_channels, g_list_free);
channel_undo->prev_channels = g_list_copy (gimp_image_get_selected_channels (undo->image));
gimp_image_add_channel (undo->image, channel,
channel_undo->prev_parent,

View File

@ -38,8 +38,8 @@ struct _GimpChannelUndo
GimpItemUndo parent_instance;
GimpChannel *prev_parent;
gint prev_position; /* former position in list */
GimpChannel *prev_channel; /* previous active channel */
gint prev_position; /* former position in list */
GList *prev_channels; /* previous selected channels */
};
struct _GimpChannelUndoClass

View File

@ -57,11 +57,11 @@ static void gimp_image_duplicate_colormap (GimpImage *image,
GimpImage *new_image);
static GimpItem * gimp_image_duplicate_item (GimpItem *item,
GimpImage *new_image);
static GimpLayer * gimp_image_duplicate_layers (GimpImage *image,
static GList * gimp_image_duplicate_layers (GimpImage *image,
GimpImage *new_image);
static GimpChannel * gimp_image_duplicate_channels (GimpImage *image,
static GList * gimp_image_duplicate_channels (GimpImage *image,
GimpImage *new_image);
static GimpVectors * gimp_image_duplicate_vectors (GimpImage *image,
static GList * gimp_image_duplicate_vectors (GimpImage *image,
GimpImage *new_image);
static void gimp_image_duplicate_floating_sel (GimpImage *image,
GimpImage *new_image);
@ -89,9 +89,9 @@ GimpImage *
gimp_image_duplicate (GimpImage *image)
{
GimpImage *new_image;
GimpLayer *active_layer;
GimpChannel *active_channel;
GimpVectors *active_vectors;
GList *active_layers;
GList *active_channels;
GList *active_vectors;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -120,10 +120,10 @@ gimp_image_duplicate (GimpImage *image)
gimp_image_duplicate_colormap (image, new_image);
/* Copy the layers */
active_layer = gimp_image_duplicate_layers (image, new_image);
active_layers = gimp_image_duplicate_layers (image, new_image);
/* Copy the channels */
active_channel = gimp_image_duplicate_channels (image, new_image);
active_channels = gimp_image_duplicate_channels (image, new_image);
/* Copy any vectors */
active_vectors = gimp_image_duplicate_vectors (image, new_image);
@ -135,14 +135,14 @@ gimp_image_duplicate (GimpImage *image)
gimp_image_duplicate_mask (image, new_image);
/* Set active layer, active channel, active vectors */
if (active_layer)
gimp_image_set_active_layer (new_image, active_layer);
if (active_layers)
gimp_image_set_selected_layers (new_image, active_layers);
if (active_channel)
gimp_image_set_active_channel (new_image, active_channel);
if (active_channels)
gimp_image_set_selected_channels (new_image, active_channels);
if (active_vectors)
gimp_image_set_active_vectors (new_image, active_vectors);
gimp_image_set_selected_vectors (new_image, active_vectors);
/* Copy state of all color components */
gimp_image_duplicate_components (image, new_image);
@ -221,13 +221,16 @@ gimp_image_duplicate_item (GimpItem *item,
return new_item;
}
static GimpLayer *
static GList *
gimp_image_duplicate_layers (GimpImage *image,
GimpImage *new_image)
{
GimpLayer *active_layer = NULL;
GList *list;
gint count;
GList *new_selected_layers = NULL;
GList *selected_layers;
GList *list;
gint count;
selected_layers = gimp_image_get_selected_layers (image);
for (list = gimp_image_get_layer_iter (image), count = 0;
list;
@ -249,23 +252,26 @@ gimp_image_duplicate_layers (GimpImage *image,
gimp_object_set_name (GIMP_OBJECT (new_layer->mask),
gimp_object_get_name (layer->mask));
if (gimp_image_get_active_layer (image) == layer)
active_layer = new_layer;
if (g_list_find (selected_layers, layer))
new_selected_layers = g_list_prepend (new_selected_layers, new_layer);
gimp_image_add_layer (new_image, new_layer,
NULL, count++, FALSE);
}
return active_layer;
return new_selected_layers;
}
static GimpChannel *
static GList *
gimp_image_duplicate_channels (GimpImage *image,
GimpImage *new_image)
{
GimpChannel *active_channel = NULL;
GList *list;
gint count;
GList *new_selected_channels = NULL;
GList *selected_channels;
GList *list;
gint count;
selected_channels = gimp_image_get_selected_channels (image);
for (list = gimp_image_get_channel_iter (image), count = 0;
list;
@ -277,23 +283,26 @@ gimp_image_duplicate_channels (GimpImage *image,
new_channel = GIMP_CHANNEL (gimp_image_duplicate_item (GIMP_ITEM (channel),
new_image));
if (gimp_image_get_active_channel (image) == channel)
active_channel = new_channel;
if (g_list_find (selected_channels, channel))
new_selected_channels = g_list_prepend (new_selected_channels, new_channel);
gimp_image_add_channel (new_image, new_channel,
NULL, count++, FALSE);
}
return active_channel;
return new_selected_channels;
}
static GimpVectors *
static GList *
gimp_image_duplicate_vectors (GimpImage *image,
GimpImage *new_image)
{
GimpVectors *active_vectors = NULL;
GList *list;
gint count;
GList *new_selected_vectors = NULL;
GList *selected_vectors;
GList *list;
gint count;
selected_vectors = gimp_image_get_selected_vectors (image);
for (list = gimp_image_get_vectors_iter (image), count = 0;
list;
@ -305,14 +314,15 @@ gimp_image_duplicate_vectors (GimpImage *image,
new_vectors = GIMP_VECTORS (gimp_image_duplicate_item (GIMP_ITEM (vectors),
new_image));
if (gimp_image_get_active_vectors (image) == vectors)
active_vectors = new_vectors;
if (g_list_find (selected_vectors, vectors))
new_selected_vectors = g_list_prepend (new_selected_vectors, new_vectors);
gimp_image_add_vectors (new_image, new_vectors,
NULL, count++, FALSE);
}
return active_vectors;
return new_selected_vectors;
}
static void

View File

@ -132,7 +132,7 @@ gimp_image_set_quick_mask_state (GimpImage *image,
gimp_image_remove_channel (image, mask, TRUE, NULL);
if (! channel_was_active)
gimp_image_unset_active_channel (image);
gimp_image_unset_selected_channels (image);
gimp_image_undo_group_end (image);
}

View File

@ -529,19 +529,22 @@ GimpUndo *
gimp_image_undo_push_layer_add (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer,
GimpLayer *prev_layer)
GList *prev_layers)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (! gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
g_return_val_if_fail (prev_layer == NULL || GIMP_IS_LAYER (prev_layer),
NULL);
for (iter = prev_layers; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_LAYER (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_UNDO,
GIMP_UNDO_LAYER_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
"item", layer,
"prev-layer", prev_layer,
"item", layer,
"prev-layers", prev_layers,
NULL);
}
@ -551,15 +554,18 @@ gimp_image_undo_push_layer_remove (GimpImage *image,
GimpLayer *layer,
GimpLayer *prev_parent,
gint prev_position,
GimpLayer *prev_layer)
GList *prev_layers)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
g_return_val_if_fail (prev_parent == NULL || GIMP_IS_LAYER (prev_parent),
NULL);
g_return_val_if_fail (prev_layer == NULL || GIMP_IS_LAYER (prev_layer),
NULL);
for (iter = prev_layers; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_LAYER (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_UNDO,
GIMP_UNDO_LAYER_REMOVE, undo_desc,
@ -567,7 +573,7 @@ gimp_image_undo_push_layer_remove (GimpImage *image,
"item", layer,
"prev-parent", prev_parent,
"prev-position", prev_position,
"prev-layer", prev_layer,
"prev-layers", prev_layers,
NULL);
}
@ -879,19 +885,22 @@ GimpUndo *
gimp_image_undo_push_channel_add (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel,
GimpChannel *prev_channel)
GList *prev_channels)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
g_return_val_if_fail (! gimp_item_is_attached (GIMP_ITEM (channel)), NULL);
g_return_val_if_fail (prev_channel == NULL || GIMP_IS_CHANNEL (prev_channel),
NULL);
for (iter = prev_channels; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_CHANNEL (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_CHANNEL_UNDO,
GIMP_UNDO_CHANNEL_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
"item", channel,
"prev-channel", prev_channel,
"item", channel,
"prev-channels", prev_channels,
NULL);
}
@ -901,15 +910,18 @@ gimp_image_undo_push_channel_remove (GimpImage *image,
GimpChannel *channel,
GimpChannel *prev_parent,
gint prev_position,
GimpChannel *prev_channel)
GList *prev_channels)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)), NULL);
g_return_val_if_fail (prev_parent == NULL || GIMP_IS_CHANNEL (prev_parent),
NULL);
g_return_val_if_fail (prev_channel == NULL || GIMP_IS_CHANNEL (prev_channel),
NULL);
for (iter = prev_channels; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_CHANNEL (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_CHANNEL_UNDO,
GIMP_UNDO_CHANNEL_REMOVE, undo_desc,
@ -917,7 +929,7 @@ gimp_image_undo_push_channel_remove (GimpImage *image,
"item", channel,
"prev-parent", prev_parent,
"prev-position", prev_position,
"prev-channel", prev_channel,
"prev-channels", prev_channels,
NULL);
}
@ -946,13 +958,16 @@ GimpUndo *
gimp_image_undo_push_vectors_add (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors,
GimpVectors *prev_vectors)
GList *prev_vectors)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
g_return_val_if_fail (! gimp_item_is_attached (GIMP_ITEM (vectors)), NULL);
g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors),
NULL);
for (iter = prev_vectors; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_VECTORS (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO,
GIMP_UNDO_VECTORS_ADD, undo_desc,
@ -968,15 +983,18 @@ gimp_image_undo_push_vectors_remove (GimpImage *image,
GimpVectors *vectors,
GimpVectors *prev_parent,
gint prev_position,
GimpVectors *prev_vectors)
GList *prev_vectors)
{
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (vectors)), NULL);
g_return_val_if_fail (prev_parent == NULL || GIMP_IS_VECTORS (prev_parent),
NULL);
g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors),
NULL);
for (iter = prev_vectors; iter; iter = iter->next)
g_return_val_if_fail (GIMP_IS_VECTORS (iter->data), NULL);
return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO,
GIMP_UNDO_VECTORS_REMOVE, undo_desc,

View File

@ -128,13 +128,13 @@ GimpUndo * gimp_image_undo_push_item_parasite_remove(GimpImage *image,
GimpUndo * gimp_image_undo_push_layer_add (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer,
GimpLayer *prev_layer);
GList *prev_layers);
GimpUndo * gimp_image_undo_push_layer_remove (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer,
GimpLayer *prev_parent,
gint prev_position,
GimpLayer *prev_layer);
GList *prev_layers);
GimpUndo * gimp_image_undo_push_layer_mode (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer);
@ -214,13 +214,13 @@ GimpUndo * gimp_image_undo_push_layer_mask_show (GimpImage *image,
GimpUndo * gimp_image_undo_push_channel_add (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel,
GimpChannel *prev_channel);
GList *prev_channels);
GimpUndo * gimp_image_undo_push_channel_remove (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel,
GimpChannel *prev_parent,
gint prev_position,
GimpChannel *prev_channel);
GList *prev_channels);
GimpUndo * gimp_image_undo_push_channel_color (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel);
@ -231,13 +231,13 @@ GimpUndo * gimp_image_undo_push_channel_color (GimpImage *image,
GimpUndo * gimp_image_undo_push_vectors_add (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors,
GimpVectors *prev_vectors);
GList *prev_vectors);
GimpUndo * gimp_image_undo_push_vectors_remove (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors,
GimpVectors *prev_parent,
gint prev_position,
GimpVectors *prev_vectors);
GList *prev_vectors);
GimpUndo * gimp_image_undo_push_vectors_mod (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors);

View File

@ -99,8 +99,8 @@ enum
PRECISION_CHANGED,
ALPHA_CHANGED,
FLOATING_SELECTION_CHANGED,
ACTIVE_CHANNEL_CHANGED,
ACTIVE_VECTORS_CHANGED,
SELECTED_CHANNELS_CHANGED,
SELECTED_VECTORS_CHANGED,
SELECTED_LAYERS_CHANGED,
LINKED_ITEMS_CHANGED,
COMPONENT_VISIBILITY_CHANGED,
@ -255,20 +255,27 @@ static void gimp_image_channel_name_changed (GimpChannel *channel,
GimpImage *image);
static void gimp_image_channel_color_changed (GimpChannel *channel,
GimpImage *image);
static void gimp_image_active_layer_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_active_channel_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_active_vectors_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_selected_layers_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_selected_channels_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_selected_vectors_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image);
static void gimp_image_freeze_bounding_box (GimpImage *image);
static void gimp_image_thaw_bounding_box (GimpImage *image);
static void gimp_image_update_bounding_box (GimpImage *image);
static gint gimp_image_layer_stack_cmp (GList *layers1,
GList *layers2);
static void gimp_image_remove_from_layer_stack (GimpImage *image,
GimpLayer *layer);
static gint gimp_image_selected_is_descendant (GimpViewable *selected,
GimpViewable *viewable);
G_DEFINE_TYPE_WITH_CODE (GimpImage, gimp_image, GIMP_TYPE_VIEWABLE,
G_ADD_PRIVATE (GimpImage)
@ -331,19 +338,19 @@ gimp_image_class_init (GimpImageClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
gimp_image_signals[ACTIVE_CHANNEL_CHANGED] =
g_signal_new ("active-channel-changed",
gimp_image_signals[SELECTED_CHANNELS_CHANGED] =
g_signal_new ("selected-channels-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpImageClass, active_channel_changed),
G_STRUCT_OFFSET (GimpImageClass, selected_channels_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
gimp_image_signals[ACTIVE_VECTORS_CHANGED] =
g_signal_new ("active-vectors-changed",
gimp_image_signals[SELECTED_VECTORS_CHANGED] =
g_signal_new ("selected-vectors-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpImageClass, active_vectors_changed),
G_STRUCT_OFFSET (GimpImageClass, selected_vectors_changed),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
@ -584,8 +591,9 @@ gimp_image_class_init (GimpImageClass *klass)
klass->precision_changed = gimp_image_real_precision_changed;
klass->alpha_changed = NULL;
klass->floating_selection_changed = NULL;
klass->active_channel_changed = NULL;
klass->active_vectors_changed = NULL;
klass->selected_layers_changed = NULL;
klass->selected_channels_changed = NULL;
klass->selected_vectors_changed = NULL;
klass->linked_items_changed = NULL;
klass->component_visibility_changed = NULL;
klass->component_active_changed = NULL;
@ -770,13 +778,13 @@ gimp_image_init (GimpImage *image)
image);
g_signal_connect (private->layers, "notify::selected-items",
G_CALLBACK (gimp_image_active_layer_notify),
G_CALLBACK (gimp_image_selected_layers_notify),
image);
g_signal_connect (private->channels, "notify::selected-items",
G_CALLBACK (gimp_image_active_channel_notify),
G_CALLBACK (gimp_image_selected_channels_notify),
image);
g_signal_connect (private->vectors, "notify::selected-items",
G_CALLBACK (gimp_image_active_vectors_notify),
G_CALLBACK (gimp_image_selected_vectors_notify),
image);
g_signal_connect_swapped (private->layers->container, "update",
@ -1110,7 +1118,8 @@ gimp_image_finalize (GObject *object)
if (private->layer_stack)
{
g_slist_free (private->layer_stack);
g_slist_free_full (private->layer_stack,
(GDestroyNotify) g_list_free);
private->layer_stack = NULL;
}
@ -1721,45 +1730,56 @@ gimp_image_channel_color_changed (GimpChannel *channel,
}
static void
gimp_image_active_layer_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
gimp_image_selected_layers_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
{
GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
GimpLayer *layer = gimp_image_get_active_layer (image);
GList *layers = gimp_image_get_selected_layers (image);
if (layer)
if (layers)
{
/* Configure the layer stack to reflect this change */
private->layer_stack = g_slist_remove (private->layer_stack, layer);
private->layer_stack = g_slist_prepend (private->layer_stack, layer);
GSList *prev_layers;
prev_layers = g_slist_find_custom (private->layer_stack, layers,
(GCompareFunc) gimp_image_layer_stack_cmp);
if (prev_layers)
{
g_list_free (prev_layers->data);
private->layer_stack = g_slist_delete_link (private->layer_stack,
prev_layers);
}
private->layer_stack = g_slist_prepend (private->layer_stack,
g_list_copy (layers));
}
g_signal_emit (image, gimp_image_signals[SELECTED_LAYERS_CHANGED], 0);
if (layer && gimp_image_get_active_channel (image))
gimp_image_set_active_channel (image, NULL);
if (layers && gimp_image_get_selected_channels (image))
gimp_image_set_selected_channels (image, NULL);
}
static void
gimp_image_active_channel_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
gimp_image_selected_channels_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
{
GimpChannel *channel = gimp_image_get_active_channel (image);
GList *channels = gimp_image_get_selected_channels (image);
g_signal_emit (image, gimp_image_signals[ACTIVE_CHANNEL_CHANGED], 0);
g_signal_emit (image, gimp_image_signals[SELECTED_CHANNELS_CHANGED], 0);
if (channel && gimp_image_get_active_layer (image))
gimp_image_set_active_layer (image, NULL);
if (channels && gimp_image_get_selected_layers (image))
gimp_image_set_selected_layers (image, NULL);
}
static void
gimp_image_active_vectors_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
gimp_image_selected_vectors_notify (GimpItemTree *tree,
const GParamSpec *pspec,
GimpImage *image)
{
g_signal_emit (image, gimp_image_signals[ACTIVE_VECTORS_CHANGED], 0);
g_signal_emit (image, gimp_image_signals[SELECTED_VECTORS_CHANGED], 0);
}
static void
@ -1838,6 +1858,96 @@ gimp_image_update_bounding_box (GimpImage *image)
}
}
static gint
gimp_image_layer_stack_cmp (GList *layers1,
GList *layers2)
{
if (g_list_length (layers1) != g_list_length (layers2))
{
/* We don't really need to order lists of layers, and only care
* about identity.
*/
return 1;
}
else
{
GList *iter;
for (iter = layers1; iter; iter = iter->next)
{
if (! g_list_find (layers2, iter))
return 1;
}
return 0;
}
}
static void
gimp_image_remove_from_layer_stack (GimpImage *image,
GimpLayer *layer)
{
GimpImagePrivate *private;
GSList *slist;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GIMP_IS_LAYER (layer));
private = GIMP_IMAGE_GET_PRIVATE (image);
/* Remove layer itself from the MRU layer stack. */
for (slist = private->layer_stack; slist; slist = slist->next)
{
GList *layers = slist->data;
layers = g_list_remove (layers, layer);
if (layers == NULL)
private->layer_stack = g_slist_delete_link (private->layer_stack, slist);
else
slist->data = layers;
}
/* Also remove all children of a group layer from the layer_stack */
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
GimpContainer *stack = gimp_viewable_get_children (GIMP_VIEWABLE (layer));
GList *children;
GList *list;
children = gimp_item_stack_get_item_list (GIMP_ITEM_STACK (stack));
for (list = children; list; list = g_list_next (list))
{
GimpLayer *child = list->data;
for (slist = private->layer_stack; slist; slist = slist->next)
{
GList *layers = slist->data;
layers = g_list_remove (layers, child);
if (layers == NULL)
private->layer_stack = g_slist_delete_link (private->layer_stack, slist);
else
slist->data = layers;
}
}
g_list_free (children);
}
}
static gint
gimp_image_selected_is_descendant (GimpViewable *selected,
GimpViewable *viewable)
{
/* Used as a GCompareFunc to g_list_find_custom() in order to know if
* one of the selected items is a descendant to @viewable.
*/
if (gimp_viewable_is_ancestor (viewable, selected))
return 0;
else
return 1;
}
/* public functions */
@ -3076,7 +3186,7 @@ gimp_image_set_component_active (GimpImage *image,
/* If there is an active channel and we mess with the components,
* the active channel gets unset...
*/
gimp_image_unset_active_channel (image);
gimp_image_unset_selected_channels (image);
g_signal_emit (image,
gimp_image_signals[COMPONENT_ACTIVE_CHANGED], 0,
@ -4266,7 +4376,6 @@ gimp_image_set_active_layer (GimpImage *image,
GimpLayer *layer)
{
GList *layers = NULL;
GList *new_layers;
GimpLayer *active_layer;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -4278,11 +4387,11 @@ gimp_image_set_active_layer (GimpImage *image,
if (layer)
layers = g_list_prepend (NULL, layer);
new_layers = gimp_image_set_selected_layers (image, layers);
gimp_image_set_selected_layers (image, layers);
g_list_free (layers);
active_layer = g_list_length (new_layers) == 1 ? new_layers->data : NULL;
g_list_free (new_layers);
layers = gimp_image_get_selected_layers (image);
active_layer = g_list_length (layers) == 1 ? layers->data : NULL;
return active_layer;
}
@ -4293,7 +4402,6 @@ gimp_image_set_active_channel (GimpImage *image,
{
GimpChannel *active_channel;
GList *channels = NULL;
GList *new_channels;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (channel == NULL || GIMP_IS_CHANNEL (channel), NULL);
@ -4309,36 +4417,34 @@ gimp_image_set_active_channel (GimpImage *image,
if (channel)
channels = g_list_prepend (NULL, channel);
new_channels = gimp_image_set_selected_channels (image, channels);
gimp_image_set_selected_channels (image, channels);
g_list_free (channels);
active_channel = g_list_length (new_channels) == 1 ? new_channels->data : NULL;
g_list_free (new_channels);
channels = gimp_image_get_selected_channels (image);
active_channel = g_list_length (channels) == 1 ? channels->data : NULL;
return active_channel;
}
GimpChannel *
gimp_image_unset_active_channel (GimpImage *image)
void
gimp_image_unset_selected_channels (GimpImage *image)
{
GimpImagePrivate *private;
GimpChannel *channel;
GList *channels;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_if_fail (GIMP_IS_IMAGE (image));
private = GIMP_IMAGE_GET_PRIVATE (image);
channel = gimp_image_get_active_channel (image);
channels = gimp_image_get_selected_channels (image);
if (channel)
if (channels)
{
gimp_image_set_active_channel (image, NULL);
gimp_image_set_selected_channels (image, NULL);
if (private->layer_stack)
gimp_image_set_active_layer (image, private->layer_stack->data);
gimp_image_set_selected_layers (image, private->layer_stack->data);
}
return channel;
}
GimpVectors *
@ -4346,7 +4452,6 @@ gimp_image_set_active_vectors (GimpImage *image,
GimpVectors *vectors)
{
GList *all_vectors = NULL;
GList *new_vectors;
GimpVectors *active_vectors;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -4358,11 +4463,11 @@ gimp_image_set_active_vectors (GimpImage *image,
if (vectors)
all_vectors = g_list_prepend (NULL, vectors);
new_vectors = gimp_image_set_selected_vectors (image, all_vectors);
gimp_image_set_selected_vectors (image, all_vectors);
g_list_free (all_vectors);
active_vectors = (g_list_length (new_vectors) == 1 ? new_vectors->data : NULL);
g_list_free (new_vectors);
all_vectors = gimp_image_get_selected_vectors (image);
active_vectors = (g_list_length (all_vectors) == 1 ? all_vectors->data : NULL);
return active_vectors;
}
@ -4403,25 +4508,24 @@ gimp_image_get_selected_vectors (GimpImage *image)
return gimp_item_tree_get_selected_items (private->vectors);
}
GList *
void
gimp_image_set_selected_layers (GimpImage *image,
GList *layers)
{
GimpImagePrivate *private;
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);
g_return_if_fail (GIMP_IS_IMAGE (image));
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_get_image (GIMP_ITEM (iter->data)) == image, NULL);
g_return_if_fail (GIMP_IS_LAYER (iter->data));
g_return_if_fail (gimp_item_get_image (GIMP_ITEM (iter->data)) == image);
/* Silently remove non-attached layers from selection. Do not
* error out on it as it may happen for instance when selection
@ -4437,10 +4541,9 @@ gimp_image_set_selected_layers (GimpImage *image,
/* Make sure the floating_sel always is the active layer */
if (floating_sel && (g_list_length (layers2) != 1 || layers2->data != floating_sel))
return g_list_prepend (NULL, floating_sel);
return;
selected_layers = gimp_image_get_selected_layers (image);
active_layer = gimp_image_get_active_layer (image);
if (g_list_length (layers2) == g_list_length (selected_layers))
{
@ -4458,8 +4561,8 @@ gimp_image_set_selected_layers (GimpImage *image,
if (selection_changed)
{
/* Don't cache selection info for the previous active layer */
if (active_layer)
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (active_layer));
if (selected_layers)
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (selected_layers->data));
gimp_item_tree_set_selected_items (private->layers, layers2);
}
@ -4467,57 +4570,51 @@ gimp_image_set_selected_layers (GimpImage *image,
{
g_list_free (layers2);
}
return g_list_copy (gimp_image_get_selected_layers (image));
}
GList *
void
gimp_image_set_selected_channels (GimpImage *image,
GList *channels)
{
GimpImagePrivate *private;
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_if_fail (GIMP_IS_IMAGE (image));
for (iter = channels; iter; iter = iter->next)
{
g_return_val_if_fail (GIMP_IS_CHANNEL (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_if_fail (GIMP_IS_CHANNEL (iter->data));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (iter->data)) &&
gimp_item_get_image (GIMP_ITEM (iter->data)) == image);
}
private = GIMP_IMAGE_GET_PRIVATE (image);
/* Not if there is a floating selection */
if (g_list_length (channels) > 0 && gimp_image_get_floating_selection (image))
return NULL;
return;
gimp_item_tree_set_selected_items (private->channels, g_list_copy (channels));
return g_list_copy (gimp_image_get_selected_channels (image));
}
GList *
void
gimp_image_set_selected_vectors (GimpImage *image,
GList *vectors)
{
GimpImagePrivate *private;
GList *iter;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_if_fail (GIMP_IS_IMAGE (image));
for (iter = vectors; iter; iter = iter->next)
{
g_return_val_if_fail (GIMP_IS_VECTORS (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_if_fail (GIMP_IS_VECTORS (iter->data));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (iter->data)) &&
gimp_item_get_image (GIMP_ITEM (iter->data)) == image);
}
private = GIMP_IMAGE_GET_PRIVATE (image);
gimp_item_tree_set_selected_items (private->vectors, g_list_copy (vectors));
return g_list_copy (gimp_image_get_selected_vectors (image));
}
@ -4759,6 +4856,7 @@ gimp_image_add_layer (GimpImage *image,
gboolean push_undo)
{
GimpImagePrivate *private;
GList *selected_layers;
gboolean old_has_alpha;
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@ -4787,12 +4885,14 @@ gimp_image_add_layer (GimpImage *image,
if (push_undo)
gimp_image_undo_push_layer_add (image, C_("undo-type", "Add Layer"),
layer,
gimp_image_get_active_layer (image));
gimp_image_get_selected_layers (image));
gimp_item_tree_add_item (private->layers, GIMP_ITEM (layer),
GIMP_ITEM (parent), position);
gimp_image_set_active_layer (image, layer);
selected_layers = g_list_prepend (NULL, layer);
gimp_image_set_selected_layers (image, selected_layers);
g_list_free (selected_layers);
/* If the layer is a floating selection, attach it to the drawable */
if (gimp_layer_is_floating_sel (layer))
@ -4809,10 +4909,10 @@ void
gimp_image_remove_layer (GimpImage *image,
GimpLayer *layer,
gboolean push_undo,
GimpLayer *new_active)
GList *new_selected)
{
GimpImagePrivate *private;
GimpLayer *active_layer;
GList *selected_layers;
gboolean old_has_alpha;
const gchar *undo_desc;
@ -4846,7 +4946,7 @@ gimp_image_remove_layer (GimpImage *image,
TRUE, NULL);
}
active_layer = gimp_image_get_active_layer (image);
selected_layers = g_list_copy (gimp_image_get_selected_layers (image));
old_has_alpha = gimp_image_has_alpha (image);
@ -4865,38 +4965,20 @@ gimp_image_remove_layer (GimpImage *image,
gimp_image_undo_push_layer_remove (image, undo_desc, layer,
gimp_layer_get_parent (layer),
gimp_item_get_index (GIMP_ITEM (layer)),
active_layer);
selected_layers);
g_object_ref (layer);
/* Make sure we're not caching any old selection info */
if (layer == active_layer)
if (g_list_find (selected_layers, layer))
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
private->layer_stack = g_slist_remove (private->layer_stack, layer);
/* Remove layer and its children from the MRU layer stack. */
gimp_image_remove_from_layer_stack (image, layer);
/* Also remove all children of a group layer from the layer_stack */
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
GimpContainer *stack = gimp_viewable_get_children (GIMP_VIEWABLE (layer));
GList *children;
GList *list;
children = gimp_item_stack_get_item_list (GIMP_ITEM_STACK (stack));
for (list = children; list; list = g_list_next (list))
{
private->layer_stack = g_slist_remove (private->layer_stack,
list->data);
}
g_list_free (children);
}
new_active =
GIMP_LAYER (gimp_item_tree_remove_item (private->layers,
GIMP_ITEM (layer),
GIMP_ITEM (new_active)));
new_selected = gimp_item_tree_remove_item (private->layers,
GIMP_ITEM (layer),
new_selected);
if (gimp_layer_is_floating_sel (layer))
{
@ -4904,17 +4986,20 @@ gimp_image_remove_layer (GimpImage *image,
*/
floating_sel_activate_drawable (layer);
}
else if (active_layer &&
(layer == active_layer ||
gimp_viewable_is_ancestor (GIMP_VIEWABLE (layer),
GIMP_VIEWABLE (active_layer))))
else if (selected_layers &&
(g_list_find (selected_layers, layer) ||
g_list_find_custom (selected_layers, layer,
(GCompareFunc) gimp_image_selected_is_descendant)))
{
gimp_image_set_active_layer (image, new_active);
gimp_image_set_selected_layers (image, new_selected);
}
gimp_item_end_move (GIMP_ITEM (layer), push_undo);
g_object_unref (layer);
g_list_free (selected_layers);
if (new_selected)
g_list_free (new_selected);
if (old_has_alpha != gimp_image_has_alpha (image))
private->flush_accum.alpha_changed = TRUE;
@ -4989,7 +5074,7 @@ gimp_image_add_layers (GimpImage *image,
}
if (layers)
gimp_image_set_active_layer (image, layers->data);
gimp_image_set_selected_layers (image, layers);
gimp_image_undo_group_end (image);
}
@ -5005,6 +5090,7 @@ gimp_image_add_channel (GimpImage *image,
gboolean push_undo)
{
GimpImagePrivate *private;
GList *channels;
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@ -5021,12 +5107,14 @@ gimp_image_add_channel (GimpImage *image,
if (push_undo)
gimp_image_undo_push_channel_add (image, C_("undo-type", "Add Channel"),
channel,
gimp_image_get_active_channel (image));
gimp_image_get_selected_channels (image));
gimp_item_tree_add_item (private->channels, GIMP_ITEM (channel),
GIMP_ITEM (parent), position);
gimp_image_set_active_channel (image, channel);
channels = g_list_prepend (NULL, channel);
gimp_image_set_selected_channels (image, channels);
g_list_free (channels);
return TRUE;
}
@ -5035,10 +5123,10 @@ void
gimp_image_remove_channel (GimpImage *image,
GimpChannel *channel,
gboolean push_undo,
GimpChannel *new_active)
GList *new_selected)
{
GimpImagePrivate *private;
GimpChannel *active_channel;
GList *selected_channels;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@ -5068,35 +5156,36 @@ gimp_image_remove_channel (GimpImage *image,
private = GIMP_IMAGE_GET_PRIVATE (image);
active_channel = gimp_image_get_active_channel (image);
selected_channels = gimp_image_get_selected_channels (image);
if (push_undo)
gimp_image_undo_push_channel_remove (image, C_("undo-type", "Remove Channel"), channel,
gimp_channel_get_parent (channel),
gimp_item_get_index (GIMP_ITEM (channel)),
active_channel);
selected_channels);
g_object_ref (channel);
new_active =
GIMP_CHANNEL (gimp_item_tree_remove_item (private->channels,
GIMP_ITEM (channel),
GIMP_ITEM (new_active)));
new_selected = gimp_item_tree_remove_item (private->channels,
GIMP_ITEM (channel),
new_selected);
if (active_channel &&
(channel == active_channel ||
gimp_viewable_is_ancestor (GIMP_VIEWABLE (channel),
GIMP_VIEWABLE (active_channel))))
if (selected_channels &&
(g_list_find (selected_channels, channel) ||
g_list_find_custom (selected_channels, channel,
(GCompareFunc) gimp_image_selected_is_descendant)))
{
if (new_active)
gimp_image_set_active_channel (image, new_active);
if (new_selected)
gimp_image_set_selected_channels (image, new_selected);
else
gimp_image_unset_active_channel (image);
gimp_image_unset_selected_channels (image);
}
gimp_item_end_move (GIMP_ITEM (channel), push_undo);
g_object_unref (channel);
if (new_selected)
g_list_free (new_selected);
if (push_undo)
gimp_image_undo_group_end (image);
@ -5129,7 +5218,7 @@ gimp_image_add_vectors (GimpImage *image,
if (push_undo)
gimp_image_undo_push_vectors_add (image, C_("undo-type", "Add Path"),
vectors,
gimp_image_get_active_vectors (image));
gimp_image_get_selected_vectors (image));
gimp_item_tree_add_item (private->vectors, GIMP_ITEM (vectors),
GIMP_ITEM (parent), position);
@ -5143,10 +5232,10 @@ void
gimp_image_remove_vectors (GimpImage *image,
GimpVectors *vectors,
gboolean push_undo,
GimpVectors *new_active)
GList *new_selected)
{
GimpImagePrivate *private;
GimpVectors *active_vectors;
GList *selected_vectors;
g_return_if_fail (GIMP_IS_IMAGE (image));
g_return_if_fail (GIMP_IS_VECTORS (vectors));
@ -5161,32 +5250,33 @@ gimp_image_remove_vectors (GimpImage *image,
gimp_item_start_move (GIMP_ITEM (vectors), push_undo);
active_vectors = gimp_image_get_active_vectors (image);
selected_vectors = gimp_image_get_selected_vectors (image);
if (push_undo)
gimp_image_undo_push_vectors_remove (image, C_("undo-type", "Remove Path"), vectors,
gimp_vectors_get_parent (vectors),
gimp_item_get_index (GIMP_ITEM (vectors)),
active_vectors);
selected_vectors);
g_object_ref (vectors);
new_active =
GIMP_VECTORS (gimp_item_tree_remove_item (private->vectors,
GIMP_ITEM (vectors),
GIMP_ITEM (new_active)));
new_selected = gimp_item_tree_remove_item (private->vectors,
GIMP_ITEM (vectors),
new_selected);
if (active_vectors &&
(vectors == active_vectors ||
gimp_viewable_is_ancestor (GIMP_VIEWABLE (vectors),
GIMP_VIEWABLE (active_vectors))))
if (selected_vectors &&
(g_list_find (selected_vectors, vectors) ||
g_list_find_custom (selected_vectors, vectors,
(GCompareFunc) gimp_image_selected_is_descendant)))
{
gimp_image_set_active_vectors (image, new_active);
gimp_image_set_selected_vectors (image, new_selected);
}
gimp_item_end_move (GIMP_ITEM (vectors), push_undo);
g_object_unref (vectors);
if (new_selected)
g_list_free (new_selected);
if (push_undo)
gimp_image_undo_group_end (image);

View File

@ -54,8 +54,8 @@ struct _GimpImageClass
void (* precision_changed) (GimpImage *image);
void (* alpha_changed) (GimpImage *image);
void (* floating_selection_changed) (GimpImage *image);
void (* active_channel_changed) (GimpImage *image);
void (* active_vectors_changed) (GimpImage *image);
void (* selected_channels_changed) (GimpImage *image);
void (* selected_vectors_changed) (GimpImage *image);
void (* selected_layers_changed) (GimpImage *image);
void (* linked_items_changed) (GimpImage *image);
void (* component_visibility_changed) (GimpImage *image,
@ -375,7 +375,7 @@ GimpLayer * gimp_image_set_active_layer (GimpImage *image,
GimpLayer *layer);
GimpChannel * gimp_image_set_active_channel (GimpImage *image,
GimpChannel *channel);
GimpChannel * gimp_image_unset_active_channel (GimpImage *image);
void gimp_image_unset_selected_channels (GimpImage *image);
GimpVectors * gimp_image_set_active_vectors (GimpImage *image,
GimpVectors *vectors);
@ -383,11 +383,11 @@ GList * gimp_image_get_selected_layers (GimpImage *image);
GList * gimp_image_get_selected_channels (GimpImage *image);
GList * gimp_image_get_selected_vectors (GimpImage *image);
GList * gimp_image_set_selected_layers (GimpImage *image,
void gimp_image_set_selected_layers (GimpImage *image,
GList *layers);
GList * gimp_image_set_selected_channels (GimpImage *image,
void gimp_image_set_selected_channels (GimpImage *image,
GList *channels);
GList * gimp_image_set_selected_vectors (GimpImage *image,
void gimp_image_set_selected_vectors (GimpImage *image,
GList *vectors);
GimpLayer * gimp_image_get_layer_by_tattoo (GimpImage *image,
@ -429,7 +429,7 @@ gboolean gimp_image_add_layer (GimpImage *image,
void gimp_image_remove_layer (GimpImage *image,
GimpLayer *layer,
gboolean push_undo,
GimpLayer *new_active);
GList *new_selected);
void gimp_image_add_layers (GimpImage *image,
GList *layers,
@ -449,7 +449,7 @@ gboolean gimp_image_add_channel (GimpImage *image,
void gimp_image_remove_channel (GimpImage *image,
GimpChannel *channel,
gboolean push_undo,
GimpChannel *new_active);
GList *new_selected);
gboolean gimp_image_add_vectors (GimpImage *image,
GimpVectors *vectors,
@ -459,7 +459,7 @@ gboolean gimp_image_add_vectors (GimpImage *image,
void gimp_image_remove_vectors (GimpImage *image,
GimpVectors *vectors,
gboolean push_undo,
GimpVectors *new_active);
GList *new_selected);
gboolean gimp_image_coords_in_active_pickable (GimpImage *image,
const GimpCoords *coords,

View File

@ -565,10 +565,10 @@ gimp_item_tree_add_item (GimpItemTree *tree,
gimp_item_unset_removed (item);
}
GimpItem *
GList *
gimp_item_tree_remove_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *new_active)
GList *new_selected)
{
GimpItemTreePrivate *private;
GimpItem *parent;
@ -615,26 +615,34 @@ gimp_item_tree_remove_item (GimpItemTree *tree,
gimp_item_removed (item);
if (! new_active)
if (! new_selected)
{
gint n_children = gimp_container_get_n_children (container);
GimpItem *selected = NULL;
gint n_children = gimp_container_get_n_children (container);
if (n_children > 0)
{
index = CLAMP (index, 0, n_children - 1);
new_active =
selected =
GIMP_ITEM (gimp_container_get_child_by_index (container, index));
}
else if (parent)
{
new_active = parent;
selected = parent;
}
if (selected)
new_selected = g_list_prepend (NULL, selected);
}
else
{
new_selected = g_list_copy (new_selected);
}
g_object_unref (item);
return new_active;
return new_selected;
}
gboolean

View File

@ -72,9 +72,9 @@ void gimp_item_tree_add_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *parent,
gint position);
GimpItem * gimp_item_tree_remove_item (GimpItemTree *tree,
GList * gimp_item_tree_remove_item (GimpItemTree *tree,
GimpItem *item,
GimpItem *new_active);
GList *new_selected);
gboolean gimp_item_tree_reorder_item (GimpItemTree *tree,
GimpItem *item,

View File

@ -228,11 +228,19 @@ floating_sel_activate_drawable (GimpLayer *layer)
}
else if (GIMP_IS_CHANNEL (drawable))
{
gimp_image_set_active_channel (image, GIMP_CHANNEL (drawable));
GList *channels = g_list_prepend (NULL, drawable);
gimp_image_set_selected_channels (image, channels);
g_list_free (channels);
}
else
{
gimp_image_set_active_layer (image, GIMP_LAYER (drawable));
GList *layers = g_list_prepend (NULL, drawable);
gimp_image_set_selected_layers (image, layers);
g_list_free (layers);
}
}

View File

@ -34,11 +34,12 @@ enum
PROP_0,
PROP_PREV_PARENT,
PROP_PREV_POSITION,
PROP_PREV_LAYER
PROP_PREV_LAYERS
};
static void gimp_layer_undo_constructed (GObject *object);
static void gimp_layer_undo_finalize (GObject *object);
static void gimp_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -69,6 +70,7 @@ gimp_layer_undo_class_init (GimpLayerUndoClass *klass)
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_layer_undo_constructed;
object_class->finalize = gimp_layer_undo_finalize;
object_class->set_property = gimp_layer_undo_set_property;
object_class->get_property = gimp_layer_undo_get_property;
@ -89,16 +91,16 @@ gimp_layer_undo_class_init (GimpLayerUndoClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_LAYER,
g_param_spec_object ("prev-layer", NULL, NULL,
GIMP_TYPE_LAYER,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_LAYERS,
g_param_spec_pointer ("prev-layers", NULL, NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_layer_undo_init (GimpLayerUndo *undo)
{
undo->prev_layers = NULL;
}
static void
@ -109,6 +111,15 @@ gimp_layer_undo_constructed (GObject *object)
gimp_assert (GIMP_IS_LAYER (GIMP_ITEM_UNDO (object)->item));
}
static void
gimp_layer_undo_finalize (GObject *object)
{
GimpLayerUndo *undo = GIMP_LAYER_UNDO (object);
g_clear_pointer (&undo->prev_layers, g_list_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_layer_undo_set_property (GObject *object,
guint property_id,
@ -125,8 +136,8 @@ gimp_layer_undo_set_property (GObject *object,
case PROP_PREV_POSITION:
layer_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_LAYER:
layer_undo->prev_layer = g_value_get_object (value);
case PROP_PREV_LAYERS:
layer_undo->prev_layers = g_list_copy (g_value_get_pointer (value));
break;
default:
@ -151,8 +162,8 @@ gimp_layer_undo_get_property (GObject *object,
case PROP_PREV_POSITION:
g_value_set_int (value, layer_undo->prev_position);
break;
case PROP_PREV_LAYER:
g_value_set_object (value, layer_undo->prev_layer);
case PROP_PREV_LAYERS:
g_value_set_pointer (value, layer_undo->prev_layers);
break;
default:
@ -198,14 +209,15 @@ gimp_layer_undo_pop (GimpUndo *undo,
layer_undo->prev_position = gimp_item_get_index (GIMP_ITEM (layer));
gimp_image_remove_layer (undo->image, layer, FALSE,
layer_undo->prev_layer);
layer_undo->prev_layers);
}
else
{
/* restore layer */
/* record the active layer */
layer_undo->prev_layer = gimp_image_get_active_layer (undo->image);
g_clear_pointer (&layer_undo->prev_layers, g_list_free);
layer_undo->prev_layers = g_list_copy (gimp_image_get_selected_layers (undo->image));
gimp_image_add_layer (undo->image, layer,
layer_undo->prev_parent,

View File

@ -39,7 +39,7 @@ struct _GimpLayerUndo
GimpLayer *prev_parent;
gint prev_position; /* former position in list */
GimpLayer *prev_layer; /* previous active layer */
GList *prev_layers; /* previous selected layers */
};
struct _GimpLayerUndoClass

View File

@ -295,7 +295,7 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
G_CALLBACK (gimp_display_shell_exported_handler),
shell);
g_signal_connect (image, "active-vectors-changed",
g_signal_connect (image, "selected-vectors-changed",
G_CALLBACK (gimp_display_shell_active_vectors_handler),
shell);

View File

@ -593,7 +593,7 @@ image_unset_active_channel_invoker (GimpProcedure *procedure,
if (success)
{
gimp_image_unset_active_channel (image);
gimp_image_unset_selected_channels (image);
}
return gimp_procedure_get_return_values (procedure, success,

View File

@ -961,7 +961,7 @@ gimp_bucket_fill_tool_reset_line_art (GimpBucketFillTool *tool)
g_signal_connect_swapped (image, "selected-layers-changed",
G_CALLBACK (gimp_bucket_fill_tool_reset_line_art),
tool);
g_signal_connect_swapped (image, "active-channel-changed",
g_signal_connect_swapped (image, "selected-channels-changed",
G_CALLBACK (gimp_bucket_fill_tool_reset_line_art),
tool);

View File

@ -155,8 +155,8 @@ gimp_move_tool_init (GimpMoveTool *move_tool)
move_tool->saved_type = GIMP_TRANSFORM_TYPE_LAYER;
move_tool->old_active_layer = NULL;
move_tool->old_active_vectors = NULL;
move_tool->old_selected_layers = NULL;
move_tool->old_selected_vectors = NULL;
}
static void
@ -165,6 +165,8 @@ gimp_move_tool_finalize (GObject *object)
GimpMoveTool *move = GIMP_MOVE_TOOL (object);
g_clear_pointer (&move->guides, g_list_free);
g_clear_pointer (&move->old_selected_layers, g_list_free);
g_clear_pointer (&move->old_selected_vectors, g_list_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -206,10 +208,13 @@ gimp_move_tool_button_press (GimpTool *tool,
FUNSCALEY (shell, snap_distance));
if (vectors)
{
move->old_active_vectors =
gimp_image_get_active_vectors (image);
GList *new_selected_vectors = g_list_prepend (NULL, vectors);
gimp_image_set_active_vectors (image, vectors);
move->old_selected_vectors =
g_list_copy (gimp_image_get_selected_vectors (image));
gimp_image_set_selected_vectors (image, new_selected_vectors);
g_list_free (new_selected_vectors);
}
else
{
@ -254,9 +259,12 @@ gimp_move_tool_button_press (GimpTool *tool,
}
else
{
move->old_active_layer = gimp_image_get_active_layer (image);
GList *new_selected_layers = g_list_prepend (NULL, layer);
gimp_image_set_active_layer (image, layer);
move->old_selected_layers = g_list_copy (gimp_image_get_selected_layers (image));
gimp_image_set_selected_layers (image, new_selected_layers);
g_list_free (new_selected_layers);
}
}
else
@ -388,18 +396,18 @@ gimp_move_tool_button_release (GimpTool *tool,
if (! config->move_tool_changes_active ||
(release_type == GIMP_BUTTON_RELEASE_CANCEL))
{
if (move->old_active_layer)
if (move->old_selected_layers)
{
gimp_image_set_active_layer (image, move->old_active_layer);
move->old_active_layer = NULL;
gimp_image_set_selected_layers (image, move->old_selected_layers);
g_clear_pointer (&move->old_selected_layers, g_list_free);
flush = TRUE;
}
if (move->old_active_vectors)
if (move->old_selected_vectors)
{
gimp_image_set_active_vectors (image, move->old_active_vectors);
move->old_active_vectors = NULL;
gimp_image_set_selected_vectors (image, move->old_selected_vectors);
g_clear_pointer (&move->old_selected_vectors, g_list_free);
flush = TRUE;
}

View File

@ -44,8 +44,8 @@ struct _GimpMoveTool
GimpTransformType saved_type;
GimpLayer *old_active_layer;
GimpVectors *old_active_vectors;
GList *old_selected_layers;
GList *old_selected_vectors;
};
struct _GimpMoveToolClass

View File

@ -487,12 +487,15 @@ gimp_text_tool_button_press (GimpTool *tool,
if (text_layer && text_layer != text_tool->layer)
{
GList *selection = g_list_prepend (NULL, text_layer);
if (text_tool->image == image)
g_signal_handlers_block_by_func (image,
gimp_text_tool_layer_changed,
text_tool);
gimp_image_set_active_layer (image, GIMP_LAYER (text_layer));
gimp_image_set_selected_layers (image, selection);
g_list_free (selection);
if (text_tool->image == image)
g_signal_handlers_unblock_by_func (image,
@ -1806,18 +1809,27 @@ static void
gimp_text_tool_layer_changed (GimpImage *image,
GimpTextTool *text_tool)
{
GimpLayer *layer = gimp_image_get_active_layer (image);
GList *layers = gimp_image_get_selected_layers (image);
if (layer != GIMP_LAYER (text_tool->layer))
if (g_list_length (layers) != 1 || layers->data != text_tool->layer)
{
GimpTool *tool = GIMP_TOOL (text_tool);
GimpDisplay *display = tool->display;
if (display)
{
GimpLayer *layer = NULL;
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
if (gimp_text_tool_set_drawable (text_tool, GIMP_DRAWABLE (layer),
if (g_list_length (layers) == 1)
layer = layers->data;
/* The tool can only be started when a single layer is
* selected and this is a text layer.
*/
if (layer &&
gimp_text_tool_set_drawable (text_tool, GIMP_DRAWABLE (layer),
FALSE) &&
GIMP_LAYER (text_tool->layer) == layer)
{

View File

@ -609,7 +609,7 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
vector_tool->vectors = g_object_ref (vectors);
g_signal_connect_object (gimp_item_get_image (item), "active-vectors-changed",
g_signal_connect_object (gimp_item_get_image (item), "selected-vectors-changed",
G_CALLBACK (gimp_vector_tool_vectors_changed),
vector_tool, 0);
g_signal_connect_object (vectors, "removed",

View File

@ -40,6 +40,7 @@ enum
static void gimp_vectors_undo_constructed (GObject *object);
static void gimp_vectors_undo_finalize (GObject *object);
static void gimp_vectors_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -70,6 +71,7 @@ gimp_vectors_undo_class_init (GimpVectorsUndoClass *klass)
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructed = gimp_vectors_undo_constructed;
object_class->finalize = gimp_vectors_undo_finalize;
object_class->set_property = gimp_vectors_undo_set_property;
object_class->get_property = gimp_vectors_undo_get_property;
@ -91,15 +93,15 @@ gimp_vectors_undo_class_init (GimpVectorsUndoClass *klass)
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_VECTORS,
g_param_spec_object ("prev-vectors", NULL, NULL,
GIMP_TYPE_VECTORS,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_param_spec_pointer ("prev-vectors", NULL, NULL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_vectors_undo_init (GimpVectorsUndo *undo)
{
undo->prev_vectors = NULL;
}
static void
@ -110,6 +112,16 @@ gimp_vectors_undo_constructed (GObject *object)
gimp_assert (GIMP_IS_VECTORS (GIMP_ITEM_UNDO (object)->item));
}
static void
gimp_vectors_undo_finalize (GObject *object)
{
GimpVectorsUndo *undo = GIMP_VECTORS_UNDO (object);
g_clear_pointer (&undo->prev_vectors, g_list_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gimp_vectors_undo_set_property (GObject *object,
guint property_id,
@ -127,7 +139,7 @@ gimp_vectors_undo_set_property (GObject *object,
vectors_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_VECTORS:
vectors_undo->prev_vectors = g_value_get_object (value);
vectors_undo->prev_vectors = g_list_copy (g_value_get_pointer (value));
break;
default:
@ -153,7 +165,7 @@ gimp_vectors_undo_get_property (GObject *object,
g_value_set_int (value, vectors_undo->prev_position);
break;
case PROP_PREV_VECTORS:
g_value_set_object (value, vectors_undo->prev_vectors);
g_value_set_pointer (value, vectors_undo->prev_vectors);
break;
default:
@ -206,7 +218,8 @@ gimp_vectors_undo_pop (GimpUndo *undo,
/* restore vectors */
/* record the active vectors */
vectors_undo->prev_vectors = gimp_image_get_active_vectors (undo->image);
g_clear_pointer (&vectors_undo->prev_vectors, g_list_free);
vectors_undo->prev_vectors = g_list_copy (gimp_image_get_selected_vectors (undo->image));
gimp_image_add_vectors (undo->image, vectors,
vectors_undo->prev_parent,

View File

@ -38,8 +38,8 @@ struct _GimpVectorsUndo
GimpItemUndo parent_instance;
GimpVectors *prev_parent;
gint prev_position; /* former position in list */
GimpVectors *prev_vectors; /* previous active vectors */
gint prev_position; /* former position in list */
GList *prev_vectors; /* previous selected vectors */
};
struct _GimpVectorsUndoClass

View File

@ -105,7 +105,7 @@ gimp_channel_tree_view_class_init (GimpChannelTreeViewClass *klass)
iv_class->set_image = gimp_channel_tree_view_set_image;
iv_class->item_type = GIMP_TYPE_CHANNEL;
iv_class->signal_name = "active-channel-changed";
iv_class->signal_name = "selected-channels-changed";
iv_class->get_container = gimp_image_get_channels;
iv_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_channel;

View File

@ -88,7 +88,7 @@ gimp_vectors_tree_view_class_init (GimpVectorsTreeViewClass *klass)
view_class->drop_svg = gimp_vectors_tree_view_drop_svg;
iv_class->item_type = GIMP_TYPE_VECTORS;
iv_class->signal_name = "active-vectors-changed";
iv_class->signal_name = "selected-vectors-changed";
iv_class->get_container = gimp_image_get_vectors;
iv_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_vectors;

View File

@ -387,7 +387,7 @@ HELP
%invoke = (
code => <<'CODE'
{
gimp_image_unset_active_channel (image);
gimp_image_unset_selected_channels (image);
}
CODE
);