mirror of https://github.com/GNOME/gimp.git
Fix undoing a group layer type conversion
* app/core/gimpdrawable.[ch]: add "gboolean push_undo" to GimpDrawable::convert_type(). * app/core/gimpdrawable-convert.[ch]: same here for the gray and rgb conversion functions. * app/core/gimpchannel.c * app/core/gimplayer.c: pass FALSE when called from GimpItem::convert() because it can be called on unattached items only. * app/core/gimpimage-convert.c: pass TRUE. * app/core/core-enums.[ch] * app/core/gimpgrouplayerundo.[ch] * app/core/gimpimage-undo-push.[ch]: add GIMP_UNDO_GROUP_LAYER_CONVERT which simply calls gimp_drawable_convert_type() with the old type when undone/redone. * app/core/gimpgrouplayer.c: push a group layer convert undo so this can be properly undone/redone.
This commit is contained in:
parent
2ac7cedbfc
commit
717b4e6a07
|
@ -841,6 +841,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_LAYER_LOCK_ALPHA, "GIMP_UNDO_LAYER_LOCK_ALPHA", "layer-lock-alpha" },
|
||||
{ GIMP_UNDO_GROUP_LAYER_SUSPEND, "GIMP_UNDO_GROUP_LAYER_SUSPEND", "group-layer-suspend" },
|
||||
{ GIMP_UNDO_GROUP_LAYER_RESUME, "GIMP_UNDO_GROUP_LAYER_RESUME", "group-layer-resume" },
|
||||
{ GIMP_UNDO_GROUP_LAYER_CONVERT, "GIMP_UNDO_GROUP_LAYER_CONVERT", "group-layer-convert" },
|
||||
{ GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
|
||||
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" },
|
||||
{ GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" },
|
||||
|
@ -928,6 +929,7 @@ gimp_undo_type_get_type (void)
|
|||
{ GIMP_UNDO_LAYER_LOCK_ALPHA, NC_("undo-type", "Lock/Unlock alpha channel"), NULL },
|
||||
{ GIMP_UNDO_GROUP_LAYER_SUSPEND, NC_("undo-type", "Suspend group layer resize"), NULL },
|
||||
{ GIMP_UNDO_GROUP_LAYER_RESUME, NC_("undo-type", "Resume group layer resize"), NULL },
|
||||
{ GIMP_UNDO_GROUP_LAYER_CONVERT, NC_("undo-type", "Convert group layer"), NULL },
|
||||
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL },
|
||||
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL },
|
||||
{ GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer mask"), NULL },
|
||||
|
|
|
@ -422,6 +422,7 @@ typedef enum /*< pdb-skip >*/
|
|||
GIMP_UNDO_LAYER_LOCK_ALPHA, /*< desc="Lock/Unlock alpha channel" >*/
|
||||
GIMP_UNDO_GROUP_LAYER_SUSPEND, /*< desc="Suspend group layer resize" >*/
|
||||
GIMP_UNDO_GROUP_LAYER_RESUME, /*< desc="Resume group layer resize" >*/
|
||||
GIMP_UNDO_GROUP_LAYER_CONVERT, /*< desc="Convert group layer" >*/
|
||||
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
|
||||
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/
|
||||
GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer mask" >*/
|
||||
|
|
|
@ -434,7 +434,7 @@ gimp_channel_convert (GimpItem *item,
|
|||
|
||||
if (! gimp_drawable_is_gray (drawable))
|
||||
{
|
||||
gimp_drawable_convert_type (drawable, NULL, GIMP_GRAY);
|
||||
gimp_drawable_convert_type (drawable, NULL, GIMP_GRAY, FALSE);
|
||||
}
|
||||
|
||||
if (gimp_drawable_has_alpha (drawable))
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
|
||||
void
|
||||
gimp_drawable_convert_rgb (GimpDrawable *drawable)
|
||||
gimp_drawable_convert_rgb (GimpDrawable *drawable,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpImageType type;
|
||||
TileManager *tiles;
|
||||
|
@ -52,14 +53,14 @@ gimp_drawable_convert_rgb (GimpDrawable *drawable)
|
|||
|
||||
gimp_drawable_convert_tiles_rgb (drawable, tiles);
|
||||
|
||||
gimp_drawable_set_tiles (drawable,
|
||||
gimp_item_is_attached (GIMP_ITEM (drawable)), NULL,
|
||||
gimp_drawable_set_tiles (drawable, push_undo, NULL,
|
||||
tiles, type);
|
||||
tile_manager_unref (tiles);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_drawable_convert_grayscale (GimpDrawable *drawable)
|
||||
gimp_drawable_convert_grayscale (GimpDrawable *drawable,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpImageType type;
|
||||
TileManager *tiles;
|
||||
|
@ -78,8 +79,7 @@ gimp_drawable_convert_grayscale (GimpDrawable *drawable)
|
|||
|
||||
gimp_drawable_convert_tiles_grayscale (drawable, tiles);
|
||||
|
||||
gimp_drawable_set_tiles (drawable,
|
||||
gimp_item_is_attached (GIMP_ITEM (drawable)), NULL,
|
||||
gimp_drawable_set_tiles (drawable, push_undo, NULL,
|
||||
tiles, type);
|
||||
tile_manager_unref (tiles);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#define __GIMP_DRAWABLE_CONVERT_H__
|
||||
|
||||
|
||||
void gimp_drawable_convert_rgb (GimpDrawable *drawable);
|
||||
void gimp_drawable_convert_grayscale (GimpDrawable *drawable);
|
||||
void gimp_drawable_convert_rgb (GimpDrawable *drawable,
|
||||
gboolean push_undo);
|
||||
void gimp_drawable_convert_grayscale (GimpDrawable *drawable,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_drawable_convert_tiles_rgb (GimpDrawable *drawable,
|
||||
TileManager *new_tiles);
|
||||
|
|
|
@ -128,7 +128,8 @@ static gint64 gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable
|
|||
|
||||
static void gimp_drawable_real_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type);
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo);
|
||||
|
||||
static TileManager * gimp_drawable_real_get_tiles (GimpDrawable *drawable);
|
||||
static void gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
||||
|
@ -728,18 +729,19 @@ gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable,
|
|||
static void
|
||||
gimp_drawable_real_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type)
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo)
|
||||
{
|
||||
g_return_if_fail (new_base_type != GIMP_INDEXED);
|
||||
|
||||
switch (new_base_type)
|
||||
{
|
||||
case GIMP_RGB:
|
||||
gimp_drawable_convert_rgb (drawable);
|
||||
gimp_drawable_convert_rgb (drawable, push_undo);
|
||||
break;
|
||||
|
||||
case GIMP_GRAY:
|
||||
gimp_drawable_convert_grayscale (drawable);
|
||||
gimp_drawable_convert_grayscale (drawable, push_undo);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1230,7 +1232,8 @@ gimp_drawable_get_active_components (const GimpDrawable *drawable,
|
|||
void
|
||||
gimp_drawable_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type)
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpImageType type;
|
||||
|
||||
|
@ -1238,12 +1241,15 @@ gimp_drawable_convert_type (GimpDrawable *drawable,
|
|||
g_return_if_fail (dest_image == NULL || GIMP_IS_IMAGE (dest_image));
|
||||
g_return_if_fail (new_base_type != GIMP_INDEXED || GIMP_IS_IMAGE (dest_image));
|
||||
|
||||
if (! gimp_item_is_attached (GIMP_ITEM (drawable)))
|
||||
push_undo = FALSE;
|
||||
|
||||
type = gimp_drawable_type (drawable);
|
||||
|
||||
g_return_if_fail (new_base_type != GIMP_IMAGE_TYPE_BASE_TYPE (type));
|
||||
|
||||
GIMP_DRAWABLE_GET_CLASS (drawable)->convert_type (drawable, dest_image,
|
||||
new_base_type);
|
||||
new_base_type, push_undo);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -65,7 +65,8 @@ struct _GimpDrawableClass
|
|||
gboolean *active);
|
||||
void (* convert_type) (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type);
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo);
|
||||
void (* apply_region) (GimpDrawable *drawable,
|
||||
PixelRegion *src2PR,
|
||||
gboolean push_undo,
|
||||
|
@ -145,7 +146,8 @@ void gimp_drawable_get_active_components (const GimpDrawable *drawable,
|
|||
|
||||
void gimp_drawable_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type);
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_drawable_apply_region (GimpDrawable *drawable,
|
||||
PixelRegion *src2PR,
|
||||
|
|
|
@ -105,7 +105,8 @@ static gint64 gimp_group_layer_estimate_memsize (const GimpDrawable *drawab
|
|||
gint height);
|
||||
static void gimp_group_layer_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type);
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo);
|
||||
|
||||
static GeglNode * gimp_group_layer_get_graph (GimpProjectable *projectable);
|
||||
static GList * gimp_group_layer_get_layers (GimpProjectable *projectable);
|
||||
|
@ -724,12 +725,20 @@ gimp_group_layer_estimate_memsize (const GimpDrawable *drawable,
|
|||
static void
|
||||
gimp_group_layer_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type)
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (drawable);
|
||||
TileManager *tiles;
|
||||
GimpImageType new_type;
|
||||
|
||||
if (push_undo)
|
||||
{
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (group));
|
||||
|
||||
gimp_image_undo_push_group_layer_convert (image, NULL, group);
|
||||
}
|
||||
|
||||
new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type);
|
||||
|
||||
if (gimp_drawable_has_alpha (drawable))
|
||||
|
|
|
@ -61,37 +61,80 @@ gimp_group_layer_undo_constructor (GType type,
|
|||
guint n_params,
|
||||
GObjectConstructParam *params)
|
||||
{
|
||||
GObject *object;
|
||||
GObject *object;
|
||||
GimpGroupLayerUndo *group_layer_undo;
|
||||
GimpGroupLayer *group;
|
||||
|
||||
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
|
||||
|
||||
group_layer_undo = GIMP_GROUP_LAYER_UNDO (object);
|
||||
|
||||
g_assert (GIMP_IS_GROUP_LAYER (GIMP_ITEM_UNDO (object)->item));
|
||||
|
||||
group = GIMP_GROUP_LAYER (GIMP_ITEM_UNDO (object)->item);
|
||||
|
||||
switch (GIMP_UNDO (object)->undo_type)
|
||||
{
|
||||
case GIMP_UNDO_GROUP_LAYER_SUSPEND:
|
||||
case GIMP_UNDO_GROUP_LAYER_RESUME:
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_GROUP_LAYER_CONVERT:
|
||||
group_layer_undo->prev_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (GIMP_DRAWABLE (group)));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_group_layer_undo_pop (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (GIMP_ITEM_UNDO (undo)->item);
|
||||
GimpGroupLayerUndo *group_layer_undo = GIMP_GROUP_LAYER_UNDO (undo);
|
||||
GimpGroupLayer *group;
|
||||
|
||||
group = GIMP_GROUP_LAYER (GIMP_ITEM_UNDO (undo)->item);
|
||||
|
||||
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
|
||||
|
||||
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
|
||||
undo->undo_type == GIMP_UNDO_GROUP_LAYER_SUSPEND) ||
|
||||
(undo_mode == GIMP_UNDO_MODE_REDO &&
|
||||
undo->undo_type == GIMP_UNDO_GROUP_LAYER_RESUME))
|
||||
switch (undo->undo_type)
|
||||
{
|
||||
/* resume group layer auto-resizing */
|
||||
case GIMP_UNDO_GROUP_LAYER_SUSPEND:
|
||||
case GIMP_UNDO_GROUP_LAYER_RESUME:
|
||||
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
|
||||
undo->undo_type == GIMP_UNDO_GROUP_LAYER_SUSPEND) ||
|
||||
(undo_mode == GIMP_UNDO_MODE_REDO &&
|
||||
undo->undo_type == GIMP_UNDO_GROUP_LAYER_RESUME))
|
||||
{
|
||||
/* resume group layer auto-resizing */
|
||||
|
||||
gimp_group_layer_resume_resize (group, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* suspend group layer auto-resizing */
|
||||
gimp_group_layer_resume_resize (group, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* suspend group layer auto-resizing */
|
||||
|
||||
gimp_group_layer_suspend_resize (group, FALSE);
|
||||
gimp_group_layer_suspend_resize (group, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_GROUP_LAYER_CONVERT:
|
||||
{
|
||||
GimpImageBaseType type;
|
||||
|
||||
type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (GIMP_DRAWABLE (group)));
|
||||
gimp_drawable_convert_type (GIMP_DRAWABLE (group), NULL,
|
||||
group_layer_undo->prev_type, FALSE);
|
||||
group_layer_undo->prev_type = type;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ typedef struct _GimpGroupLayerUndoClass GimpGroupLayerUndoClass;
|
|||
|
||||
struct _GimpGroupLayerUndo
|
||||
{
|
||||
GimpItemUndo parent_instance;
|
||||
GimpItemUndo parent_instance;
|
||||
|
||||
GimpImageBaseType prev_type;
|
||||
};
|
||||
|
||||
struct _GimpGroupLayerUndoClass
|
||||
|
|
|
@ -963,7 +963,8 @@ gimp_image_convert (GimpImage *image,
|
|||
{
|
||||
case GIMP_RGB:
|
||||
case GIMP_GRAY:
|
||||
gimp_drawable_convert_type (GIMP_DRAWABLE (layer), NULL, new_type);
|
||||
gimp_drawable_convert_type (GIMP_DRAWABLE (layer), NULL, new_type,
|
||||
TRUE);
|
||||
break;
|
||||
|
||||
case GIMP_INDEXED:
|
||||
|
|
|
@ -551,6 +551,22 @@ gimp_image_undo_push_group_layer_resume (GimpImage *image,
|
|||
NULL);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_group_layer_convert (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpGroupLayer *group)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_GROUP_LAYER (group), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (group)), NULL);
|
||||
|
||||
return gimp_image_undo_push (image, GIMP_TYPE_GROUP_LAYER_UNDO,
|
||||
GIMP_UNDO_GROUP_LAYER_CONVERT, undo_desc,
|
||||
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
|
||||
"item", group,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**********************/
|
||||
/* Text Layer Undos */
|
||||
|
|
|
@ -136,6 +136,9 @@ GimpUndo * gimp_image_undo_push_group_layer_suspend (GimpImage *image,
|
|||
GimpUndo * gimp_image_undo_push_group_layer_resume (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpGroupLayer *group);
|
||||
GimpUndo * gimp_image_undo_push_group_layer_convert (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpGroupLayer *group);
|
||||
|
||||
|
||||
/* text layer undos */
|
||||
|
|
|
@ -153,7 +153,8 @@ static void gimp_layer_get_active_components (const GimpDrawable *drawable,
|
|||
gboolean *active);
|
||||
static void gimp_layer_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type);
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo);
|
||||
|
||||
static gint gimp_layer_get_opacity_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
|
@ -545,7 +546,7 @@ gimp_layer_convert (GimpItem *item,
|
|||
new_base_type = gimp_image_base_type (dest_image);
|
||||
|
||||
if (old_base_type != new_base_type)
|
||||
gimp_drawable_convert_type (drawable, dest_image, new_base_type);
|
||||
gimp_drawable_convert_type (drawable, dest_image, new_base_type, FALSE);
|
||||
|
||||
if (layer->mask)
|
||||
gimp_item_set_image (GIMP_ITEM (layer->mask), dest_image);
|
||||
|
@ -858,14 +859,16 @@ gimp_layer_get_active_components (const GimpDrawable *drawable,
|
|||
static void
|
||||
gimp_layer_convert_type (GimpDrawable *drawable,
|
||||
GimpImage *dest_image,
|
||||
GimpImageBaseType new_base_type)
|
||||
GimpImageBaseType new_base_type,
|
||||
gboolean push_undo)
|
||||
{
|
||||
switch (new_base_type)
|
||||
{
|
||||
case GIMP_RGB:
|
||||
case GIMP_GRAY:
|
||||
GIMP_DRAWABLE_CLASS (parent_class)->convert_type (drawable, dest_image,
|
||||
new_base_type);
|
||||
new_base_type,
|
||||
push_undo);
|
||||
break;
|
||||
|
||||
case GIMP_INDEXED:
|
||||
|
@ -900,9 +903,7 @@ gimp_layer_convert_type (GimpDrawable *drawable,
|
|||
&layerPR, gimp_drawable_type (drawable),
|
||||
&newPR, new_type);
|
||||
|
||||
gimp_drawable_set_tiles (drawable,
|
||||
gimp_item_is_attached (GIMP_ITEM (drawable)),
|
||||
NULL,
|
||||
gimp_drawable_set_tiles (drawable, push_undo, NULL,
|
||||
new_tiles, new_type);
|
||||
tile_manager_unref (new_tiles);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue