mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
ef4cb06bb7
commit
0a7dca9110
38
ChangeLog
38
ChangeLog
|
@ -1,3 +1,41 @@
|
|||
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().
|
||||
|
|
9
TODO
9
TODO
|
@ -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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ 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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ 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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ 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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ 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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ void
|
|||
gimp_image_clean_all (GimpImage *gimage)
|
||||
{
|
||||
gimage->dirty = 0;
|
||||
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
}
|
||||
|
||||
Layer *
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "tile.h" /* ick. */
|
||||
|
||||
#include "libgimp/parasite.h"
|
||||
#include "libgimp/gimpintl.h"
|
||||
#include "gimpparasite.h"
|
||||
|
||||
|
||||
|
@ -80,6 +81,9 @@ int undo_pop_gimage_mod (GImage *, int, int, void *);
|
|||
int undo_pop_guide (GImage *, int, int, void *);
|
||||
int undo_pop_parasite (GImage *, int, int, void *);
|
||||
int undo_pop_qmask (GImage *, int, int, void *);
|
||||
static int undo_pop_layer_rename (GImage *, int, int, void *);
|
||||
static int undo_pop_cantundo (GImage *, int, int, void *);
|
||||
|
||||
|
||||
/* Free functions */
|
||||
|
||||
|
@ -100,13 +104,14 @@ void undo_free_gimage_mod (int, void *);
|
|||
void undo_free_guide (int, void *);
|
||||
void undo_free_parasite (int, void *);
|
||||
void undo_free_qmask (int, void *);
|
||||
static void undo_free_layer_rename (int, void *);
|
||||
static void undo_free_cantundo (int, void *);
|
||||
|
||||
|
||||
/* Sizing functions */
|
||||
static int layer_size (Layer *);
|
||||
static int channel_size (Channel *);
|
||||
|
||||
static int group_count = 0;
|
||||
static int shrink_wrap = FALSE;
|
||||
|
||||
#define UNDO 0
|
||||
|
@ -249,6 +254,14 @@ undo_push (GImage *gimage,
|
|||
{
|
||||
undo_free_list (gimage, REDO, gimage->redo_stack);
|
||||
gimage->redo_stack = NULL;
|
||||
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
}
|
||||
|
||||
if (!gimage->pushing_undo_group)
|
||||
|
@ -384,6 +397,18 @@ undo_free (GImage *gimage)
|
|||
gimage->redo_stack = NULL;
|
||||
gimage->undo_bytes = 0;
|
||||
gimage->undo_levels = 0;
|
||||
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
|
||||
/* The same applies to the case where the image would become clean
|
||||
* due to undo actions, but since user can't undo without an undo
|
||||
* stack, that's not so much a problem. */
|
||||
}
|
||||
|
||||
|
||||
|
@ -397,16 +422,23 @@ undo_push_group_start (GImage *gimage,
|
|||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
group_count ++;
|
||||
gimage->group_count ++;
|
||||
|
||||
/* If we're already in a group...ignore */
|
||||
if (group_count > 1)
|
||||
if (gimage->group_count > 1)
|
||||
return TRUE;
|
||||
|
||||
if (gimage->redo_stack)
|
||||
{
|
||||
undo_free_list (gimage, REDO, gimage->redo_stack);
|
||||
gimage->redo_stack = NULL;
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
}
|
||||
|
||||
if (! undo_free_up_space (gimage))
|
||||
|
@ -426,9 +458,9 @@ undo_push_group_end (GImage *gimage)
|
|||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
group_count --;
|
||||
gimage->group_count --;
|
||||
|
||||
if (group_count == 0)
|
||||
if (gimage->group_count == 0)
|
||||
{
|
||||
gimage->pushing_undo_group = 0;
|
||||
gimage->undo_stack = g_slist_prepend (gimage->undo_stack, NULL);
|
||||
|
@ -2423,3 +2455,134 @@ undo_free_parasite (int state,
|
|||
g_free (data_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* Layer name change */
|
||||
|
||||
typedef struct {
|
||||
Layer *layer;
|
||||
gchar *old_name;
|
||||
} LayerRenameUndo;
|
||||
|
||||
int
|
||||
undo_push_layer_rename (GImage *gimage, Layer *layer)
|
||||
{
|
||||
Undo *new;
|
||||
LayerRenameUndo *data;
|
||||
long size;
|
||||
|
||||
/* increment the dirty flag for this gimage */
|
||||
gimage_dirty (gimage);
|
||||
|
||||
size = sizeof (LayerRenameUndo);
|
||||
|
||||
if ((new = undo_push (gimage, size, LAYER_CHANGE)))
|
||||
{
|
||||
data = g_new (LayerRenameUndo, 1);
|
||||
new->data = data;
|
||||
new->pop_func = undo_pop_layer_rename;
|
||||
new->free_func = undo_free_layer_rename;
|
||||
|
||||
data->layer = layer;
|
||||
data->old_name = g_strdup (layer_get_name (layer));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
undo_pop_layer_rename (GImage *gimage,
|
||||
int state,
|
||||
int type,
|
||||
void *data_ptr)
|
||||
{
|
||||
LayerRenameUndo *data = data_ptr;
|
||||
gchar *tmp;
|
||||
|
||||
tmp = g_strdup (layer_get_name (data->layer));
|
||||
layer_set_name (data->layer, data->old_name);
|
||||
g_free (data->old_name);
|
||||
data->old_name = tmp;
|
||||
|
||||
switch (state) {
|
||||
case UNDO:
|
||||
gimp_image_clean (gimage);
|
||||
break;
|
||||
|
||||
case REDO:
|
||||
gimp_image_dirty (gimage);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
undo_free_layer_rename (int state,
|
||||
void *data_ptr)
|
||||
{
|
||||
LayerRenameUndo *data = data_ptr;
|
||||
|
||||
g_free (data->old_name);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* Something for which programmer is too lazy to write an undo
|
||||
* function for.
|
||||
*/
|
||||
|
||||
int
|
||||
undo_push_cantundo (GImage *gimage,
|
||||
const char *action)
|
||||
{
|
||||
Undo *new;
|
||||
|
||||
/* This is the sole purpose of this type of undo: the ability to
|
||||
* mark an image as having been mutated, without really providing
|
||||
* any adequate undo facility. */
|
||||
gimp_image_dirty (gimage);
|
||||
|
||||
new = undo_push (gimage, 0, GIMAGE_MOD);
|
||||
if (!new)
|
||||
return FALSE;
|
||||
|
||||
new->data = (void*)action;
|
||||
new->pop_func = undo_pop_cantundo;
|
||||
new->free_func = undo_free_cantundo;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
undo_pop_cantundo (GImage *gimage,
|
||||
int state,
|
||||
int type,
|
||||
void *data_ptr)
|
||||
{
|
||||
char *action = data_ptr;
|
||||
|
||||
switch (state) {
|
||||
case UNDO:
|
||||
g_message (_("Can't undo %s"), action);
|
||||
gimp_image_clean (gimage);
|
||||
break;
|
||||
|
||||
case REDO:
|
||||
gimp_image_dirty (gimage);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
undo_free_cantundo (int state, void *data_ptr)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ int undo_push_image_parasite_remove (GImage *, const char *);
|
|||
int undo_push_drawable_parasite_remove (GImage *, GimpDrawable *,
|
||||
const char *);
|
||||
int undo_push_qmask (GImage *, int);
|
||||
int undo_push_layer_rename (GImage *, Layer *);
|
||||
int undo_push_cantundo (GImage *, const char *);
|
||||
|
||||
int undo_pop (GImage *);
|
||||
int undo_redo (GImage *);
|
||||
|
|
|
@ -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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ 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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ void
|
|||
gimp_image_clean_all (GimpImage *gimage)
|
||||
{
|
||||
gimage->dirty = 0;
|
||||
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
}
|
||||
|
||||
Layer *
|
||||
|
|
|
@ -70,6 +70,7 @@ static void gdisplay_paint_area (GDisplay *, int, int, int, int);
|
|||
static void gdisplay_draw_cursor (GDisplay *);
|
||||
static void gdisplay_display_area (GDisplay *, int, int, int, int);
|
||||
static guint gdisplay_hash (GDisplay *);
|
||||
static void gdisplay_cleandirty_handler (GimpImage *, void *);
|
||||
|
||||
|
||||
static GHashTable *display_ht = NULL;
|
||||
|
@ -155,6 +156,13 @@ gdisplay_new (GimpImage *gimage,
|
|||
|
||||
lc_dialog_preview_update(gimage);
|
||||
|
||||
/* We're interested in clean and dirty signals so we can update the
|
||||
* title if need be. */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
return gdisp;
|
||||
}
|
||||
|
||||
|
@ -259,7 +267,18 @@ gdisplay_format_title (GDisplay *gdisp,
|
|||
"%d", 100 * SCALEDEST (gdisp) / SCALESRC (gdisp));
|
||||
break;
|
||||
|
||||
/* other cool things to be added:
|
||||
case 'D': /* dirty flag */
|
||||
if (format[1] == 0)
|
||||
{
|
||||
g_warning("image-title-format string ended within %%D-sequence");
|
||||
break;
|
||||
}
|
||||
if (gimage->dirty)
|
||||
title[i++] = format[1];
|
||||
format++;
|
||||
break;
|
||||
|
||||
/* Other cool things to be added:
|
||||
* %m = memory used by picture
|
||||
* some kind of resolution / image size thing
|
||||
* people seem to want to know the active layer name
|
||||
|
@ -313,6 +332,9 @@ gdisplay_delete (GDisplay *gdisp)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
/* get rid of signals handled by this display */
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
|
||||
if (gdisp->scroll_gc)
|
||||
gdk_gc_destroy (gdisp->scroll_gc);
|
||||
|
||||
|
@ -2042,7 +2064,7 @@ gdisplays_dirty ()
|
|||
/* traverse the linked list of displays */
|
||||
while (list)
|
||||
{
|
||||
if (((GDisplay *) list->data)->gimage->dirty > 0)
|
||||
if (((GDisplay *) list->data)->gimage->dirty != 0)
|
||||
dirty = 1;
|
||||
list = g_slist_next (list);
|
||||
}
|
||||
|
@ -2158,6 +2180,7 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
gimage_delete (gdisp->gimage);
|
||||
|
||||
instance = gimage->instance_count;
|
||||
|
@ -2167,8 +2190,24 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->gimage = gimage;
|
||||
gdisp->instance = instance;
|
||||
|
||||
/* reconnect our clean / dirty signals */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
gdisplays_update_title (gimage);
|
||||
|
||||
gdisplay_expose_full (gdisp);
|
||||
gdisplay_flush (gdisp);
|
||||
}
|
||||
|
||||
|
||||
/* Called whenever the underlying gimage is dirtied or cleaned */
|
||||
static void
|
||||
gdisplay_cleandirty_handler (GimpImage *gimage, void *data)
|
||||
{
|
||||
GDisplay *gdisp = data;
|
||||
|
||||
gdisplay_update_title (gdisp);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ gdisplay_close_window (GDisplay *gdisp,
|
|||
* to an image canvas. (a gimage with ref_count = 1)
|
||||
*/
|
||||
if (!kill_it && (gdisp->gimage->ref_count == 1) &&
|
||||
(gdisp->gimage->dirty > 0) && confirm_on_close)
|
||||
gdisp->gimage->dirty && confirm_on_close)
|
||||
{
|
||||
gdisplay_close_warning_dialog
|
||||
(g_basename (gimage_filename (gdisp->gimage)), gdisp);
|
||||
|
|
|
@ -70,6 +70,7 @@ static void gdisplay_paint_area (GDisplay *, int, int, int, int);
|
|||
static void gdisplay_draw_cursor (GDisplay *);
|
||||
static void gdisplay_display_area (GDisplay *, int, int, int, int);
|
||||
static guint gdisplay_hash (GDisplay *);
|
||||
static void gdisplay_cleandirty_handler (GimpImage *, void *);
|
||||
|
||||
|
||||
static GHashTable *display_ht = NULL;
|
||||
|
@ -155,6 +156,13 @@ gdisplay_new (GimpImage *gimage,
|
|||
|
||||
lc_dialog_preview_update(gimage);
|
||||
|
||||
/* We're interested in clean and dirty signals so we can update the
|
||||
* title if need be. */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
return gdisp;
|
||||
}
|
||||
|
||||
|
@ -259,7 +267,18 @@ gdisplay_format_title (GDisplay *gdisp,
|
|||
"%d", 100 * SCALEDEST (gdisp) / SCALESRC (gdisp));
|
||||
break;
|
||||
|
||||
/* other cool things to be added:
|
||||
case 'D': /* dirty flag */
|
||||
if (format[1] == 0)
|
||||
{
|
||||
g_warning("image-title-format string ended within %%D-sequence");
|
||||
break;
|
||||
}
|
||||
if (gimage->dirty)
|
||||
title[i++] = format[1];
|
||||
format++;
|
||||
break;
|
||||
|
||||
/* Other cool things to be added:
|
||||
* %m = memory used by picture
|
||||
* some kind of resolution / image size thing
|
||||
* people seem to want to know the active layer name
|
||||
|
@ -313,6 +332,9 @@ gdisplay_delete (GDisplay *gdisp)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
/* get rid of signals handled by this display */
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
|
||||
if (gdisp->scroll_gc)
|
||||
gdk_gc_destroy (gdisp->scroll_gc);
|
||||
|
||||
|
@ -2042,7 +2064,7 @@ gdisplays_dirty ()
|
|||
/* traverse the linked list of displays */
|
||||
while (list)
|
||||
{
|
||||
if (((GDisplay *) list->data)->gimage->dirty > 0)
|
||||
if (((GDisplay *) list->data)->gimage->dirty != 0)
|
||||
dirty = 1;
|
||||
list = g_slist_next (list);
|
||||
}
|
||||
|
@ -2158,6 +2180,7 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
gimage_delete (gdisp->gimage);
|
||||
|
||||
instance = gimage->instance_count;
|
||||
|
@ -2167,8 +2190,24 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->gimage = gimage;
|
||||
gdisp->instance = instance;
|
||||
|
||||
/* reconnect our clean / dirty signals */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
gdisplays_update_title (gimage);
|
||||
|
||||
gdisplay_expose_full (gdisp);
|
||||
gdisplay_flush (gdisp);
|
||||
}
|
||||
|
||||
|
||||
/* Called whenever the underlying gimage is dirtied or cleaned */
|
||||
static void
|
||||
gdisplay_cleandirty_handler (GimpImage *gimage, void *data)
|
||||
{
|
||||
GDisplay *gdisp = data;
|
||||
|
||||
gdisplay_update_title (gdisp);
|
||||
}
|
||||
|
|
|
@ -535,6 +535,7 @@ file_revert_callback (GtkWidget *w,
|
|||
{
|
||||
undo_free (gimage);
|
||||
gdisplay_reconnect (gdisplay, gimage);
|
||||
gimp_image_clean_all (gimage);
|
||||
}
|
||||
else
|
||||
g_message (_("Revert failed."));
|
||||
|
|
|
@ -70,6 +70,7 @@ static void gdisplay_paint_area (GDisplay *, int, int, int, int);
|
|||
static void gdisplay_draw_cursor (GDisplay *);
|
||||
static void gdisplay_display_area (GDisplay *, int, int, int, int);
|
||||
static guint gdisplay_hash (GDisplay *);
|
||||
static void gdisplay_cleandirty_handler (GimpImage *, void *);
|
||||
|
||||
|
||||
static GHashTable *display_ht = NULL;
|
||||
|
@ -155,6 +156,13 @@ gdisplay_new (GimpImage *gimage,
|
|||
|
||||
lc_dialog_preview_update(gimage);
|
||||
|
||||
/* We're interested in clean and dirty signals so we can update the
|
||||
* title if need be. */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
return gdisp;
|
||||
}
|
||||
|
||||
|
@ -259,7 +267,18 @@ gdisplay_format_title (GDisplay *gdisp,
|
|||
"%d", 100 * SCALEDEST (gdisp) / SCALESRC (gdisp));
|
||||
break;
|
||||
|
||||
/* other cool things to be added:
|
||||
case 'D': /* dirty flag */
|
||||
if (format[1] == 0)
|
||||
{
|
||||
g_warning("image-title-format string ended within %%D-sequence");
|
||||
break;
|
||||
}
|
||||
if (gimage->dirty)
|
||||
title[i++] = format[1];
|
||||
format++;
|
||||
break;
|
||||
|
||||
/* Other cool things to be added:
|
||||
* %m = memory used by picture
|
||||
* some kind of resolution / image size thing
|
||||
* people seem to want to know the active layer name
|
||||
|
@ -313,6 +332,9 @@ gdisplay_delete (GDisplay *gdisp)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
/* get rid of signals handled by this display */
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
|
||||
if (gdisp->scroll_gc)
|
||||
gdk_gc_destroy (gdisp->scroll_gc);
|
||||
|
||||
|
@ -2042,7 +2064,7 @@ gdisplays_dirty ()
|
|||
/* traverse the linked list of displays */
|
||||
while (list)
|
||||
{
|
||||
if (((GDisplay *) list->data)->gimage->dirty > 0)
|
||||
if (((GDisplay *) list->data)->gimage->dirty != 0)
|
||||
dirty = 1;
|
||||
list = g_slist_next (list);
|
||||
}
|
||||
|
@ -2158,6 +2180,7 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->idle_render.active = FALSE;
|
||||
}
|
||||
|
||||
gtk_signal_disconnect_by_data (GTK_OBJECT (gdisp->gimage), gdisp);
|
||||
gimage_delete (gdisp->gimage);
|
||||
|
||||
instance = gimage->instance_count;
|
||||
|
@ -2167,8 +2190,24 @@ gdisplay_reconnect (GDisplay *gdisp, GimpImage *gimage)
|
|||
gdisp->gimage = gimage;
|
||||
gdisp->instance = instance;
|
||||
|
||||
/* reconnect our clean / dirty signals */
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "dirty",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gimage), "clean",
|
||||
GTK_SIGNAL_FUNC(gdisplay_cleandirty_handler), gdisp);
|
||||
|
||||
gdisplays_update_title (gimage);
|
||||
|
||||
gdisplay_expose_full (gdisp);
|
||||
gdisplay_flush (gdisp);
|
||||
}
|
||||
|
||||
|
||||
/* Called whenever the underlying gimage is dirtied or cleaned */
|
||||
static void
|
||||
gdisplay_cleandirty_handler (GimpImage *gimage, void *data)
|
||||
{
|
||||
GDisplay *gdisp = data;
|
||||
|
||||
gdisplay_update_title (gdisp);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ gdisplay_close_window (GDisplay *gdisp,
|
|||
* to an image canvas. (a gimage with ref_count = 1)
|
||||
*/
|
||||
if (!kill_it && (gdisp->gimage->ref_count == 1) &&
|
||||
(gdisp->gimage->dirty > 0) && confirm_on_close)
|
||||
gdisp->gimage->dirty && confirm_on_close)
|
||||
{
|
||||
gdisplay_close_warning_dialog
|
||||
(g_basename (gimage_filename (gdisp->gimage)), gdisp);
|
||||
|
|
|
@ -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;
|
||||
|
@ -1069,7 +1074,7 @@ gimp_image_attach_parasite (GimpImage *gimage,
|
|||
&& !parasite_compare (parasite,
|
||||
gimp_image_find_parasite(gimage,
|
||||
parasite_name(parasite))))
|
||||
gimp_image_dirty (gimage);
|
||||
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,12 +3347,40 @@ 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]);
|
||||
|
||||
|
@ -3355,10 +3390,9 @@ gimp_image_dirty (GimpImage *gimage)
|
|||
gint
|
||||
gimp_image_clean (GimpImage *gimage)
|
||||
{
|
||||
/* if (gimage->dirty <= 0)
|
||||
gimage->dirty = 0;
|
||||
else */
|
||||
gimage->dirty--;
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
|
||||
return gimage->dirty;
|
||||
}
|
||||
|
||||
|
@ -3366,6 +3400,8 @@ void
|
|||
gimp_image_clean_all (GimpImage *gimage)
|
||||
{
|
||||
gimage->dirty = 0;
|
||||
|
||||
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[CLEAN]);
|
||||
}
|
||||
|
||||
Layer *
|
||||
|
|
|
@ -97,6 +97,7 @@ struct _GimpImage
|
|||
GSList *redo_stack; /* stack for redo operations */
|
||||
gint undo_bytes; /* bytes in undo stack */
|
||||
gint undo_levels; /* levels in undo stack */
|
||||
gint group_count; /* nested undo groups */
|
||||
gint pushing_undo_group; /* undo group status flag */
|
||||
|
||||
/* Composite preview */
|
||||
|
|
|
@ -3471,17 +3471,19 @@ edit_layer_query_ok_callback (GtkWidget *widget,
|
|||
if ((layer = options->layer))
|
||||
{
|
||||
/* Set the new layer name */
|
||||
if (GIMP_DRAWABLE (layer)->name)
|
||||
if (GIMP_DRAWABLE (layer)->name && layer_is_floating_sel (layer))
|
||||
{
|
||||
/* If the layer is a floating selection, make it a layer */
|
||||
if (layer_is_floating_sel (layer))
|
||||
{
|
||||
floating_sel_to_layer (layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're doing a plain rename */
|
||||
undo_push_layer_rename (options->gimage, layer);
|
||||
}
|
||||
|
||||
layer_set_name (layer,
|
||||
gtk_entry_get_text (GTK_ENTRY (options->name_entry)));
|
||||
gimage_dirty (options->gimage);
|
||||
}
|
||||
|
||||
gdisplays_flush ();
|
||||
|
|
|
@ -3471,17 +3471,19 @@ edit_layer_query_ok_callback (GtkWidget *widget,
|
|||
if ((layer = options->layer))
|
||||
{
|
||||
/* Set the new layer name */
|
||||
if (GIMP_DRAWABLE (layer)->name)
|
||||
if (GIMP_DRAWABLE (layer)->name && layer_is_floating_sel (layer))
|
||||
{
|
||||
/* If the layer is a floating selection, make it a layer */
|
||||
if (layer_is_floating_sel (layer))
|
||||
{
|
||||
floating_sel_to_layer (layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're doing a plain rename */
|
||||
undo_push_layer_rename (options->gimage, layer);
|
||||
}
|
||||
|
||||
layer_set_name (layer,
|
||||
gtk_entry_get_text (GTK_ENTRY (options->name_entry)));
|
||||
gimage_dirty (options->gimage);
|
||||
}
|
||||
|
||||
gdisplays_flush ();
|
||||
|
|
173
app/undo.c
173
app/undo.c
|
@ -42,6 +42,7 @@
|
|||
#include "tile.h" /* ick. */
|
||||
|
||||
#include "libgimp/parasite.h"
|
||||
#include "libgimp/gimpintl.h"
|
||||
#include "gimpparasite.h"
|
||||
|
||||
|
||||
|
@ -80,6 +81,9 @@ int undo_pop_gimage_mod (GImage *, int, int, void *);
|
|||
int undo_pop_guide (GImage *, int, int, void *);
|
||||
int undo_pop_parasite (GImage *, int, int, void *);
|
||||
int undo_pop_qmask (GImage *, int, int, void *);
|
||||
static int undo_pop_layer_rename (GImage *, int, int, void *);
|
||||
static int undo_pop_cantundo (GImage *, int, int, void *);
|
||||
|
||||
|
||||
/* Free functions */
|
||||
|
||||
|
@ -100,13 +104,14 @@ void undo_free_gimage_mod (int, void *);
|
|||
void undo_free_guide (int, void *);
|
||||
void undo_free_parasite (int, void *);
|
||||
void undo_free_qmask (int, void *);
|
||||
static void undo_free_layer_rename (int, void *);
|
||||
static void undo_free_cantundo (int, void *);
|
||||
|
||||
|
||||
/* Sizing functions */
|
||||
static int layer_size (Layer *);
|
||||
static int channel_size (Channel *);
|
||||
|
||||
static int group_count = 0;
|
||||
static int shrink_wrap = FALSE;
|
||||
|
||||
#define UNDO 0
|
||||
|
@ -249,6 +254,14 @@ undo_push (GImage *gimage,
|
|||
{
|
||||
undo_free_list (gimage, REDO, gimage->redo_stack);
|
||||
gimage->redo_stack = NULL;
|
||||
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
}
|
||||
|
||||
if (!gimage->pushing_undo_group)
|
||||
|
@ -384,6 +397,18 @@ undo_free (GImage *gimage)
|
|||
gimage->redo_stack = NULL;
|
||||
gimage->undo_bytes = 0;
|
||||
gimage->undo_levels = 0;
|
||||
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
|
||||
/* The same applies to the case where the image would become clean
|
||||
* due to undo actions, but since user can't undo without an undo
|
||||
* stack, that's not so much a problem. */
|
||||
}
|
||||
|
||||
|
||||
|
@ -397,16 +422,23 @@ undo_push_group_start (GImage *gimage,
|
|||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
group_count ++;
|
||||
gimage->group_count ++;
|
||||
|
||||
/* If we're already in a group...ignore */
|
||||
if (group_count > 1)
|
||||
if (gimage->group_count > 1)
|
||||
return TRUE;
|
||||
|
||||
if (gimage->redo_stack)
|
||||
{
|
||||
undo_free_list (gimage, REDO, gimage->redo_stack);
|
||||
gimage->redo_stack = NULL;
|
||||
/* If the image was dirty, but could become clean by redo-ing
|
||||
* some actions, then it should now become 'infinitely' dirty.
|
||||
* This is because we've just nuked the actions that would allow
|
||||
* the image to become clean again. The only hope for salvation
|
||||
* is to save the image now! -- austin */
|
||||
if (gimage->dirty < 0)
|
||||
gimage->dirty = 10000;
|
||||
}
|
||||
|
||||
if (! undo_free_up_space (gimage))
|
||||
|
@ -426,9 +458,9 @@ undo_push_group_end (GImage *gimage)
|
|||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
group_count --;
|
||||
gimage->group_count --;
|
||||
|
||||
if (group_count == 0)
|
||||
if (gimage->group_count == 0)
|
||||
{
|
||||
gimage->pushing_undo_group = 0;
|
||||
gimage->undo_stack = g_slist_prepend (gimage->undo_stack, NULL);
|
||||
|
@ -2423,3 +2455,134 @@ undo_free_parasite (int state,
|
|||
g_free (data_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* Layer name change */
|
||||
|
||||
typedef struct {
|
||||
Layer *layer;
|
||||
gchar *old_name;
|
||||
} LayerRenameUndo;
|
||||
|
||||
int
|
||||
undo_push_layer_rename (GImage *gimage, Layer *layer)
|
||||
{
|
||||
Undo *new;
|
||||
LayerRenameUndo *data;
|
||||
long size;
|
||||
|
||||
/* increment the dirty flag for this gimage */
|
||||
gimage_dirty (gimage);
|
||||
|
||||
size = sizeof (LayerRenameUndo);
|
||||
|
||||
if ((new = undo_push (gimage, size, LAYER_CHANGE)))
|
||||
{
|
||||
data = g_new (LayerRenameUndo, 1);
|
||||
new->data = data;
|
||||
new->pop_func = undo_pop_layer_rename;
|
||||
new->free_func = undo_free_layer_rename;
|
||||
|
||||
data->layer = layer;
|
||||
data->old_name = g_strdup (layer_get_name (layer));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
undo_pop_layer_rename (GImage *gimage,
|
||||
int state,
|
||||
int type,
|
||||
void *data_ptr)
|
||||
{
|
||||
LayerRenameUndo *data = data_ptr;
|
||||
gchar *tmp;
|
||||
|
||||
tmp = g_strdup (layer_get_name (data->layer));
|
||||
layer_set_name (data->layer, data->old_name);
|
||||
g_free (data->old_name);
|
||||
data->old_name = tmp;
|
||||
|
||||
switch (state) {
|
||||
case UNDO:
|
||||
gimp_image_clean (gimage);
|
||||
break;
|
||||
|
||||
case REDO:
|
||||
gimp_image_dirty (gimage);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
undo_free_layer_rename (int state,
|
||||
void *data_ptr)
|
||||
{
|
||||
LayerRenameUndo *data = data_ptr;
|
||||
|
||||
g_free (data->old_name);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* Something for which programmer is too lazy to write an undo
|
||||
* function for.
|
||||
*/
|
||||
|
||||
int
|
||||
undo_push_cantundo (GImage *gimage,
|
||||
const char *action)
|
||||
{
|
||||
Undo *new;
|
||||
|
||||
/* This is the sole purpose of this type of undo: the ability to
|
||||
* mark an image as having been mutated, without really providing
|
||||
* any adequate undo facility. */
|
||||
gimp_image_dirty (gimage);
|
||||
|
||||
new = undo_push (gimage, 0, GIMAGE_MOD);
|
||||
if (!new)
|
||||
return FALSE;
|
||||
|
||||
new->data = (void*)action;
|
||||
new->pop_func = undo_pop_cantundo;
|
||||
new->free_func = undo_free_cantundo;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
undo_pop_cantundo (GImage *gimage,
|
||||
int state,
|
||||
int type,
|
||||
void *data_ptr)
|
||||
{
|
||||
char *action = data_ptr;
|
||||
|
||||
switch (state) {
|
||||
case UNDO:
|
||||
g_message (_("Can't undo %s"), action);
|
||||
gimp_image_clean (gimage);
|
||||
break;
|
||||
|
||||
case REDO:
|
||||
gimp_image_dirty (gimage);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
undo_free_cantundo (int state, void *data_ptr)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ int undo_push_image_parasite_remove (GImage *, const char *);
|
|||
int undo_push_drawable_parasite_remove (GImage *, GimpDrawable *,
|
||||
const char *);
|
||||
int undo_push_qmask (GImage *, int);
|
||||
int undo_push_layer_rename (GImage *, Layer *);
|
||||
int undo_push_cantundo (GImage *, const char *);
|
||||
|
||||
int undo_pop (GImage *);
|
||||
int undo_redo (GImage *);
|
||||
|
|
Loading…
Reference in New Issue