Commit 0a7dca91 authored by EDT 1999  Austin Donnelly's avatar EDT 1999 Austin Donnelly Committed by Austin Donnelly
Browse files

Dirty flag now correct in all cases. Can be displayed in image window

Mon Aug 23 10:15:32 EDT 1999  Austin Donnelly  <austin@gimp.org>

	Dirty flag now correct in all cases.  Can be displayed in image
	window title too.  See NOTE near gimp_image_dirty() for details.

	* app/fileops.c: gimp_image_clean_all() after reverting an image.
	* app/gdisplay.c: register handlers for gimage dirty and clean
	    signals to update image title.  New image-title-format
	    expansion: %Dx expands to x if the image is dirty.
	* app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct
	    condition to test to see if an image is dirty.
	* app/gimpdrawable.c: gimp_image_dirty() should never be called
	    except from an undo_push_* function.  Call
	    undo_push_cantundo() if you want to dirty the image but can't
	    be bothered writing an undo handler (be ashamed of yourself!).
	* app/gimpimage.c: new gimage signal: clean.  Emitted when an undo
	    operation takes place.  Gimage changes when either dirty or
	    clean is emitted, so if you need to update previews etc, look
	    for both!  Move group_count into gimage structure, since
	    leaving it as a static in undo.c is bad if two undo groups are
	    started on different images at the same time.  More changes
	    of gimp_image_dirty() to undo_push_cantundo()
	    (parasite-related, plus layer moves).  See the NOTE on dirty
	    counter near gimp_image_dirty() for the full story.
	    gimp_image_dirty() and gimp_image_clean() simplified - counter
	    can go negative.
	* app/gimpimageP.h: group_count moved from undo.c
	* app/layers_dialog.c: push undo for layer name change, rather
	    than dirtying the image.
	* app/undo.c: layer rename undo functions
	    added. undo_push_cantundo() convenience functions added.
	    group_count made per-gimage since everything else is.  When
	    blowing away redo stack, make image infinitely dirty if redo
	    info contained file save point.
	* app/undo.h: added undo_push_layer_rename() and
	    undo_push_cantundo().
	* TODO: added idea for undo history window.
parent ef4cb06b
Mon Aug 23 10:15:32 EDT 1999 Austin Donnelly <austin@gimp.org>
Dirty flag now correct in all cases. Can be displayed in image
window title too. See NOTE near gimp_image_dirty() for details.
* app/fileops.c: gimp_image_clean_all() after reverting an image.
* app/gdisplay.c: register handlers for gimage dirty and clean
signals to update image title. New image-title-format
expansion: %Dx expands to x if the image is dirty.
* app/gdisplay_ops.c: gimage->dirty flags != 0 is the correct
condition to test to see if an image is dirty.
* app/gimpdrawable.c: gimp_image_dirty() should never be called
except from an undo_push_* function. Call
undo_push_cantundo() if you want to dirty the image but can't
be bothered writing an undo handler (be ashamed of yourself!).
* app/gimpimage.c: new gimage signal: clean. Emitted when an undo
operation takes place. Gimage changes when either dirty or
clean is emitted, so if you need to update previews etc, look
for both! Move group_count into gimage structure, since
leaving it as a static in undo.c is bad if two undo groups are
started on different images at the same time. More changes
of gimp_image_dirty() to undo_push_cantundo()
(parasite-related, plus layer moves). See the NOTE on dirty
counter near gimp_image_dirty() for the full story.
gimp_image_dirty() and gimp_image_clean() simplified - counter
can go negative.
* app/gimpimageP.h: group_count moved from undo.c
* app/layers_dialog.c: push undo for layer name change, rather
than dirtying the image.
* app/undo.c: layer rename undo functions
added. undo_push_cantundo() convenience functions added.
group_count made per-gimage since everything else is. When
blowing away redo stack, make image infinitely dirty if redo
info contained file save point.
* app/undo.h: added undo_push_layer_rename() and
undo_push_cantundo().
* TODO: added idea for undo history window.
1999-08-23 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/bucket_fill.[ch]: export bucket_fill_region().
......
......@@ -406,6 +406,13 @@ named undo
meaningful undo history display, so you can undo multiple
levels in one go.
undo history
The "type" argument to the undo_push_* functions isn't really
used for anything. We could use it to do the named undos
described above, and allow a "history" window to list the
undo-able actions. Clicking on the relevant line would
roll-back to that point. -- austin.
gradient map layer
map values from current gradient to value/intensity
......@@ -431,5 +438,3 @@ Grid
bitmap. limited utility for char's, but a couple of nice sets
of winding fonts could make it interestings. And you could
use words or strings.
......@@ -490,7 +490,7 @@ gimp_drawable_attach_parasite (GimpDrawable *drawable,
!parasite_compare( parasite,
gimp_drawable_find_parasite
(drawable, parasite_name (parasite))))
gimp_image_dirty (drawable->gimage);
undo_push_cantundo (drawable->gimage, _("parasite attach to drawable"));
parasite_list_add (drawable->parasites, parasite);
if (parasite_has_flag (parasite, PARASITE_ATTACH_PARENT))
......@@ -523,7 +523,7 @@ gimp_drawable_detach_parasite (GimpDrawable *drawable,
undo_push_drawable_parasite_remove (drawable->gimage, drawable,
parasite_name (p));
else if (parasite_is_persistent (p))
gimp_image_dirty (drawable->gimage);
undo_push_cantundo (drawable->gimage, _("detach parasite from drawable"));
parasite_list_remove (drawable->parasites, parasite);
}
......
......@@ -91,6 +91,7 @@ guint32 next_guide_id = 1; /* For generating guide_ID handles for PDB stuff */
*/
enum {
CLEAN,
DIRTY,
REPAINT,
RENAME,
......@@ -118,6 +119,9 @@ gimp_image_class_init (GimpImageClass *klass)
object_class->destroy = gimp_image_destroy;
gimp_image_signals[CLEAN] =
gimp_signal_new ("clean", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
gimp_image_signals[DIRTY] =
gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
......@@ -165,6 +169,7 @@ gimp_image_init (GimpImage *gimage)
gimage->redo_stack = NULL;
gimage->undo_bytes = 0;
gimage->undo_levels = 0;
gimage->group_count = 0;
gimage->pushing_undo_group = 0;
gimage->comp_preview_valid[0] = FALSE;
gimage->comp_preview_valid[1] = FALSE;
......@@ -1068,8 +1073,8 @@ gimp_image_attach_parasite (GimpImage *gimage,
if (parasite_is_persistent (parasite)
&& !parasite_compare (parasite,
gimp_image_find_parasite(gimage,
parasite_name (parasite))))
gimp_image_dirty (gimage);
parasite_name(parasite))))
undo_push_cantundo (gimage, _("attach parasite to image"));
parasite_list_add (gimage->parasites, parasite);
......@@ -1092,7 +1097,7 @@ gimp_image_detach_parasite (GimpImage *gimage,
if (parasite_is_undoable (p))
undo_push_image_parasite_remove (gimage, parasite_name (p));
else if (parasite_is_persistent (p))
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("detach parasite from image"));
parasite_list_remove (gimage->parasites, parasite);
}
......@@ -2089,7 +2094,9 @@ gimp_image_raise_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
/* Dirty the image, but we're too lazy to provide a
* proper undo. */
undo_push_cantundo (gimage, _("raise layer"));
return prev_layer;
}
......@@ -2163,7 +2170,7 @@ gimp_image_lower_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer"));
return next_layer;
}
......@@ -2246,7 +2253,7 @@ gimp_image_raise_layer_to_top (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("raise layer to top"));
return layer;
}
......@@ -2341,7 +2348,7 @@ gimp_image_lower_layer_to_bottom (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer to bottom"));
return layer_arg;
}
......@@ -2420,7 +2427,7 @@ gimp_image_position_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("re-position layer"));
return layer_arg;
}
......@@ -3340,32 +3347,61 @@ gimp_image_enable_undo (GimpImage *gimage)
return gimp_image_thaw_undo (gimage);
}
/* NOTE about the gimage->dirty counter:
* If 0, then the image is clean (ie, copy on disk is the same as the one
* in memory).
* If positive, then that's the number of dirtying operations done
* on the image since the last save.
* If negative, then user has hit undo and gone back in time prior
* to the saved copy. Hitting redo will eventually come back to
* the saved copy.
*
* The image is dirty (ie, needs saving) if counter is non-zero.
*
* If the counter is around 10000, this is due to undo-ing back
* before a saved version, then mutating the image (thus destroying
* the redo stack). Once this has happened, it's impossible to get
* the image back to the state on disk, since the redo info has been
* freed. See undo.c for the gorey details.
*/
/*
* NEVER CALL gimp_image_dirty() directly!
*
* If your code has just dirtied the image, push an undo instead.
* Failing that, push the trivial undo which tells the user the
* command is not undoable: undo_push_cantundo() (But really, it would
* be best to push a proper undo). If you just dirty the image
* without pushing an undo then the dirty count is increased, but
* popping that many undo actions won't lead to a clean image.
*/
gint
gimp_image_dirty (GimpImage *gimage)
{
/* if (gimage->dirty < 0)
gimage->dirty = 2;
else */
gimage->dirty ++;
gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[DIRTY]);
gimage->dirty++;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[DIRTY]);
return gimage->dirty;
return gimage->dirty;
}
gint
gimp_image_clean (GimpImage *gimage)
{
/* if (gimage->dirty <= 0)
gimage->dirty = 0;
else */
gimage->dirty --;
return gimage->dirty;
gimage->dirty--;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
return gimage->dirty;
}
void
gimp_image_clean_all (GimpImage *gimage)
{
gimage->dirty = 0;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
}
Layer *
......
......@@ -91,6 +91,7 @@ guint32 next_guide_id = 1; /* For generating guide_ID handles for PDB stuff */
*/
enum {
CLEAN,
DIRTY,
REPAINT,
RENAME,
......@@ -118,6 +119,9 @@ gimp_image_class_init (GimpImageClass *klass)
object_class->destroy = gimp_image_destroy;
gimp_image_signals[CLEAN] =
gimp_signal_new ("clean", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
gimp_image_signals[DIRTY] =
gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
......@@ -165,6 +169,7 @@ gimp_image_init (GimpImage *gimage)
gimage->redo_stack = NULL;
gimage->undo_bytes = 0;
gimage->undo_levels = 0;
gimage->group_count = 0;
gimage->pushing_undo_group = 0;
gimage->comp_preview_valid[0] = FALSE;
gimage->comp_preview_valid[1] = FALSE;
......@@ -1068,8 +1073,8 @@ gimp_image_attach_parasite (GimpImage *gimage,
if (parasite_is_persistent (parasite)
&& !parasite_compare (parasite,
gimp_image_find_parasite(gimage,
parasite_name (parasite))))
gimp_image_dirty (gimage);
parasite_name(parasite))))
undo_push_cantundo (gimage, _("attach parasite to image"));
parasite_list_add (gimage->parasites, parasite);
......@@ -1092,7 +1097,7 @@ gimp_image_detach_parasite (GimpImage *gimage,
if (parasite_is_undoable (p))
undo_push_image_parasite_remove (gimage, parasite_name (p));
else if (parasite_is_persistent (p))
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("detach parasite from image"));
parasite_list_remove (gimage->parasites, parasite);
}
......@@ -2089,7 +2094,9 @@ gimp_image_raise_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
/* Dirty the image, but we're too lazy to provide a
* proper undo. */
undo_push_cantundo (gimage, _("raise layer"));
return prev_layer;
}
......@@ -2163,7 +2170,7 @@ gimp_image_lower_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer"));
return next_layer;
}
......@@ -2246,7 +2253,7 @@ gimp_image_raise_layer_to_top (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("raise layer to top"));
return layer;
}
......@@ -2341,7 +2348,7 @@ gimp_image_lower_layer_to_bottom (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer to bottom"));
return layer_arg;
}
......@@ -2420,7 +2427,7 @@ gimp_image_position_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("re-position layer"));
return layer_arg;
}
......@@ -3340,32 +3347,61 @@ gimp_image_enable_undo (GimpImage *gimage)
return gimp_image_thaw_undo (gimage);
}
/* NOTE about the gimage->dirty counter:
* If 0, then the image is clean (ie, copy on disk is the same as the one
* in memory).
* If positive, then that's the number of dirtying operations done
* on the image since the last save.
* If negative, then user has hit undo and gone back in time prior
* to the saved copy. Hitting redo will eventually come back to
* the saved copy.
*
* The image is dirty (ie, needs saving) if counter is non-zero.
*
* If the counter is around 10000, this is due to undo-ing back
* before a saved version, then mutating the image (thus destroying
* the redo stack). Once this has happened, it's impossible to get
* the image back to the state on disk, since the redo info has been
* freed. See undo.c for the gorey details.
*/
/*
* NEVER CALL gimp_image_dirty() directly!
*
* If your code has just dirtied the image, push an undo instead.
* Failing that, push the trivial undo which tells the user the
* command is not undoable: undo_push_cantundo() (But really, it would
* be best to push a proper undo). If you just dirty the image
* without pushing an undo then the dirty count is increased, but
* popping that many undo actions won't lead to a clean image.
*/
gint
gimp_image_dirty (GimpImage *gimage)
{
/* if (gimage->dirty < 0)
gimage->dirty = 2;
else */
gimage->dirty ++;
gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[DIRTY]);
gimage->dirty++;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[DIRTY]);
return gimage->dirty;
return gimage->dirty;
}
gint
gimp_image_clean (GimpImage *gimage)
{
/* if (gimage->dirty <= 0)
gimage->dirty = 0;
else */
gimage->dirty --;
return gimage->dirty;
gimage->dirty--;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
return gimage->dirty;
}
void
gimp_image_clean_all (GimpImage *gimage)
{
gimage->dirty = 0;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
}
Layer *
......
......@@ -91,6 +91,7 @@ guint32 next_guide_id = 1; /* For generating guide_ID handles for PDB stuff */
*/
enum {
CLEAN,
DIRTY,
REPAINT,
RENAME,
......@@ -118,6 +119,9 @@ gimp_image_class_init (GimpImageClass *klass)
object_class->destroy = gimp_image_destroy;
gimp_image_signals[CLEAN] =
gimp_signal_new ("clean", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
gimp_image_signals[DIRTY] =
gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
......@@ -165,6 +169,7 @@ gimp_image_init (GimpImage *gimage)
gimage->redo_stack = NULL;
gimage->undo_bytes = 0;
gimage->undo_levels = 0;
gimage->group_count = 0;
gimage->pushing_undo_group = 0;
gimage->comp_preview_valid[0] = FALSE;
gimage->comp_preview_valid[1] = FALSE;
......@@ -1068,8 +1073,8 @@ gimp_image_attach_parasite (GimpImage *gimage,
if (parasite_is_persistent (parasite)
&& !parasite_compare (parasite,
gimp_image_find_parasite(gimage,
parasite_name (parasite))))
gimp_image_dirty (gimage);
parasite_name(parasite))))
undo_push_cantundo (gimage, _("attach parasite to image"));
parasite_list_add (gimage->parasites, parasite);
......@@ -1092,7 +1097,7 @@ gimp_image_detach_parasite (GimpImage *gimage,
if (parasite_is_undoable (p))
undo_push_image_parasite_remove (gimage, parasite_name (p));
else if (parasite_is_persistent (p))
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("detach parasite from image"));
parasite_list_remove (gimage->parasites, parasite);
}
......@@ -2089,7 +2094,9 @@ gimp_image_raise_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
/* Dirty the image, but we're too lazy to provide a
* proper undo. */
undo_push_cantundo (gimage, _("raise layer"));
return prev_layer;
}
......@@ -2163,7 +2170,7 @@ gimp_image_lower_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer"));
return next_layer;
}
......@@ -2246,7 +2253,7 @@ gimp_image_raise_layer_to_top (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("raise layer to top"));
return layer;
}
......@@ -2341,7 +2348,7 @@ gimp_image_lower_layer_to_bottom (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("lower layer to bottom"));
return layer_arg;
}
......@@ -2420,7 +2427,7 @@ gimp_image_position_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("re-position layer"));
return layer_arg;
}
......@@ -3340,32 +3347,61 @@ gimp_image_enable_undo (GimpImage *gimage)
return gimp_image_thaw_undo (gimage);
}
/* NOTE about the gimage->dirty counter:
* If 0, then the image is clean (ie, copy on disk is the same as the one
* in memory).
* If positive, then that's the number of dirtying operations done
* on the image since the last save.
* If negative, then user has hit undo and gone back in time prior
* to the saved copy. Hitting redo will eventually come back to
* the saved copy.
*
* The image is dirty (ie, needs saving) if counter is non-zero.
*
* If the counter is around 10000, this is due to undo-ing back
* before a saved version, then mutating the image (thus destroying
* the redo stack). Once this has happened, it's impossible to get
* the image back to the state on disk, since the redo info has been
* freed. See undo.c for the gorey details.
*/
/*
* NEVER CALL gimp_image_dirty() directly!
*
* If your code has just dirtied the image, push an undo instead.
* Failing that, push the trivial undo which tells the user the
* command is not undoable: undo_push_cantundo() (But really, it would
* be best to push a proper undo). If you just dirty the image
* without pushing an undo then the dirty count is increased, but
* popping that many undo actions won't lead to a clean image.
*/
gint
gimp_image_dirty (GimpImage *gimage)
{
/* if (gimage->dirty < 0)
gimage->dirty = 2;
else */
gimage->dirty ++;
gtk_signal_emit (GTK_OBJECT (gimage), gimp_image_signals[DIRTY]);
gimage->dirty++;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[DIRTY]);
return gimage->dirty;
return gimage->dirty;
}
gint
gimp_image_clean (GimpImage *gimage)
{
/* if (gimage->dirty <= 0)
gimage->dirty = 0;
else */
gimage->dirty --;
return gimage->dirty;
gimage->dirty--;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
return gimage->dirty;
}
void
gimp_image_clean_all (GimpImage *gimage)
{
gimage->dirty = 0;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
}
Layer *
......
......@@ -91,6 +91,7 @@ guint32 next_guide_id = 1; /* For generating guide_ID handles for PDB stuff */
*/
enum {
CLEAN,
DIRTY,
REPAINT,
RENAME,
......@@ -118,6 +119,9 @@ gimp_image_class_init (GimpImageClass *klass)
object_class->destroy = gimp_image_destroy;
gimp_image_signals[CLEAN] =
gimp_signal_new ("clean", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
gimp_image_signals[DIRTY] =
gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0,
gimp_sigtype_void);
......@@ -165,6 +169,7 @@ gimp_image_init (GimpImage *gimage)
gimage->redo_stack = NULL;
gimage->undo_bytes = 0;
gimage->undo_levels = 0;
gimage->group_count = 0;
gimage->pushing_undo_group = 0;
gimage->comp_preview_valid[0] = FALSE;
gimage->comp_preview_valid[1] = FALSE;
......@@ -1068,8 +1073,8 @@ gimp_image_attach_parasite (GimpImage *gimage,
if (parasite_is_persistent (parasite)
&& !parasite_compare (parasite,
gimp_image_find_parasite(gimage,
parasite_name (parasite))))
gimp_image_dirty (gimage);
parasite_name(parasite))))
undo_push_cantundo (gimage, _("attach parasite to image"));
parasite_list_add (gimage->parasites, parasite);
......@@ -1092,7 +1097,7 @@ gimp_image_detach_parasite (GimpImage *gimage,
if (parasite_is_undoable (p))
undo_push_image_parasite_remove (gimage, parasite_name (p));
else if (parasite_is_persistent (p))
gimp_image_dirty (gimage);
undo_push_cantundo (gimage, _("detach parasite from image"));
parasite_list_remove (gimage->parasites, parasite);
}
......@@ -2089,7 +2094,9 @@ gimp_image_raise_layer (GimpImage *gimage,
/* invalidate the composite preview */
gimp_image_invalidate_preview (gimage);
gimp_image_dirty (gimage);
/* Dirty the image, but we're too lazy to provide a
* proper undo. */