added undo type GIMP_UNDO_TEXT_LAYER_MODIFIED and undo group types

2004-04-01  Michael Natterer  <mitch@gimp.org>

	* app/core/core-enums.[ch] (enum GimpUndoType): added undo type
	GIMP_UNDO_TEXT_LAYER_MODIFIED and undo group types
	GIMP_UNDO_GROUP_DRAWABLE and GIMP_UNDO_GROUP_DRAWABLE_MOD.

	* app/core/gimpimage-undo-push.[ch]: added new new function
	gimp_image_undo_push_text_layer_modified() which makes
	modifications of the text_layer's "modified" boolean undoable.

	* app/core/gimpdrawable.[ch]: added new virtual function
	GimpDrawable::push_undo() and moved the actual undo pushing into
	the default implementation gimp_drawable_real_push_undo().

	* app/text/gimptextlayer.c (gimp_text_layer_push_undo): new
	function. Pushes the text_layer's modified state to the undo stack
	after upchaining and sets modified to TRUE.

	(gimp_text_layer_set_tiles): ditto.

	(gimp_lext_layer_apply_region)
	(gimp_text_layer_replace_region): removed because their default
	implementations already call gimp_drawable_push_undo().

	(gimp_text_layer_swap_pixels): removed because swap_pixels() is
	used by undo only and doesn't need to care about the text_layer's
	modified state.

	(gimp_text_layer_render): don't set modified to FALSE here because
	we can't push an undo step here.

	(gimp_text_layer_set): push the modified state to the undo stack
	and set it to FALSE here. Also push the layer's tiles if the
	layer was modified.

	* app/tools/gimptexttool.c (gimp_text_tool_apply): push "modified"
	to the undo stack and set it to FALSE here, too.

	Fixes bug #137767.
This commit is contained in:
Michael Natterer 2004-04-01 14:51:58 +00:00 committed by Michael Natterer
parent 02caa61288
commit acc72b620e
9 changed files with 267 additions and 117 deletions

View File

@ -1,3 +1,43 @@
2004-04-01 Michael Natterer <mitch@gimp.org>
* app/core/core-enums.[ch] (enum GimpUndoType): added undo type
GIMP_UNDO_TEXT_LAYER_MODIFIED and undo group types
GIMP_UNDO_GROUP_DRAWABLE and GIMP_UNDO_GROUP_DRAWABLE_MOD.
* app/core/gimpimage-undo-push.[ch]: added new new function
gimp_image_undo_push_text_layer_modified() which makes
modifications of the text_layer's "modified" boolean undoable.
* app/core/gimpdrawable.[ch]: added new virtual function
GimpDrawable::push_undo() and moved the actual undo pushing into
the default implementation gimp_drawable_real_push_undo().
* app/text/gimptextlayer.c (gimp_text_layer_push_undo): new
function. Pushes the text_layer's modified state to the undo stack
after upchaining and sets modified to TRUE.
(gimp_text_layer_set_tiles): ditto.
(gimp_lext_layer_apply_region)
(gimp_text_layer_replace_region): removed because their default
implementations already call gimp_drawable_push_undo().
(gimp_text_layer_swap_pixels): removed because swap_pixels() is
used by undo only and doesn't need to care about the text_layer's
modified state.
(gimp_text_layer_render): don't set modified to FALSE here because
we can't push an undo step here.
(gimp_text_layer_set): push the modified state to the undo stack
and set it to FALSE here. Also push the layer's tiles if the
layer was modified.
* app/tools/gimptexttool.c (gimp_text_tool_apply): push "modified"
to the undo stack and set it to FALSE here, too.
Fixes bug #137767.
2004-03-31 Simon Budig <simon@gimp.org>
* app/tools/gimptransformtool.c: One really should use braces

View File

@ -591,6 +591,8 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_GROUP_IMAGE_QMASK, N_("QuickMask"), "group-image-qmask" },
{ GIMP_UNDO_GROUP_IMAGE_GRID, N_("Grid"), "group-image-grid" },
{ GIMP_UNDO_GROUP_IMAGE_GUIDE, N_("Guide"), "group-image-guide" },
{ GIMP_UNDO_GROUP_DRAWABLE, N_("Drawable"), "group-drawable" },
{ GIMP_UNDO_GROUP_DRAWABLE_MOD, N_("Drawable Mod"), "group-drawable-mod" },
{ GIMP_UNDO_GROUP_MASK, N_("Selection Mask"), "group-mask" },
{ GIMP_UNDO_GROUP_ITEM_PROPERTIES, N_("Item Properties"), "group-item-properties" },
{ GIMP_UNDO_GROUP_ITEM_DISPLACE, N_("Move Item"), "group-item-displace" },
@ -635,6 +637,7 @@ static const GEnumValue gimp_undo_type_enum_values[] =
{ GIMP_UNDO_LAYER_OPACITY, N_("Set Layer Opacity"), "layer-opacity" },
{ GIMP_UNDO_LAYER_PRESERVE_TRANS, N_("Set Preserve Trans"), "layer-preserve-trans" },
{ GIMP_UNDO_TEXT_LAYER, N_("Text"), "text-layer" },
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, N_("Text Modified"), "text-layer-modified" },
{ GIMP_UNDO_CHANNEL_ADD, N_("New Channel"), "channel-add" },
{ GIMP_UNDO_CHANNEL_REMOVE, N_("Delete Channel"), "channel-remove" },
{ GIMP_UNDO_CHANNEL_REPOSITION, N_("Reposition Channel"), "channel-reposition" },

View File

@ -421,6 +421,8 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_GROUP_IMAGE_QMASK, /*< desc="QuickMask" >*/
GIMP_UNDO_GROUP_IMAGE_GRID, /*< desc="Grid" >*/
GIMP_UNDO_GROUP_IMAGE_GUIDE, /*< desc="Guide" >*/
GIMP_UNDO_GROUP_DRAWABLE, /*< desc="Drawable" >*/
GIMP_UNDO_GROUP_DRAWABLE_MOD, /*< desc="Drawable Mod" >*/
GIMP_UNDO_GROUP_MASK, /*< desc="Selection Mask" >*/
GIMP_UNDO_GROUP_ITEM_PROPERTIES, /*< desc="Item Properties" >*/
GIMP_UNDO_GROUP_ITEM_DISPLACE, /*< desc="Move Item" >*/
@ -470,6 +472,7 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_LAYER_OPACITY, /*< desc="Set Layer Opacity" >*/
GIMP_UNDO_LAYER_PRESERVE_TRANS, /*< desc="Set Preserve Trans" >*/
GIMP_UNDO_TEXT_LAYER, /*< desc="Text" >*/
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text Modified" >*/
GIMP_UNDO_CHANNEL_ADD, /*< desc="New Channel" >*/
GIMP_UNDO_CHANNEL_REMOVE, /*< desc="Delete Channel" >*/
GIMP_UNDO_CHANNEL_REPOSITION, /*< desc="Reposition Channel" >*/

View File

@ -116,6 +116,14 @@ static void gimp_drawable_real_set_tiles (GimpDrawable *drawable,
gint offset_x,
gint offset_y);
static void gimp_drawable_real_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
TileManager *tiles,
gboolean sparse,
gint x,
gint y,
gint width,
gint height);
static void gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
TileManager *tiles,
gboolean sparse,
@ -218,6 +226,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
klass->apply_region = gimp_drawable_real_apply_region;
klass->replace_region = gimp_drawable_real_replace_region;
klass->set_tiles = gimp_drawable_real_set_tiles;
klass->push_undo = gimp_drawable_real_push_undo;
klass->swap_pixels = gimp_drawable_real_swap_pixels;
klass->scale_desc = NULL;
@ -617,6 +626,41 @@ gimp_drawable_real_set_tiles (GimpDrawable *drawable,
gimp_drawable_alpha_changed (drawable);
}
static void
gimp_drawable_real_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
TileManager *tiles,
gboolean sparse,
gint x,
gint y,
gint width,
gint height)
{
gboolean new_tiles = FALSE;
if (! tiles)
{
PixelRegion srcPR, destPR;
tiles = tile_manager_new (width, height, gimp_drawable_bytes (drawable));
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
x, y, width, height, FALSE);
pixel_region_init (&destPR, tiles,
0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
new_tiles = TRUE;
}
gimp_image_undo_push_drawable (gimp_item_get_image (GIMP_ITEM (drawable)),
undo_desc, drawable,
tiles, sparse,
x, y, width, height);
if (new_tiles)
tile_manager_unref (tiles);
}
static void
gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
TileManager *tiles,
@ -879,8 +923,8 @@ gimp_drawable_push_undo (GimpDrawable *drawable,
gboolean sparse)
{
GimpItem *item;
gint x, y, width, height;
gboolean new_tiles = FALSE;
gint x, y;
gint width, height;
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (sparse == FALSE || tiles != NULL);
@ -908,27 +952,9 @@ gimp_drawable_push_undo (GimpDrawable *drawable,
return;
}
if (! tiles)
{
PixelRegion srcPR, destPR;
tiles = tile_manager_new (width, height, gimp_drawable_bytes (drawable));
pixel_region_init (&srcPR, gimp_drawable_data (drawable),
x, y, width, height, FALSE);
pixel_region_init (&destPR, tiles,
0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
new_tiles = TRUE;
}
gimp_image_undo_push_drawable (gimp_item_get_image (GIMP_ITEM (drawable)),
undo_desc, drawable,
tiles, sparse,
x, y, width, height);
if (new_tiles)
tile_manager_unref (tiles);
GIMP_DRAWABLE_GET_CLASS (drawable)->push_undo (drawable, undo_desc,
tiles, sparse,
x, y, width, height);
}
TileManager *

View File

@ -88,6 +88,15 @@ struct _GimpDrawableClass
GimpImageType type,
gint offset_x,
gint offset_y);
void (* push_undo) (GimpDrawable *drawable,
const gchar *undo_desc,
TileManager *tiles,
gboolean sparse,
gint x,
gint y,
gint width,
gint height);
void (* swap_pixels) (GimpDrawable *drawable,
TileManager *tiles,
gboolean sparse,

View File

@ -49,6 +49,7 @@
#include "gimplist.h"
#include "gimpparasitelist.h"
#include "text/gimptextlayer.h"
#include "text/gimptextundo.h"
#include "vectors/gimpvectors.h"
@ -1752,6 +1753,7 @@ gimp_image_undo_push_text_layer (GimpImage *gimage,
GimpUndo *undo;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), FALSE);
gimp_image_dirty (gimage);
@ -1766,6 +1768,85 @@ gimp_image_undo_push_text_layer (GimpImage *gimage,
}
/******************************/
/* Text Layer Modified Undo */
/******************************/
typedef struct _TextLayerModifiedUndo TextLayerModifiedUndo;
struct _TextLayerModifiedUndo
{
gboolean old_modified;
};
static gboolean undo_pop_text_layer_modified (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_text_layer_modified (GimpUndo *undo,
GimpUndoMode undo_mode);
gboolean
gimp_image_undo_push_text_layer_modified (GimpImage *gimage,
const gchar *undo_desc,
GimpTextLayer *layer)
{
GimpUndo *new;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), FALSE);
if ((new = gimp_image_undo_push_item (gimage, GIMP_ITEM (layer),
sizeof (TextLayerModifiedUndo),
sizeof (TextLayerModifiedUndo),
GIMP_UNDO_TEXT_LAYER_MODIFIED, undo_desc,
TRUE,
undo_pop_text_layer_modified,
undo_free_text_layer_modified)))
{
TextLayerModifiedUndo *modified_undo = new->data;
modified_undo->old_modified = layer->modified;
return TRUE;
}
return FALSE;
}
static gboolean
undo_pop_text_layer_modified (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
TextLayerModifiedUndo *modified_undo = undo->data;
GimpTextLayer *layer;
gboolean modified;
layer = GIMP_TEXT_LAYER (GIMP_ITEM_UNDO (undo)->item);
#if 0
g_print ("setting layer->modified from %s to %s\n",
layer->modified ? "TRUE" : "FALSE",
modified_undo->old_modified ? "TRUE" : "FALSE");
#endif
modified = layer->modified;
g_object_set (layer, "modified", modified_undo->old_modified, NULL);
modified_undo->old_modified = modified;
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
return TRUE;
}
static void
undo_free_text_layer_modified (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
}
/*****************************/
/* Add/Remove Channel Undo */
/*****************************/

View File

@ -110,11 +110,17 @@ gboolean gimp_image_undo_push_layer_preserve_trans (GimpImage *gimage,
const gchar *undo_desc,
GimpLayer *layer);
/* text layer undo */
gboolean gimp_image_undo_push_text_layer (GimpImage *gimage,
const gchar *undo_desc,
GimpTextLayer *layer,
const GParamSpec *pspec);
/* text layer undos */
gboolean gimp_image_undo_push_text_layer (GimpImage *gimage,
const gchar *undo_desc,
GimpTextLayer *layer,
const GParamSpec *pspec);
gboolean gimp_image_undo_push_text_layer_modified (GimpImage *gimage,
const gchar *undo_desc,
GimpTextLayer *layer);
/* channel undos */

View File

@ -84,23 +84,6 @@ static gboolean gimp_text_layer_rename (GimpItem *item,
const gchar *new_name,
const gchar *undo_desc);
static void gimp_text_layer_apply_region (GimpDrawable *drawable,
PixelRegion *src2PR,
gboolean push_undo,
const gchar *undo_desc,
gdouble opacity,
GimpLayerModeEffects mode,
TileManager *src1_tiles,
gint x,
gint y);
static void gimp_text_layer_replace_region (GimpDrawable *drawable,
PixelRegion *src2PR,
gboolean push_undo,
const gchar *undo_desc,
gdouble opacity,
PixelRegion *maskPR,
gint x,
gint y);
static void gimp_text_layer_set_tiles (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
@ -108,7 +91,8 @@ static void gimp_text_layer_set_tiles (GimpDrawable *drawable,
GimpImageType type,
gint offset_x,
gint offset_y);
static void gimp_text_layer_swap_pixels (GimpDrawable *drawable,
static void gimp_text_layer_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
TileManager *tiles,
gboolean sparse,
gint x,
@ -183,10 +167,8 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass)
item_class->transform = gimp_text_layer_transform;
#endif
drawable_class->apply_region = gimp_text_layer_apply_region;
drawable_class->replace_region = gimp_text_layer_replace_region;
drawable_class->set_tiles = gimp_text_layer_set_tiles;
drawable_class->swap_pixels = gimp_text_layer_swap_pixels;
drawable_class->push_undo = gimp_text_layer_push_undo;
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_AUTO_RENAME,
"auto-rename", NULL,
@ -334,41 +316,6 @@ gimp_text_layer_rename (GimpItem *item,
return FALSE;
}
static void
gimp_text_layer_apply_region (GimpDrawable *drawable,
PixelRegion *src2PR,
gboolean push_undo,
const gchar *undo_desc,
gdouble opacity,
GimpLayerModeEffects mode,
TileManager *src1_tiles,
gint x,
gint y)
{
GIMP_DRAWABLE_CLASS (parent_class)->apply_region (drawable, src2PR,
push_undo, undo_desc,
opacity, mode,
src1_tiles, x, y);
g_object_set (drawable, "modified", TRUE, NULL);
}
static void
gimp_text_layer_replace_region (GimpDrawable *drawable,
PixelRegion *src2PR,
gboolean push_undo,
const gchar *undo_desc,
gdouble opacity,
PixelRegion *maskPR,
gint x,
gint y)
{
GIMP_DRAWABLE_CLASS (parent_class)->replace_region (drawable, src2PR,
push_undo, undo_desc,
opacity,
maskPR, x, y);
g_object_set (drawable, "modified", TRUE, NULL);
}
static void
gimp_text_layer_set_tiles (GimpDrawable *drawable,
gboolean push_undo,
@ -378,25 +325,56 @@ gimp_text_layer_set_tiles (GimpDrawable *drawable,
gint offset_x,
gint offset_y)
{
GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
GimpImage *gimage = gimp_item_get_image (GIMP_ITEM (layer));
if (push_undo && ! layer->modified)
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_DRAWABLE_MOD,
undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->set_tiles (drawable,
push_undo, undo_desc,
tiles, type,
offset_x, offset_y);
g_object_set (drawable, "modified", TRUE, NULL);
if (push_undo && ! layer->modified)
{
gimp_image_undo_push_text_layer_modified (gimage, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_image_undo_group_end (gimage);
}
}
static void
gimp_text_layer_swap_pixels (GimpDrawable *drawable,
TileManager *tiles,
gboolean sparse,
gint x,
gint y,
gint width,
gint height)
gimp_text_layer_push_undo (GimpDrawable *drawable,
const gchar *undo_desc,
TileManager *tiles,
gboolean sparse,
gint x,
gint y,
gint width,
gint height)
{
GIMP_DRAWABLE_CLASS (parent_class)->swap_pixels (drawable, tiles, sparse,
x, y, width, height);
g_object_set (drawable, "modified", TRUE, NULL);
GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
GimpImage *gimage = gimp_item_get_image (GIMP_ITEM (layer));
if (! layer->modified)
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);
GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
tiles, sparse,
x, y, width, height);
if (! layer->modified)
{
gimp_image_undo_push_text_layer_modified (gimage, NULL, layer);
g_object_set (drawable, "modified", TRUE, NULL);
gimp_image_undo_group_end (gimage);
}
}
@ -488,7 +466,6 @@ gimp_text_layer_set (GimpTextLayer *layer,
{
GimpImage *image;
GimpText *text;
gboolean undo_group;
va_list var_args;
g_return_if_fail (gimp_drawable_is_text_layer ((GimpDrawable *) layer));
@ -499,12 +476,15 @@ gimp_text_layer_set (GimpTextLayer *layer,
image = gimp_item_get_image (GIMP_ITEM (layer));
/* If the layer contains a mask,
* gimp_text_layer_render() might have to resize it.
*/
undo_group = ((GIMP_LAYER (layer)->mask != NULL) || layer->modified);
if (undo_group)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc);
g_object_freeze_notify (G_OBJECT (layer));
if (layer->modified)
{
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer));
}
gimp_image_undo_push_text_layer (image, undo_desc, layer, NULL);
@ -514,8 +494,11 @@ gimp_text_layer_set (GimpTextLayer *layer,
va_end (var_args);
if (undo_group)
gimp_image_undo_group_end (image);
g_object_set (layer, "modified", FALSE, NULL);
g_object_thaw_notify (G_OBJECT (layer));
gimp_image_undo_group_end (image);
}
/**
@ -617,8 +600,6 @@ gimp_text_layer_render (GimpTextLayer *layer)
gimp_text_layer_render_layout (layer, layout);
g_object_unref (layout);
g_object_set (drawable, "modified", FALSE, NULL);
g_object_thaw_notify (G_OBJECT (drawable));
return (width > 0 && height > 0);

View File

@ -513,8 +513,7 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
GObject *src;
GObject *dest;
GList *list;
gboolean push_undo = TRUE;
gboolean undo_group = FALSE;
gboolean push_undo = TRUE;
if (text_tool->idle_id)
{
@ -575,15 +574,13 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
if (push_undo)
{
/* If the layer contains a mask,
* gimp_text_layer_render() might have to resize it.
*/
undo_group = ((GIMP_LAYER (layer)->mask != NULL) || layer->modified);
if (undo_group)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, NULL);
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, NULL);
if (layer->modified)
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer));
{
gimp_image_undo_push_text_layer_modified (image, NULL, layer);
gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer));
}
gimp_image_undo_push_text_layer (image, NULL, layer, pspec);
}
@ -622,8 +619,12 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
g_signal_handlers_unblock_by_func (dest,
gimp_text_tool_text_notify, text_tool);
if (push_undo && undo_group)
gimp_image_undo_group_end (image);
if (push_undo)
{
g_object_set (layer, "modified", FALSE, NULL);
gimp_image_undo_group_end (image);
}
gimp_image_flush (image);
}