Commit 4b582b48 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer
Browse files

Replaced the concept of having a boolean indicating if an undo step

2004-07-29  Michael Natterer  <mitch@gimp.org>

	Replaced the concept of having a boolean indicating if an undo
	step dirties the image by a bitfield indicating which parts
	of the image are dirtied:

	* app/core/core-enums.[ch]: reordered two values in enum
	GimpUndoType, added GIMP_DIRTY_IMAGE_SIZE to enum GimpDirtyMask.

	The values of GimpDirtyMask are still questionable and will
	probably change...

	* app/core/gimpimage.[ch]: removed signal "undo_start" and added
	a GimpDirtyMask parameter to the "dirty" and "clean" signals.

	* app/core/gimpimage-undo.[ch] (gimp_image_undo_push): replaced
	"gboolean dirties_image" by "GimpDirtyMask dirty_mask" and pass
	it to gimp_image_dirty().

	(gimp_image_undo_group_start): added *ugly* code which tries to
	figure GimpDirtyMask from the group's GimpUndoType and store it in
	the GimpUndoGroup. Call gimp_image_dirty() instead of the removed
	gimp_image_undo_start(). This means the undo group now dirties the
	image just like one of its undo steps, but that's no problem since
	undoing cleans it in the same way.

	* app/core/gimpundo.[ch]: s/dirties_image/dirty_mask/g

	(gimp_undo_pop): emit clean/dirty signals *before* performing the
	actual undo step so listeners can detach from the image before it
	is changed by undo.

	* app/core/gimpimage-undo-push.c (gimp_image_undo_push_*): pass a
	GimpDirtyMask instead of TRUE/FALSE to gimp_image_undo_push().

	* app/core/gimpimagemap.[ch]: removed "gboolean interactive"
	because it makes no sense to use GimpImageMap noninteractively.
	Don't freeze()/thaw() undo while the image_map is active which
	fixes many ways of trashing the image's undo state but probably
	introduces new ways of doing evil things.

	* app/display/gimpdisplay-foreach.c
	* app/display/gimpdisplayshell-handlers.c: changed according
	to the GimpImage::clean()/dirty() signal changes. Small fixes
	in the quit dialog's dirty image container.

	* app/tools/gimptoolcontrol.[ch]: added member and API to
	set/get the dirty_mask.

	* app/tools/gimpcroptool.c
	* app/tools/gimpimagemaptool.c
	* app/tools/gimpiscissorstool.c
	* app/tools/gimptexttool.c
	* app/tools/gimptransformtool.c: whenever setting "preserve" to
	FALSE, also set a "dirty_mask" which specifies on which image
	changes the tool wants to be canceled.

	* app/tools/tool_manager.c: removed "undo_start" connection and
	connect to both "dirty" *and* "clean" to check if the active_tool
	needs to be canceled. Cancel the tool only if the dirty_mask
	passed in the signal has common bits with the tool's dirty_mask.

	Fixes bug #109561 and probably opens some new ones...
parent 91d19f1d
2004-07-29 Michael Natterer <mitch@gimp.org>
Replaced the concept of having a boolean indicating if an undo
step dirties the image by a bitfield indicating which parts
of the image are dirtied:
* app/core/core-enums.[ch]: reordered two values in enum
GimpUndoType, added GIMP_DIRTY_IMAGE_SIZE to enum GimpDirtyMask.
The values of GimpDirtyMask are still questionable and will
probably change...
* app/core/gimpimage.[ch]: removed signal "undo_start" and added
a GimpDirtyMask parameter to the "dirty" and "clean" signals.
* app/core/gimpimage-undo.[ch] (gimp_image_undo_push): replaced
"gboolean dirties_image" by "GimpDirtyMask dirty_mask" and pass
it to gimp_image_dirty().
(gimp_image_undo_group_start): added *ugly* code which tries to
figure GimpDirtyMask from the group's GimpUndoType and store it in
the GimpUndoGroup. Call gimp_image_dirty() instead of the removed
gimp_image_undo_start(). This means the undo group now dirties the
image just like one of its undo steps, but that's no problem since
undoing cleans it in the same way.
* app/core/gimpundo.[ch]: s/dirties_image/dirty_mask/g
(gimp_undo_pop): emit clean/dirty signals *before* performing the
actual undo step so listeners can detach from the image before it
is changed by undo.
* app/core/gimpimage-undo-push.c (gimp_image_undo_push_*): pass a
GimpDirtyMask instead of TRUE/FALSE to gimp_image_undo_push().
* app/core/gimpimagemap.[ch]: removed "gboolean interactive"
because it makes no sense to use GimpImageMap noninteractively.
Don't freeze()/thaw() undo while the image_map is active which
fixes many ways of trashing the image's undo state but probably
introduces new ways of doing evil things.
* app/display/gimpdisplay-foreach.c
* app/display/gimpdisplayshell-handlers.c: changed according
to the GimpImage::clean()/dirty() signal changes. Small fixes
in the quit dialog's dirty image container.
* app/tools/gimptoolcontrol.[ch]: added member and API to
set/get the dirty_mask.
* app/tools/gimpcroptool.c
* app/tools/gimpimagemaptool.c
* app/tools/gimpiscissorstool.c
* app/tools/gimptexttool.c
* app/tools/gimptransformtool.c: whenever setting "preserve" to
FALSE, also set a "dirty_mask" which specifies on which image
changes the tool wants to be canceled.
* app/tools/tool_manager.c: removed "undo_start" connection and
connect to both "dirty" *and* "clean" to check if the active_tool
needs to be canceled. Cancel the tool only if the dirty_mask
passed in the signal has common bits with the tool's dirty_mask.
Fixes bug #109561 and probably opens some new ones...
2004-07-29 Michael Schumacher <schumaml@cvs.gnome.org>
* libgimp/gimp.def
......
......@@ -538,8 +538,8 @@ gimp_undo_type_get_type (void)
{ GIMP_UNDO_GROUP_IMAGE_RESIZE, N_("Resize image"), "group-image-resize" },
{ GIMP_UNDO_GROUP_IMAGE_FLIP, N_("Flip image"), "group-image-flip" },
{ GIMP_UNDO_GROUP_IMAGE_ROTATE, N_("Rotate image"), "group-image-rotate" },
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, N_("Convert image"), "group-image-convert" },
{ GIMP_UNDO_GROUP_IMAGE_CROP, N_("Crop image"), "group-image-crop" },
{ GIMP_UNDO_GROUP_IMAGE_CONVERT, N_("Convert image"), "group-image-convert" },
{ GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, N_("Merge layers"), "group-image-layers-merge" },
{ GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE, N_("Merge vectors"), "group-image-vectors-merge" },
{ GIMP_UNDO_GROUP_IMAGE_QMASK, N_("QuickMask"), "group-image-qmask" },
......@@ -626,6 +626,7 @@ gimp_dirty_mask_get_type (void)
{
{ GIMP_DIRTY_NONE, "GIMP_DIRTY_NONE", "none" },
{ GIMP_DIRTY_IMAGE, "GIMP_DIRTY_IMAGE", "image" },
{ GIMP_DIRTY_IMAGE_SIZE, "GIMP_DIRTY_IMAGE_SIZE", "image-size" },
{ GIMP_DIRTY_IMAGE_META, "GIMP_DIRTY_IMAGE_META", "image-meta" },
{ GIMP_DIRTY_IMAGE_STRUCTURE, "GIMP_DIRTY_IMAGE_STRUCTURE", "image-structure" },
{ GIMP_DIRTY_ITEM, "GIMP_DIRTY_ITEM", "item" },
......
......@@ -400,8 +400,8 @@ typedef enum /*< pdb-skip >*/
GIMP_UNDO_GROUP_IMAGE_RESIZE, /*< desc="Resize image" >*/
GIMP_UNDO_GROUP_IMAGE_FLIP, /*< desc="Flip image" >*/
GIMP_UNDO_GROUP_IMAGE_ROTATE, /*< desc="Rotate image" >*/
GIMP_UNDO_GROUP_IMAGE_CONVERT, /*< desc="Convert image" >*/
GIMP_UNDO_GROUP_IMAGE_CROP, /*< desc="Crop image" >*/
GIMP_UNDO_GROUP_IMAGE_CONVERT, /*< desc="Convert image" >*/
GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, /*< desc="Merge layers" >*/
GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE,/*< desc="Merge vectors" >*/
GIMP_UNDO_GROUP_IMAGE_QMASK, /*< desc="QuickMask" >*/
......@@ -488,15 +488,16 @@ typedef enum /*< pdb-skip >*/
GIMP_DIRTY_NONE = 0,
GIMP_DIRTY_IMAGE = 1 << 0,
GIMP_DIRTY_IMAGE_META = 1 << 1,
GIMP_DIRTY_IMAGE_STRUCTURE = 1 << 2,
GIMP_DIRTY_ITEM = 1 << 3,
GIMP_DIRTY_ITEM_META = 1 << 4,
GIMP_DIRTY_DRAWABLE = 1 << 5,
GIMP_DIRTY_VECTORS = 1 << 6,
GIMP_DIRTY_SELECTION = 1 << 7,
GIMP_DIRTY_ALL = 0xff
GIMP_DIRTY_IMAGE_SIZE = 1 << 1,
GIMP_DIRTY_IMAGE_META = 1 << 2,
GIMP_DIRTY_IMAGE_STRUCTURE = 1 << 3,
GIMP_DIRTY_ITEM = 1 << 4,
GIMP_DIRTY_ITEM_META = 1 << 5,
GIMP_DIRTY_DRAWABLE = 1 << 6,
GIMP_DIRTY_VECTORS = 1 << 7,
GIMP_DIRTY_SELECTION = 1 << 8,
GIMP_DIRTY_ALL = 0xffff
} GimpDirtyMask;
......
......@@ -48,6 +48,7 @@
#include "gimplayermask.h"
#include "gimplist.h"
#include "gimpparasitelist.h"
#include "gimpselection.h"
#include "text/gimptextlayer.h"
#include "text/gimptextundo.h"
......@@ -86,7 +87,7 @@ gimp_image_undo_push_image_type (GimpImage *gimage,
sizeof (ImageTypeUndo),
sizeof (ImageTypeUndo),
GIMP_UNDO_IMAGE_TYPE, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE,
undo_pop_image_type,
undo_free_image_type,
NULL)))
......@@ -159,7 +160,7 @@ gimp_image_undo_push_image_size (GimpImage *gimage,
sizeof (ImageSizeUndo),
sizeof (ImageSizeUndo),
GIMP_UNDO_IMAGE_SIZE, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE | GIMP_DIRTY_IMAGE_SIZE,
undo_pop_image_size,
undo_free_image_size,
NULL)))
......@@ -243,7 +244,7 @@ gimp_image_undo_push_image_resolution (GimpImage *gimage,
sizeof (ResolutionUndo),
sizeof (ResolutionUndo),
GIMP_UNDO_IMAGE_RESOLUTION, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE,
undo_pop_image_resolution,
undo_free_image_resolution,
NULL)))
......@@ -338,7 +339,7 @@ gimp_image_undo_push_image_grid (GimpImage *gimage,
sizeof (GridUndo),
sizeof (GridUndo),
GIMP_UNDO_IMAGE_GRID, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_META,
undo_pop_image_grid,
undo_free_image_grid,
NULL)))
......@@ -417,7 +418,7 @@ gimp_image_undo_push_image_guide (GimpImage *gimage,
sizeof (GuideUndo),
sizeof (GuideUndo),
GIMP_UNDO_IMAGE_GUIDE, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_META,
undo_pop_image_guide,
undo_free_image_guide,
NULL)))
......@@ -513,7 +514,7 @@ gimp_image_undo_push_image_colormap (GimpImage *gimage,
sizeof (ColormapUndo),
sizeof (ColormapUndo),
GIMP_UNDO_IMAGE_COLORMAP, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE,
undo_pop_image_colormap,
undo_free_image_colormap,
NULL)))
......@@ -623,7 +624,7 @@ gimp_image_undo_push_drawable (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (DrawableUndo),
GIMP_UNDO_DRAWABLE, undo_desc,
TRUE,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
undo_pop_drawable,
undo_free_drawable,
"item", item,
......@@ -713,7 +714,7 @@ gimp_image_undo_push_drawable_mod (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (DrawableModUndo),
GIMP_UNDO_DRAWABLE_MOD, undo_desc,
TRUE,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
undo_pop_drawable_mod,
undo_free_drawable_mod,
"item", drawable,
......@@ -829,7 +830,9 @@ gimp_image_undo_push_mask (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (MaskUndo),
GIMP_UNDO_MASK, undo_desc,
FALSE,
GIMP_IS_SELECTION (mask) ?
GIMP_DIRTY_SELECTION :
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
undo_pop_mask,
undo_free_mask,
"item", mask,
......@@ -991,7 +994,7 @@ gimp_image_undo_push_item_rename (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (ItemRenameUndo),
GIMP_UNDO_ITEM_RENAME, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_item_rename,
undo_free_item_rename,
"item", item,
......@@ -1071,7 +1074,9 @@ gimp_image_undo_push_item_displace (GimpImage *gimage,
sizeof (ItemDisplaceUndo),
sizeof (ItemDisplaceUndo),
GIMP_UNDO_ITEM_DISPLACE, undo_desc,
TRUE,
GIMP_IS_DRAWABLE (item) ?
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE :
GIMP_DIRTY_ITEM | GIMP_DIRTY_VECTORS,
undo_pop_item_displace,
undo_free_item_displace,
"item", item,
......@@ -1149,7 +1154,7 @@ gimp_image_undo_push_item_visibility (GimpImage *gimage,
sizeof (ItemVisibilityUndo),
sizeof (ItemVisibilityUndo),
GIMP_UNDO_ITEM_VISIBILITY, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_item_visibility,
undo_free_item_visibility,
"item", item,
......@@ -1220,7 +1225,7 @@ gimp_image_undo_push_item_linked (GimpImage *gimage,
sizeof (ItemLinkedUndo),
sizeof (ItemLinkedUndo),
GIMP_UNDO_ITEM_LINKED, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_item_linked,
undo_free_item_linked,
"item", item,
......@@ -1332,7 +1337,7 @@ undo_push_layer (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (LayerUndo),
type, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_layer,
undo_free_layer,
"item", layer,
......@@ -1510,7 +1515,7 @@ undo_push_layer_mask (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (LayerMaskUndo),
type, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_layer_mask,
undo_free_layer_mask,
"item", layer,
......@@ -1601,7 +1606,7 @@ gimp_image_undo_push_layer_reposition (GimpImage *gimage,
sizeof (LayerRepositionUndo),
sizeof (LayerRepositionUndo),
GIMP_UNDO_LAYER_REPOSITION, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_layer_reposition,
undo_free_layer_reposition,
"item", layer,
......@@ -1708,7 +1713,7 @@ undo_push_layer_properties (GimpImage *gimage,
sizeof (LayerPropertiesUndo),
sizeof (LayerPropertiesUndo),
undo_type, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_layer_properties,
undo_free_layer_properties,
"item", layer,
......@@ -1788,7 +1793,7 @@ gimp_image_undo_push_text_layer (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_TEXT_UNDO,
0, 0,
GIMP_UNDO_TEXT_LAYER, undo_desc,
TRUE,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
NULL,
NULL,
"item", layer,
......@@ -1833,7 +1838,7 @@ gimp_image_undo_push_text_layer_modified (GimpImage *gimage,
sizeof (TextLayerModifiedUndo),
sizeof (TextLayerModifiedUndo),
GIMP_UNDO_TEXT_LAYER_MODIFIED, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_text_layer_modified,
undo_free_text_layer_modified,
"item", layer,
......@@ -1955,7 +1960,7 @@ undo_push_channel (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (ChannelUndo),
type, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_channel,
undo_free_channel,
"item", channel,
......@@ -2062,7 +2067,7 @@ gimp_image_undo_push_channel_reposition (GimpImage *gimage,
sizeof (ChannelRepositionUndo),
sizeof (ChannelRepositionUndo),
GIMP_UNDO_CHANNEL_REPOSITION, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_channel_reposition,
undo_free_channel_reposition,
"item", channel,
......@@ -2134,7 +2139,7 @@ gimp_image_undo_push_channel_color (GimpImage *gimage,
sizeof (ChannelColorUndo),
sizeof (ChannelColorUndo),
GIMP_UNDO_CHANNEL_COLOR, undo_desc,
TRUE,
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
undo_pop_channel_color,
undo_free_channel_color,
"item", channel,
......@@ -2246,7 +2251,7 @@ undo_push_vectors (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (VectorsUndo),
type, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_vectors,
undo_free_vectors,
"item", vectors,
......@@ -2356,7 +2361,7 @@ gimp_image_undo_push_vectors_mod (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
size, sizeof (VectorsModUndo),
GIMP_UNDO_VECTORS_MOD, undo_desc,
TRUE,
GIMP_DIRTY_ITEM | GIMP_DIRTY_VECTORS,
undo_pop_vectors_mod,
undo_free_vectors_mod,
"item", vectors,
......@@ -2453,7 +2458,7 @@ gimp_image_undo_push_vectors_reposition (GimpImage *gimage,
sizeof (VectorsRepositionUndo),
sizeof (VectorsRepositionUndo),
GIMP_UNDO_VECTORS_REPOSITION, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_vectors_reposition,
undo_free_vectors_reposition,
"item", vectors,
......@@ -2529,7 +2534,7 @@ gimp_image_undo_push_fs_to_layer (GimpImage *gimage,
sizeof (FStoLayerUndo),
sizeof (FStoLayerUndo),
GIMP_UNDO_FS_TO_LAYER, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_fs_to_layer,
undo_free_fs_to_layer,
NULL)))
......@@ -2645,7 +2650,7 @@ gimp_image_undo_push_fs_rigor (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
0, 0,
GIMP_UNDO_FS_RIGOR, undo_desc,
FALSE,
GIMP_DIRTY_NONE,
undo_pop_fs_rigor,
NULL,
"item", floating_layer,
......@@ -2705,7 +2710,7 @@ gimp_image_undo_push_fs_relax (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_ITEM_UNDO,
0, 0,
GIMP_UNDO_FS_RELAX, undo_desc,
FALSE,
GIMP_DIRTY_NONE,
undo_pop_fs_relax,
NULL,
"item", floating_layer,
......@@ -2777,7 +2782,7 @@ gimp_image_undo_push_image_parasite (GimpImage *gimage,
sizeof (ParasiteUndo),
sizeof (ParasiteUndo),
GIMP_UNDO_PARASITE_ATTACH, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_META,
undo_pop_parasite,
undo_free_parasite,
NULL)))
......@@ -2809,7 +2814,7 @@ gimp_image_undo_push_image_parasite_remove (GimpImage *gimage,
sizeof (ParasiteUndo),
sizeof (ParasiteUndo),
GIMP_UNDO_PARASITE_REMOVE, undo_desc,
TRUE,
GIMP_DIRTY_IMAGE_META,
undo_pop_parasite,
undo_free_parasite,
NULL)))
......@@ -2842,7 +2847,7 @@ gimp_image_undo_push_item_parasite (GimpImage *gimage,
sizeof (ParasiteUndo),
sizeof (ParasiteUndo),
GIMP_UNDO_PARASITE_ATTACH, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_parasite,
undo_free_parasite,
NULL)))
......@@ -2874,7 +2879,7 @@ gimp_image_undo_push_item_parasite_remove (GimpImage *gimage,
sizeof (ParasiteUndo),
sizeof (ParasiteUndo),
GIMP_UNDO_PARASITE_REMOVE, undo_desc,
TRUE,
GIMP_DIRTY_ITEM_META,
undo_pop_parasite,
undo_free_parasite,
NULL)))
......@@ -2975,7 +2980,7 @@ gimp_image_undo_push_cantundo (GimpImage *gimage,
if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_UNDO,
0, 0,
GIMP_UNDO_CANT, undo_desc,
TRUE,
GIMP_DIRTY_ALL,
undo_pop_cantundo,
NULL,
NULL)))
......
......@@ -36,12 +36,14 @@
/* local function prototypes */
static void gimp_image_undo_pop_stack (GimpImage *gimage,
GimpUndoStack *undo_stack,
GimpUndoStack *redo_stack,
GimpUndoMode undo_mode);
static void gimp_image_undo_free_space (GimpImage *gimage);
static void gimp_image_undo_free_redo (GimpImage *gimage);
static void gimp_image_undo_pop_stack (GimpImage *gimage,
GimpUndoStack *undo_stack,
GimpUndoStack *redo_stack,
GimpUndoMode undo_mode);
static void gimp_image_undo_free_space (GimpImage *gimage);
static void gimp_image_undo_free_redo (GimpImage *gimage);
static GimpDirtyMask gimp_image_undo_dirty_from_type (GimpUndoType type);
/* public functions */
......@@ -110,6 +112,7 @@ gimp_image_undo_group_start (GimpImage *gimage,
const gchar *name)
{
GimpUndoStack *undo_group;
GimpDirtyMask dirty_mask;
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
g_return_val_if_fail (type > GIMP_UNDO_GROUP_FIRST &&
......@@ -118,8 +121,11 @@ gimp_image_undo_group_start (GimpImage *gimage,
if (! name)
name = gimp_undo_type_to_name (type);
dirty_mask = gimp_image_undo_dirty_from_type (type);
/* Notify listeners that the image will be modified */
gimp_image_undo_start (gimage);
if (gimage->group_count == 0 && dirty_mask != GIMP_DIRTY_NONE)
gimp_image_dirty (gimage, dirty_mask);
if (gimage->undo_freeze_count > 0)
return FALSE;
......@@ -145,7 +151,8 @@ gimp_image_undo_group_start (GimpImage *gimage,
undo_group = gimp_undo_stack_new (gimage);
gimp_object_set_name (GIMP_OBJECT (undo_group), name);
GIMP_UNDO (undo_group)->undo_type = type;
GIMP_UNDO (undo_group)->undo_type = type;
GIMP_UNDO (undo_group)->dirty_mask = dirty_mask;
gimp_undo_stack_push_undo (gimage->undo_stack, GIMP_UNDO (undo_group));
......@@ -189,7 +196,7 @@ gimp_image_undo_push (GimpImage *gimage,
gsize struct_size,
GimpUndoType type,
const gchar *name,
gboolean dirties_image,
GimpDirtyMask dirty_mask,
GimpUndoPopFunc pop_func,
GimpUndoFreeFunc free_func,
...)
......@@ -207,8 +214,8 @@ gimp_image_undo_push (GimpImage *gimage,
/* Does this undo dirty the image? If so, we always want to mark
* image dirty, even if we can't actually push the undo.
*/
if (dirties_image)
gimp_image_dirty (gimage);
if (dirty_mask != GIMP_DIRTY_NONE)
gimp_image_dirty (gimage, dirty_mask);
if (gimage->undo_freeze_count > 0)
return NULL;
......@@ -220,14 +227,14 @@ gimp_image_undo_push (GimpImage *gimage,
undo_struct = g_malloc0 (struct_size);
params = gimp_parameters_append (undo_gtype, params, &n_params,
"name", name,
"image", gimage,
"undo-type", type,
"dirties-image", dirties_image,
"data", undo_struct,
"size", size,
"pop-func", pop_func,
"free-func", free_func,
"name", name,
"image", gimage,
"undo-type", type,
"dirty-mask", dirty_mask,
"data", undo_struct,
"size", size,
"pop-func", pop_func,
"free-func", free_func,
NULL);
va_start (args, free_func);
......@@ -403,3 +410,92 @@ gimp_image_undo_free_redo (GimpImage *gimage)
g_object_unref (freed);
}
}
static GimpDirtyMask
gimp_image_undo_dirty_from_type (GimpUndoType type)
{
switch (type)
{
case GIMP_UNDO_GROUP_IMAGE_SCALE:
case GIMP_UNDO_GROUP_IMAGE_RESIZE:
case GIMP_UNDO_GROUP_IMAGE_FLIP:
case GIMP_UNDO_GROUP_IMAGE_ROTATE:
case GIMP_UNDO_GROUP_IMAGE_CROP:
return GIMP_DIRTY_IMAGE | GIMP_DIRTY_IMAGE_SIZE;
case GIMP_UNDO_GROUP_IMAGE_CONVERT:
return GIMP_DIRTY_IMAGE | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE:
return GIMP_DIRTY_IMAGE_STRUCTURE | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_IMAGE_VECTORS_MERGE:
return GIMP_DIRTY_IMAGE_STRUCTURE | GIMP_DIRTY_VECTORS;
case GIMP_UNDO_GROUP_IMAGE_QMASK: /* FIXME */
return GIMP_DIRTY_IMAGE_STRUCTURE | GIMP_DIRTY_SELECTION;
case GIMP_UNDO_GROUP_IMAGE_GRID:
case GIMP_UNDO_GROUP_IMAGE_GUIDE:
return GIMP_DIRTY_IMAGE_META;
case GIMP_UNDO_GROUP_DRAWABLE:
case GIMP_UNDO_GROUP_DRAWABLE_MOD:
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_MASK: /* FIXME */
return GIMP_DIRTY_SELECTION;
case GIMP_UNDO_GROUP_ITEM_VISIBILITY:
case GIMP_UNDO_GROUP_ITEM_LINKED:
case GIMP_UNDO_GROUP_ITEM_PROPERTIES:
return GIMP_DIRTY_ITEM_META;
case GIMP_UNDO_GROUP_ITEM_DISPLACE: /* FIXME */
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE | GIMP_DIRTY_VECTORS;
case GIMP_UNDO_GROUP_ITEM_SCALE: /* FIXME */
case GIMP_UNDO_GROUP_ITEM_RESIZE: /* FIXME */
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE | GIMP_DIRTY_VECTORS;
case GIMP_UNDO_GROUP_LAYER_ADD_MASK:
case GIMP_UNDO_GROUP_LAYER_APPLY_MASK:
return GIMP_DIRTY_IMAGE_STRUCTURE;
case GIMP_UNDO_GROUP_FS_TO_LAYER:
case GIMP_UNDO_GROUP_FS_FLOAT:
case GIMP_UNDO_GROUP_FS_ANCHOR:
case GIMP_UNDO_GROUP_FS_REMOVE:
return GIMP_DIRTY_IMAGE_STRUCTURE;
case GIMP_UNDO_GROUP_EDIT_PASTE:
return GIMP_DIRTY_IMAGE_STRUCTURE;
case GIMP_UNDO_GROUP_EDIT_CUT:
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_TEXT:
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_TRANSFORM: /* FIXME */
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE | GIMP_DIRTY_VECTORS;
case GIMP_UNDO_GROUP_PAINT:
return GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE;
case GIMP_UNDO_GROUP_PARASITE_ATTACH:
case GIMP_UNDO_GROUP_PARASITE_REMOVE:
return GIMP_DIRTY_IMAGE_META | GIMP_DIRTY_ITEM_META;
case GIMP_UNDO_GROUP_VECTORS_IMPORT:
return GIMP_DIRTY_IMAGE_STRUCTURE | GIMP_DIRTY_VECTORS;
case GIMP_UNDO_GROUP_MISC:
return GIMP_DIRTY_ALL;
default:
break;
}
return GIMP_DIRTY_ALL;
}
......@@ -36,7 +36,7 @@ GimpUndo * gimp_image_undo_push (GimpImage *gimage,
gsize struct_size,
GimpUndoType type,
const gchar *name,
gboolean dirties_image,
GimpDirtyMask dirty_mask,
GimpUndoPopFunc pop_func,
GimpUndoFreeFunc free_func,
...);
......
......@@ -93,7 +93,6 @@ enum
UPDATE,
UPDATE_GUIDE,
COLORMAP_CHANGED,
UNDO_START,
UNDO_EVENT,
FLUSH,
LAST_SIGNAL
......@@ -362,8 +361,9 @@ gimp_image_class_init (GimpImageClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpImageClass, clean),
NULL, NULL,