mirror of https://github.com/GNOME/gimp.git
Moved the undo system to the core: Keep GimpUndoStack objects as undo and
2003-02-12 Michael Natterer <mitch@gimp.org> Moved the undo system to the core: Keep GimpUndoStack objects as undo and redo stack. Use GimpUndo objects as members of the stacks. GimpUndoStack is derived from GimpUndo and keeps undo groups, so undo group handling is much simpler than before (the whole group is just a single GimpUndo object on the stack and not everything between group boundary markers). * app/Makefile.am * app/undo_types.h: removed. * app/config/gimpcoreconfig.[ch]: added "gulong undo_size". * app/config/gimprc-blurbs.h: and its blurb. * app/core/core-enums.[ch]: added GimpUndoMode and GimpUndoType. * app/core/core-types.h: removed UndoType, added GimpUndoAccumulator, GimpUndoPopFunc and GimpUndoFreeFunc. * app/core/gimpundo.[ch]: do everything the old "Undo" struct did. Removed the virtual push() function and added free(). * app/core/gimpundostack.[ch]: keeps the new undo/redo stacks and also acts as undo group. * app/core/gimpimage-undo.[ch]: moved the undo apparatus here. * app/core/gimpimage.[ch]: removed the old stuff. * app/core/gimpmarshal.list: added marshaller needed for GimpUndo. * app/undo.[ch]: removed the whole undo mechanism. Only the actual undo pushing functions are left. * app/undo_history.c * app/gui/edit-commands.c * app/gui/file-commands.c * app/gui/image-menu.c * app/gui/preferences-dialog.c * app/tools/gimpeditselectiontool.c: changed accordingly.
This commit is contained in:
parent
4858a3750b
commit
be70105d3b
34
ChangeLog
34
ChangeLog
|
@ -1,3 +1,37 @@
|
|||
2003-02-12 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
Undo chopping:
|
||||
|
||||
* app/Makefile.am
|
||||
* app/undo_types.h: removed.
|
||||
|
||||
* app/config/gimpcoreconfig.[ch]: added "gulong undo_size".
|
||||
* app/config/gimprc-blurbs.h: and its blurb.
|
||||
|
||||
* app/undo.[ch]
|
||||
|
||||
* app/core/core-enums.[ch]: added GimpUndoMode and GimpUndoType.
|
||||
|
||||
* app/core/core-types.h: removed UndoType, added GimpUndoAccumulator,
|
||||
GimpUndoPopFunc and GimpUndoFreeFunc.
|
||||
|
||||
* app/core/gimpundo.[ch]: do everything the old "Undo" struct did.
|
||||
Removed the virtual push() function and added free().
|
||||
|
||||
* app/core/gimpundostack.[ch]: keeps the new undo/redo stacks
|
||||
and also acts as undo group.
|
||||
|
||||
* app/core/gimpimage-undo.[ch]
|
||||
* app/core/gimpimage.[ch]
|
||||
* app/core/gimpmarshal.list
|
||||
|
||||
* app/undo_history.c
|
||||
* app/gui/edit-commands.c
|
||||
* app/gui/file-commands.c
|
||||
* app/gui/image-menu.c
|
||||
* app/gui/preferences-dialog.c
|
||||
* app/tools/gimpeditselectiontool.c: changed accordingly.
|
||||
|
||||
2003-02-12 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/Makefile.am
|
||||
|
|
|
@ -53,8 +53,7 @@ bye_sources = \
|
|||
pathP.h \
|
||||
path_transform.h \
|
||||
undo.c \
|
||||
undo.h \
|
||||
undo_types.h
|
||||
undo.h
|
||||
|
||||
##
|
||||
## stuff
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/gimpedit.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-mask.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
|
||||
|
@ -42,8 +43,6 @@
|
|||
#include "dialogs.h"
|
||||
#include "edit-commands.h"
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
|
@ -87,7 +86,7 @@ edit_undo_cmd_callback (GtkWidget *widget,
|
|||
GimpImage *gimage;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
if (undo_pop (gimage))
|
||||
if (gimp_image_undo (gimage))
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
|
||||
|
@ -98,7 +97,7 @@ edit_redo_cmd_callback (GtkWidget *widget,
|
|||
GimpImage *gimage;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
if (undo_redo (gimage))
|
||||
if (gimp_image_redo (gimage))
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpobject.h"
|
||||
|
||||
#include "file/file-open.h"
|
||||
|
@ -365,7 +366,7 @@ file_revert_confirm_callback (GtkWidget *widget,
|
|||
|
||||
if (new_gimage)
|
||||
{
|
||||
undo_free (new_gimage);
|
||||
gimp_image_undo_free (new_gimage);
|
||||
|
||||
gimp_displays_reconnect (old_gimage->gimp, old_gimage, new_gimage);
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ enum
|
|||
PROP_DEFAULT_YRESOLUTION,
|
||||
PROP_DEFAULT_RESOLUTION_UNIT,
|
||||
PROP_UNDO_LEVELS,
|
||||
PROP_UNDO_SIZE,
|
||||
PROP_PLUGINRC_PATH,
|
||||
PROP_MODULE_LOAD_INHIBIT,
|
||||
PROP_PREVIEW_SIZE,
|
||||
|
@ -239,6 +240,10 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
|
|||
"undo-levels", UNDO_LEVELS_BLURB,
|
||||
0, G_MAXINT, 5,
|
||||
GIMP_PARAM_CONFIRM);
|
||||
GIMP_CONFIG_INSTALL_PROP_MEMSIZE (object_class, PROP_UNDO_SIZE,
|
||||
"undo-size", UNDO_SIZE_BLURB,
|
||||
0, G_MAXULONG, 1 << 20,
|
||||
GIMP_PARAM_CONFIRM);
|
||||
GIMP_CONFIG_INSTALL_PROP_PATH (object_class,
|
||||
PROP_PLUGINRC_PATH,
|
||||
"pluginrc-path", PLUGINRC_PATH_BLURB,
|
||||
|
@ -392,6 +397,9 @@ gimp_core_config_set_property (GObject *object,
|
|||
case PROP_UNDO_LEVELS:
|
||||
core_config->levels_of_undo = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_UNDO_SIZE:
|
||||
core_config->undo_size = g_value_get_ulong (value);
|
||||
break;
|
||||
case PROP_PLUGINRC_PATH:
|
||||
g_free (core_config->plug_in_rc_path);
|
||||
core_config->plug_in_rc_path = g_value_dup_string (value);
|
||||
|
@ -500,6 +508,9 @@ gimp_core_config_get_property (GObject *object,
|
|||
case PROP_UNDO_LEVELS:
|
||||
g_value_set_int (value, core_config->levels_of_undo);
|
||||
break;
|
||||
case PROP_UNDO_SIZE:
|
||||
g_value_set_ulong (value, core_config->undo_size);
|
||||
break;
|
||||
case PROP_PLUGINRC_PATH:
|
||||
g_value_set_string (value, core_config->plug_in_rc_path);
|
||||
break;
|
||||
|
|
|
@ -62,6 +62,7 @@ struct _GimpCoreConfig
|
|||
gdouble default_yresolution;
|
||||
GimpUnit default_resolution_unit;
|
||||
gint levels_of_undo;
|
||||
gulong undo_size;
|
||||
gchar *plug_in_rc_path;
|
||||
gchar *module_load_inhibit;
|
||||
GimpPreviewSize preview_size;
|
||||
|
|
|
@ -299,6 +299,9 @@ N_("When set to yes, the GIMP will not save if the image is unchanged since " \
|
|||
#define UNDO_LEVELS_BLURB \
|
||||
N_("Sets the number of operations kept on the undo stack.")
|
||||
|
||||
#define UNDO_SIZE_BLURB \
|
||||
N_("Sets the maximum memory used by operations kept on the undo stack.")
|
||||
|
||||
#define USE_HELP_BLURB \
|
||||
N_("When set to no the F1 help binding will be disabled.")
|
||||
|
||||
|
|
|
@ -362,6 +362,101 @@ gimp_channel_ops_get_type (void)
|
|||
}
|
||||
|
||||
|
||||
static const GEnumValue gimp_undo_mode_enum_values[] =
|
||||
{
|
||||
{ GIMP_UNDO_MODE_UNDO, "GIMP_UNDO_MODE_UNDO", "undo" },
|
||||
{ GIMP_UNDO_MODE_REDO, "GIMP_UNDO_MODE_REDO", "redo" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
GType
|
||||
gimp_undo_mode_get_type (void)
|
||||
{
|
||||
static GType enum_type = 0;
|
||||
|
||||
if (!enum_type)
|
||||
enum_type = g_enum_register_static ("GimpUndoMode", gimp_undo_mode_enum_values);
|
||||
|
||||
return enum_type;
|
||||
}
|
||||
|
||||
|
||||
static const GEnumValue gimp_undo_type_enum_values[] =
|
||||
{
|
||||
{ NO_UNDO_GROUP, N_("<<invalid>>"), "no-undo-group" },
|
||||
{ FIRST_UNDO_GROUP, "FIRST_UNDO_GROUP", "first-undo-group" },
|
||||
{ IMAGE_SCALE_UNDO_GROUP, N_("Scale Image"), "image-scale-undo-group" },
|
||||
{ IMAGE_RESIZE_UNDO_GROUP, N_("Resize Image"), "image-resize-undo-group" },
|
||||
{ IMAGE_CONVERT_UNDO_GROUP, N_("Convert Image"), "image-convert-undo-group" },
|
||||
{ IMAGE_CROP_UNDO_GROUP, N_("Crop Image"), "image-crop-undo-group" },
|
||||
{ IMAGE_LAYERS_MERGE_UNDO_GROUP, N_("Merge Layers"), "image-layers-merge-undo-group" },
|
||||
{ IMAGE_QMASK_UNDO_GROUP, N_("QuickMask"), "image-qmask-undo-group" },
|
||||
{ IMAGE_GUIDE_UNDO_GROUP, N_("Guide"), "image-guide-undo-group" },
|
||||
{ LAYER_PROPERTIES_UNDO_GROUP, N_("Layer Properties"), "layer-properties-undo-group" },
|
||||
{ LAYER_SCALE_UNDO_GROUP, N_("Scale Layer"), "layer-scale-undo-group" },
|
||||
{ LAYER_RESIZE_UNDO_GROUP, N_("Resize Layer"), "layer-resize-undo-group" },
|
||||
{ LAYER_DISPLACE_UNDO_GROUP, N_("Move Layer"), "layer-displace-undo-group" },
|
||||
{ LAYER_LINKED_UNDO_GROUP, N_("Linked Layer"), "layer-linked-undo-group" },
|
||||
{ LAYER_APPLY_MASK_UNDO_GROUP, N_("Apply Layer Mask"), "layer-apply-mask-undo-group" },
|
||||
{ FS_FLOAT_UNDO_GROUP, N_("Float Selection"), "fs-float-undo-group" },
|
||||
{ FS_ANCHOR_UNDO_GROUP, N_("Anchor Floating Selection"), "fs-anchor-undo-group" },
|
||||
{ EDIT_PASTE_UNDO_GROUP, N_("Paste"), "edit-paste-undo-group" },
|
||||
{ EDIT_CUT_UNDO_GROUP, N_("Cut"), "edit-cut-undo-group" },
|
||||
{ EDIT_COPY_UNDO_GROUP, N_("Copy"), "edit-copy-undo-group" },
|
||||
{ TEXT_UNDO_GROUP, N_("Text"), "text-undo-group" },
|
||||
{ TRANSFORM_UNDO_GROUP, N_("Transform"), "transform-undo-group" },
|
||||
{ PAINT_UNDO_GROUP, N_("Paint"), "paint-undo-group" },
|
||||
{ PARASITE_ATTACH_UNDO_GROUP, N_("Attach Parasite"), "parasite-attach-undo-group" },
|
||||
{ PARASITE_REMOVE_UNDO_GROUP, N_("Remove Parasite"), "parasite-remove-undo-group" },
|
||||
{ MISC_UNDO_GROUP, N_("Plug-In"), "misc-undo-group" },
|
||||
{ LAST_UNDO_GROUP, "LAST_UNDO_GROUP", "last-undo-group" },
|
||||
{ IMAGE_UNDO, N_("Image"), "image-undo" },
|
||||
{ IMAGE_MOD_UNDO, N_("Image Mod"), "image-mod-undo" },
|
||||
{ IMAGE_TYPE_UNDO, N_("Image Type"), "image-type-undo" },
|
||||
{ IMAGE_SIZE_UNDO, N_("Image Size"), "image-size-undo" },
|
||||
{ IMAGE_RESOLUTION_UNDO, N_("Resolution Change"), "image-resolution-undo" },
|
||||
{ IMAGE_QMASK_UNDO, N_("QuickMask"), "image-qmask-undo" },
|
||||
{ IMAGE_GUIDE_UNDO, N_("Guide"), "image-guide-undo" },
|
||||
{ MASK_UNDO, N_("Selection Mask"), "mask-undo" },
|
||||
{ ITEM_RENAME_UNDO, N_("Rename Item"), "item-rename-undo" },
|
||||
{ LAYER_ADD_UNDO, N_("New Layer"), "layer-add-undo" },
|
||||
{ LAYER_REMOVE_UNDO, N_("Delete Layer"), "layer-remove-undo" },
|
||||
{ LAYER_MOD_UNDO, N_("Layer Mod"), "layer-mod-undo" },
|
||||
{ LAYER_MASK_ADD_UNDO, N_("Add Layer Mask"), "layer-mask-add-undo" },
|
||||
{ LAYER_MASK_REMOVE_UNDO, N_("Delete Layer Mask"), "layer-mask-remove-undo" },
|
||||
{ LAYER_REPOSITION_UNDO, N_("Layer Reposition"), "layer-reposition-undo" },
|
||||
{ LAYER_DISPLACE_UNDO, N_("Layer Move"), "layer-displace-undo" },
|
||||
{ CHANNEL_ADD_UNDO, N_("New Channel"), "channel-add-undo" },
|
||||
{ CHANNEL_REMOVE_UNDO, N_("Delete Channel"), "channel-remove-undo" },
|
||||
{ CHANNEL_MOD_UNDO, N_("Channel Mod"), "channel-mod-undo" },
|
||||
{ CHANNEL_REPOSITION_UNDO, N_("Channel Reposition"), "channel-reposition-undo" },
|
||||
{ VECTORS_ADD_UNDO, N_("New Vectors"), "vectors-add-undo" },
|
||||
{ VECTORS_REMOVE_UNDO, N_("Delete Vectors"), "vectors-remove-undo" },
|
||||
{ VECTORS_MOD_UNDO, N_("Vectors Mod"), "vectors-mod-undo" },
|
||||
{ VECTORS_REPOSITION_UNDO, N_("Vectors Reposition"), "vectors-reposition-undo" },
|
||||
{ FS_TO_LAYER_UNDO, N_("FS to Layer"), "fs-to-layer-undo" },
|
||||
{ FS_RIGOR_UNDO, N_("FS Rigor"), "fs-rigor-undo" },
|
||||
{ FS_RELAX_UNDO, N_("FS Relax"), "fs-relax-undo" },
|
||||
{ TRANSFORM_UNDO, N_("Transform"), "transform-undo" },
|
||||
{ PAINT_UNDO, N_("Paint"), "paint-undo" },
|
||||
{ PARASITE_ATTACH_UNDO, N_("Attach Parasite"), "parasite-attach-undo" },
|
||||
{ PARASITE_REMOVE_UNDO, N_("Remove Parasite"), "parasite-remove-undo" },
|
||||
{ CANT_UNDO, N_("EEK: can't undo"), "cant-undo" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
GType
|
||||
gimp_undo_type_get_type (void)
|
||||
{
|
||||
static GType enum_type = 0;
|
||||
|
||||
if (!enum_type)
|
||||
enum_type = g_enum_register_static ("GimpUndoType", gimp_undo_type_enum_values);
|
||||
|
||||
return enum_type;
|
||||
}
|
||||
|
||||
|
||||
static const GEnumValue gimp_convert_palette_type_enum_values[] =
|
||||
{
|
||||
{ GIMP_MAKE_PALETTE, "GIMP_MAKE_PALETTE", "make-palette" },
|
||||
|
|
|
@ -267,6 +267,95 @@ typedef enum /*< proxy-resume >*/
|
|||
} GimpChannelOps;
|
||||
|
||||
|
||||
#define GIMP_TYPE_UNDO_MODE (gimp_undo_mode_get_type ())
|
||||
|
||||
GType gimp_undo_mode_get_type (void) G_GNUC_CONST;
|
||||
|
||||
typedef enum /*< proxy-skip >*/ /*< pdb-skip >*/
|
||||
{
|
||||
GIMP_UNDO_MODE_UNDO,
|
||||
GIMP_UNDO_MODE_REDO
|
||||
} GimpUndoMode;
|
||||
|
||||
|
||||
#define GIMP_TYPE_UNDO_TYPE (gimp_undo_type_get_type ())
|
||||
|
||||
GType gimp_undo_type_get_type (void) G_GNUC_CONST;
|
||||
|
||||
typedef enum /*< pdb-skip >*/
|
||||
{
|
||||
/* Type NO_UNDO_GROUP (0) is special - in the gimpimage structure it
|
||||
* means there is no undo group currently being added to.
|
||||
*/
|
||||
NO_UNDO_GROUP = 0, /*< desc="<<invalid>>" >*/
|
||||
|
||||
FIRST_UNDO_GROUP = NO_UNDO_GROUP,
|
||||
|
||||
IMAGE_SCALE_UNDO_GROUP, /*< desc="Scale Image" >*/
|
||||
IMAGE_RESIZE_UNDO_GROUP, /*< desc="Resize Image" >*/
|
||||
IMAGE_CONVERT_UNDO_GROUP, /*< desc="Convert Image" >*/
|
||||
IMAGE_CROP_UNDO_GROUP, /*< desc="Crop Image" >*/
|
||||
IMAGE_LAYERS_MERGE_UNDO_GROUP, /*< desc="Merge Layers" >*/
|
||||
IMAGE_QMASK_UNDO_GROUP, /*< desc="QuickMask" >*/
|
||||
IMAGE_GUIDE_UNDO_GROUP, /*< desc="Guide" >*/
|
||||
LAYER_PROPERTIES_UNDO_GROUP, /*< desc="Layer Properties" >*/
|
||||
LAYER_SCALE_UNDO_GROUP, /*< desc="Scale Layer" >*/
|
||||
LAYER_RESIZE_UNDO_GROUP, /*< desc="Resize Layer" >*/
|
||||
LAYER_DISPLACE_UNDO_GROUP, /*< desc="Move Layer" >*/
|
||||
LAYER_LINKED_UNDO_GROUP, /*< desc="Linked Layer" >*/
|
||||
LAYER_APPLY_MASK_UNDO_GROUP, /*< desc="Apply Layer Mask" >*/
|
||||
FS_FLOAT_UNDO_GROUP, /*< desc="Float Selection" >*/
|
||||
FS_ANCHOR_UNDO_GROUP, /*< desc="Anchor Floating Selection" >*/
|
||||
EDIT_PASTE_UNDO_GROUP, /*< desc="Paste" >*/
|
||||
EDIT_CUT_UNDO_GROUP, /*< desc="Cut" >*/
|
||||
EDIT_COPY_UNDO_GROUP, /*< desc="Copy" >*/
|
||||
TEXT_UNDO_GROUP, /*< desc="Text" >*/
|
||||
TRANSFORM_UNDO_GROUP, /*< desc="Transform" >*/
|
||||
PAINT_UNDO_GROUP, /*< desc="Paint" >*/
|
||||
PARASITE_ATTACH_UNDO_GROUP, /*< desc="Attach Parasite" >*/
|
||||
PARASITE_REMOVE_UNDO_GROUP, /*< desc="Remove Parasite" >*/
|
||||
MISC_UNDO_GROUP, /*< desc="Plug-In" >*/
|
||||
|
||||
LAST_UNDO_GROUP = MISC_UNDO_GROUP,
|
||||
|
||||
/* Undo types which actually do something */
|
||||
|
||||
IMAGE_UNDO, /*< desc="Image" >*/
|
||||
IMAGE_MOD_UNDO, /*< desc="Image Mod" >*/
|
||||
IMAGE_TYPE_UNDO, /*< desc="Image Type" >*/
|
||||
IMAGE_SIZE_UNDO, /*< desc="Image Size" >*/
|
||||
IMAGE_RESOLUTION_UNDO, /*< desc="Resolution Change" >*/
|
||||
IMAGE_QMASK_UNDO, /*< desc="QuickMask" >*/
|
||||
IMAGE_GUIDE_UNDO, /*< desc="Guide" >*/
|
||||
MASK_UNDO, /*< desc="Selection Mask" >*/
|
||||
ITEM_RENAME_UNDO, /*< desc="Rename Item" >*/
|
||||
LAYER_ADD_UNDO, /*< desc="New Layer" >*/
|
||||
LAYER_REMOVE_UNDO, /*< desc="Delete Layer" >*/
|
||||
LAYER_MOD_UNDO, /*< desc="Layer Mod" >*/
|
||||
LAYER_MASK_ADD_UNDO, /*< desc="Add Layer Mask" >*/
|
||||
LAYER_MASK_REMOVE_UNDO, /*< desc="Delete Layer Mask" >*/
|
||||
LAYER_REPOSITION_UNDO, /*< desc="Layer Reposition" >*/
|
||||
LAYER_DISPLACE_UNDO, /*< desc="Layer Move" >*/
|
||||
CHANNEL_ADD_UNDO, /*< desc="New Channel" >*/
|
||||
CHANNEL_REMOVE_UNDO, /*< desc="Delete Channel" >*/
|
||||
CHANNEL_MOD_UNDO, /*< desc="Channel Mod" >*/
|
||||
CHANNEL_REPOSITION_UNDO, /*< desc="Channel Reposition" >*/
|
||||
VECTORS_ADD_UNDO, /*< desc="New Vectors" >*/
|
||||
VECTORS_REMOVE_UNDO, /*< desc="Delete Vectors" >*/
|
||||
VECTORS_MOD_UNDO, /*< desc="Vectors Mod" >*/
|
||||
VECTORS_REPOSITION_UNDO, /*< desc="Vectors Reposition" >*/
|
||||
FS_TO_LAYER_UNDO, /*< desc="FS to Layer" >*/
|
||||
FS_RIGOR_UNDO, /*< desc="FS Rigor" >*/
|
||||
FS_RELAX_UNDO, /*< desc="FS Relax" >*/
|
||||
TRANSFORM_UNDO, /*< desc="Transform" >*/
|
||||
PAINT_UNDO, /*< desc="Paint" >*/
|
||||
PARASITE_ATTACH_UNDO, /*< desc="Attach Parasite" >*/
|
||||
PARASITE_REMOVE_UNDO, /*< desc="Remove Parasite" >*/
|
||||
|
||||
CANT_UNDO, /*< desc="EEK: can't undo" >*/
|
||||
} GimpUndoType;
|
||||
|
||||
|
||||
/*
|
||||
* non-registered enums; register them if needed
|
||||
*/
|
||||
|
|
|
@ -44,46 +44,17 @@ typedef enum
|
|||
GIMP_POINTS
|
||||
} SizeType;
|
||||
|
||||
typedef enum /*< pdb-skip >*/ /*< skip >*/
|
||||
/* Argument to undo_event signal emitted by images */
|
||||
|
||||
typedef enum /*< pdb-skip >*/ /*< skip >*/
|
||||
{
|
||||
/* NOTE: If you change this list, please update the textual mapping at
|
||||
* the bottom of undo.c as well.
|
||||
*/
|
||||
UNDO_PUSHED, /* a new undo has been added to the undo stack */
|
||||
UNDO_EXPIRED, /* an undo has been freed from the undo stack */
|
||||
UNDO_POPPED, /* an undo has been executed and moved to redo stack */
|
||||
UNDO_REDO, /* a redo has been executed and moved to undo stack */
|
||||
UNDO_FREE /* all undo and redo info has been cleared */
|
||||
} undo_event_t;
|
||||
|
||||
/* Type NO_UNDO_GROUP (0) is special - in the gimpimage structure it
|
||||
* means there is no undo group currently being added to.
|
||||
*/
|
||||
NO_UNDO_GROUP = 0,
|
||||
|
||||
FIRST_UNDO_GROUP = NO_UNDO_GROUP,
|
||||
|
||||
IMAGE_SCALE_UNDO_GROUP,
|
||||
IMAGE_RESIZE_UNDO_GROUP,
|
||||
IMAGE_CONVERT_UNDO_GROUP,
|
||||
IMAGE_CROP_UNDO_GROUP,
|
||||
IMAGE_LAYERS_MERGE_UNDO_GROUP,
|
||||
IMAGE_QMASK_UNDO_GROUP,
|
||||
IMAGE_GUIDE_UNDO_GROUP,
|
||||
LAYER_PROPERTIES_UNDO_GROUP,
|
||||
LAYER_SCALE_UNDO_GROUP,
|
||||
LAYER_RESIZE_UNDO_GROUP,
|
||||
LAYER_DISPLACE_UNDO_GROUP,
|
||||
LAYER_LINKED_UNDO_GROUP,
|
||||
LAYER_APPLY_MASK_UNDO_GROUP,
|
||||
FS_FLOAT_UNDO_GROUP,
|
||||
FS_ANCHOR_UNDO_GROUP,
|
||||
EDIT_PASTE_UNDO_GROUP,
|
||||
EDIT_CUT_UNDO_GROUP,
|
||||
EDIT_COPY_UNDO_GROUP,
|
||||
TEXT_UNDO_GROUP,
|
||||
TRANSFORM_UNDO_GROUP,
|
||||
PAINT_UNDO_GROUP,
|
||||
PARASITE_ATTACH_UNDO_GROUP,
|
||||
PARASITE_REMOVE_UNDO_GROUP,
|
||||
MISC_UNDO_GROUP,
|
||||
|
||||
LAST_UNDO_GROUP = MISC_UNDO_GROUP
|
||||
} UndoType;
|
||||
|
||||
|
||||
/* base objects */
|
||||
|
@ -153,6 +124,7 @@ typedef struct _GimpEnvironTable GimpEnvironTable;
|
|||
|
||||
typedef struct _GimpUndo GimpUndo;
|
||||
typedef struct _GimpUndoStack GimpUndoStack;
|
||||
typedef struct _GimpUndoAccumulator GimpUndoAccumulator;
|
||||
|
||||
|
||||
/* non-object types */
|
||||
|
@ -181,10 +153,19 @@ typedef struct _PathList PathList;
|
|||
|
||||
/* functions */
|
||||
|
||||
typedef void (* GimpInitStatusFunc) (const gchar *text1,
|
||||
const gchar *text2,
|
||||
gdouble percentage);
|
||||
typedef GimpData * (* GimpDataObjectLoaderFunc) (const gchar *filename);
|
||||
typedef void (* GimpInitStatusFunc) (const gchar *text1,
|
||||
const gchar *text2,
|
||||
gdouble percentage);
|
||||
|
||||
typedef GimpData * (* GimpDataObjectLoaderFunc) (const gchar *filename);
|
||||
|
||||
typedef gboolean (* GimpUndoPopFunc) (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
typedef void (* GimpUndoFreeFunc) (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
|
||||
/* structs */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,48 +20,10 @@
|
|||
#define __UNDO_H__
|
||||
|
||||
|
||||
/* Argument to undo_event signal emitted by images */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNDO_PUSHED, /* a new undo has been added to the undo stack */
|
||||
UNDO_EXPIRED, /* an undo has been freed from the undo stack */
|
||||
UNDO_POPPED, /* an undo has been executed and moved to redo stack */
|
||||
UNDO_REDO, /* a redo has been executed and moved to undo stack */
|
||||
UNDO_FREE /* all undo and redo info has been cleared */
|
||||
} undo_event_t;
|
||||
|
||||
|
||||
/* Stack peeking functions */
|
||||
|
||||
typedef gint (*undo_map_fn) (const gchar *undoitemname,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/* main undo functions */
|
||||
|
||||
gboolean undo_pop (GimpImage *gimage);
|
||||
gboolean undo_redo (GimpImage *gimage);
|
||||
void undo_free (GimpImage *gimage);
|
||||
|
||||
const gchar * undo_get_undo_name (GimpImage *gimage);
|
||||
const gchar * undo_get_redo_name (GimpImage *gimage);
|
||||
|
||||
|
||||
void undo_map_over_undo_stack (GimpImage *gimage,
|
||||
undo_map_fn fn,
|
||||
gpointer data);
|
||||
void undo_map_over_redo_stack (GimpImage *gimage,
|
||||
undo_map_fn fn,
|
||||
gpointer data);
|
||||
|
||||
UndoType undo_get_undo_top_type (GimpImage *gimage);
|
||||
|
||||
|
||||
/* undo groups */
|
||||
|
||||
gboolean undo_push_group_start (GimpImage *gimage,
|
||||
UndoType type);
|
||||
GimpUndoType undo_type);
|
||||
gboolean undo_push_group_end (GimpImage *gimage);
|
||||
|
||||
|
||||
|
|
|
@ -22,30 +22,319 @@
|
|||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "config/gimpcoreconfig.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimpundostack.h"
|
||||
|
||||
|
||||
void
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_image_undo_pop_stack (GimpImage *gimage,
|
||||
GimpUndoStack *undo_stack,
|
||||
GimpUndoStack *redo_stack,
|
||||
GimpUndoMode undo_mode);
|
||||
static void gimp_image_undo_free_space (GimpImage *gimage);
|
||||
static const gchar * gimp_image_undo_type_to_name (GimpUndoType type);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
gboolean
|
||||
gimp_image_undo (GimpImage *gimage)
|
||||
{
|
||||
GimpUndo *undo;
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (gimage->pushing_undo_group == NO_UNDO_GROUP, FALSE);
|
||||
|
||||
undo = GIMP_UNDO (gimp_undo_stack_pop (gimage->new_undo_stack));
|
||||
|
||||
if (undo)
|
||||
gimp_undo_stack_push (gimage->new_redo_stack, undo);
|
||||
gimp_image_undo_pop_stack (gimage,
|
||||
gimage->undo_stack,
|
||||
gimage->redo_stack,
|
||||
GIMP_UNDO_MODE_UNDO);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gboolean
|
||||
gimp_image_redo (GimpImage *gimage)
|
||||
{
|
||||
GimpUndo *redo;
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (gimage->pushing_undo_group == NO_UNDO_GROUP, FALSE);
|
||||
|
||||
redo = GIMP_UNDO (gimp_undo_stack_pop (gimage->new_redo_stack));
|
||||
|
||||
if (redo)
|
||||
gimp_undo_stack_push (gimage->new_undo_stack, redo);
|
||||
gimp_image_undo_pop_stack (gimage,
|
||||
gimage->redo_stack,
|
||||
gimage->undo_stack,
|
||||
GIMP_UNDO_MODE_REDO);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_undo_free (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_undo_free (GIMP_UNDO (gimage->undo_stack), gimage, GIMP_UNDO_MODE_UNDO);
|
||||
gimp_undo_free (GIMP_UNDO (gimage->redo_stack), gimage, GIMP_UNDO_MODE_REDO);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
gimp_image_undo_event (gimage, UNDO_FREE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_image_undo_group_start (GimpImage *gimage,
|
||||
GimpUndoType type,
|
||||
const gchar *name)
|
||||
{
|
||||
GimpUndoStack *undo_group;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (type > FIRST_UNDO_GROUP &&
|
||||
type <= LAST_UNDO_GROUP, FALSE);
|
||||
|
||||
if (! name)
|
||||
name = gimp_image_undo_type_to_name (type);
|
||||
|
||||
/* Notify listeners that the image will be modified */
|
||||
gimp_image_undo_start (gimage);
|
||||
|
||||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
gimage->group_count++;
|
||||
|
||||
/* If we're already in a group...ignore */
|
||||
if (gimage->group_count > 1)
|
||||
return TRUE;
|
||||
|
||||
/* nuke the redo stack */
|
||||
gimp_undo_free (GIMP_UNDO (gimage->redo_stack), gimage,
|
||||
GIMP_UNDO_MODE_REDO);
|
||||
|
||||
/* 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;
|
||||
|
||||
undo_group = gimp_undo_stack_new (gimage);
|
||||
|
||||
gimp_object_set_name (GIMP_OBJECT (undo_group), name);
|
||||
GIMP_UNDO (undo_group)->undo_type = type;
|
||||
|
||||
gimp_undo_stack_push_undo (gimage->undo_stack,
|
||||
GIMP_UNDO (undo_group));
|
||||
|
||||
gimage->pushing_undo_group = type;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_image_undo_group_end (GimpImage *gimage)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (gimage->group_count > 0, FALSE);
|
||||
|
||||
if (! gimage->undo_on)
|
||||
return FALSE;
|
||||
|
||||
gimage->group_count--;
|
||||
|
||||
if (gimage->group_count == 0)
|
||||
{
|
||||
gimage->pushing_undo_group = NO_UNDO_GROUP;
|
||||
|
||||
gimp_image_undo_free_space (gimage);
|
||||
|
||||
/* Do it here, since undo_push doesn't emit this event while in
|
||||
* the middle of a group
|
||||
*/
|
||||
gimp_image_undo_event (gimage, UNDO_PUSHED);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push (GimpImage *gimage,
|
||||
gsize size,
|
||||
gsize struct_size,
|
||||
GimpUndoType type,
|
||||
const gchar *name,
|
||||
gboolean dirties_image,
|
||||
GimpUndoPopFunc pop_func,
|
||||
GimpUndoFreeFunc free_func)
|
||||
{
|
||||
GimpUndo *new;
|
||||
gpointer undo_struct = NULL;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
|
||||
g_return_val_if_fail (type > LAST_UNDO_GROUP, NULL);
|
||||
|
||||
if (! name)
|
||||
name = gimp_image_undo_type_to_name (type);
|
||||
|
||||
/* Does this undo dirty the image? If so, we always want to mark
|
||||
* image dirty, even if we can't actually push the undo.
|
||||
*/
|
||||
if (dirties_image)
|
||||
gimp_image_dirty (gimage);
|
||||
|
||||
if (! gimage->undo_on)
|
||||
return NULL;
|
||||
|
||||
/* nuke the redo stack */
|
||||
gimp_undo_free (GIMP_UNDO (gimage->redo_stack), gimage,
|
||||
GIMP_UNDO_MODE_REDO);
|
||||
|
||||
/* 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 (struct_size > 0)
|
||||
undo_struct = g_malloc0 (struct_size);
|
||||
|
||||
new = gimp_undo_new (type,
|
||||
name,
|
||||
undo_struct, size,
|
||||
dirties_image,
|
||||
pop_func, free_func);
|
||||
|
||||
if (gimage->pushing_undo_group == NO_UNDO_GROUP)
|
||||
{
|
||||
gimp_undo_stack_push_undo (gimage->undo_stack, new);
|
||||
|
||||
gimp_image_undo_free_space (gimage);
|
||||
|
||||
gimp_image_undo_event (gimage, UNDO_PUSHED);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpUndoStack *undo_group;
|
||||
|
||||
undo_group = GIMP_UNDO_STACK (gimp_undo_stack_peek (gimage->undo_stack));
|
||||
|
||||
gimp_undo_stack_push_undo (undo_group, new);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_image_undo_pop_stack (GimpImage *gimage,
|
||||
GimpUndoStack *undo_stack,
|
||||
GimpUndoStack *redo_stack,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
GimpUndo *undo;
|
||||
GimpUndoAccumulator accum = { 0, };
|
||||
|
||||
undo = gimp_undo_stack_pop_undo (undo_stack, undo_mode, &accum);
|
||||
|
||||
if (! undo)
|
||||
return;
|
||||
|
||||
if (GIMP_IS_UNDO_STACK (undo))
|
||||
gimp_list_reverse (GIMP_LIST (GIMP_UNDO_STACK (undo)->undos));
|
||||
|
||||
gimp_undo_stack_push_undo (redo_stack, undo);
|
||||
|
||||
if (accum.mode_changed)
|
||||
gimp_image_mode_changed (gimage);
|
||||
|
||||
if (accum.size_changed)
|
||||
gimp_viewable_size_changed (GIMP_VIEWABLE (gimage));
|
||||
|
||||
if (accum.resolution_changed)
|
||||
gimp_image_resolution_changed (gimage);
|
||||
|
||||
if (accum.unit_changed)
|
||||
gimp_image_unit_changed (gimage);
|
||||
|
||||
if (accum.mask_changed)
|
||||
gimp_image_mask_changed (gimage);
|
||||
|
||||
if (accum.qmask_changed)
|
||||
gimp_image_qmask_changed (gimage);
|
||||
|
||||
if (accum.alpha_changed)
|
||||
gimp_image_alpha_changed (gimage);
|
||||
|
||||
/* let others know that we just popped an action */
|
||||
gimp_image_undo_event (gimage,
|
||||
(undo_mode == GIMP_UNDO_MODE_UNDO) ?
|
||||
UNDO_POPPED : UNDO_REDO);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_image_undo_free_space (GimpImage *gimage)
|
||||
{
|
||||
GimpContainer *container;
|
||||
gint min_undo_levels;
|
||||
gint max_undo_levels;
|
||||
gulong undo_size;
|
||||
|
||||
container = gimage->undo_stack->undos;
|
||||
|
||||
min_undo_levels = gimage->gimp->config->levels_of_undo;
|
||||
max_undo_levels = 1024; /* FIXME */
|
||||
undo_size = gimage->gimp->config->undo_size;
|
||||
|
||||
/* keep at least undo_levels undo steps */
|
||||
if (gimp_container_num_children (container) <= min_undo_levels)
|
||||
return;
|
||||
|
||||
while ((gimp_object_get_memsize (GIMP_OBJECT (container)) > undo_size) ||
|
||||
(gimp_container_num_children (container) > max_undo_levels))
|
||||
{
|
||||
gimp_undo_stack_free_bottom (gimage->undo_stack, GIMP_UNDO_MODE_UNDO);
|
||||
|
||||
gimp_image_undo_event (gimage, UNDO_EXPIRED);
|
||||
|
||||
if (gimp_container_num_children (container) <= min_undo_levels)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gimp_image_undo_type_to_name (GimpUndoType type)
|
||||
{
|
||||
static GEnumClass *enum_class = NULL;
|
||||
GEnumValue *value;
|
||||
|
||||
if (! enum_class)
|
||||
enum_class = g_type_class_ref (GIMP_TYPE_UNDO_TYPE);
|
||||
|
||||
value = g_enum_get_value (enum_class, type);
|
||||
|
||||
if (value)
|
||||
return value->value_name;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -20,8 +20,24 @@
|
|||
#define __GIMP_IMAGE_UNDO_H__
|
||||
|
||||
|
||||
void gimp_image_undo (GimpImage *gimage);
|
||||
void gimp_image_redo (GimpImage *gimage);
|
||||
gboolean gimp_image_undo (GimpImage *gimage);
|
||||
gboolean gimp_image_redo (GimpImage *gimage);
|
||||
|
||||
void gimp_image_undo_free (GimpImage *gimage);
|
||||
|
||||
gboolean gimp_image_undo_group_start (GimpImage *gimage,
|
||||
GimpUndoType type,
|
||||
const gchar *name);
|
||||
gboolean gimp_image_undo_group_end (GimpImage *gimage);
|
||||
|
||||
GimpUndo * gimp_image_undo_push (GimpImage *gimage,
|
||||
gsize size,
|
||||
gsize struct_size,
|
||||
GimpUndoType type,
|
||||
const gchar *name,
|
||||
gboolean dirties_image,
|
||||
GimpUndoPopFunc pop_func,
|
||||
GimpUndoFreeFunc free_func);
|
||||
|
||||
|
||||
#endif /* __GIMP_IMAGE_UNDO_H__ */
|
||||
|
|
|
@ -414,9 +414,6 @@ gimp_image_class_init (GimpImageClass *klass)
|
|||
klass->undo_event = NULL;
|
||||
klass->flush = NULL;
|
||||
|
||||
klass->undo = gimp_image_undo;
|
||||
klass->redo = gimp_image_redo;
|
||||
|
||||
gimp_image_color_hash_init ();
|
||||
}
|
||||
|
||||
|
@ -479,15 +476,11 @@ gimp_image_init (GimpImage *gimage)
|
|||
gimage->qmask_color.b = 0.0;
|
||||
gimage->qmask_color.a = 0.5;
|
||||
|
||||
gimage->undo_stack = NULL;
|
||||
gimage->redo_stack = NULL;
|
||||
gimage->undo_bytes = 0;
|
||||
gimage->undo_levels = 0;
|
||||
gimage->undo_stack = gimp_undo_stack_new (gimage);
|
||||
gimage->redo_stack = gimp_undo_stack_new (gimage);
|
||||
gimage->group_count = 0;
|
||||
gimage->pushing_undo_group = NO_UNDO_GROUP;
|
||||
|
||||
gimage->new_undo_stack = gimp_undo_stack_new (gimage);
|
||||
gimage->new_redo_stack = gimp_undo_stack_new (gimage);
|
||||
|
||||
gimage->comp_preview = NULL;
|
||||
gimage->comp_preview_valid = FALSE;
|
||||
|
@ -500,7 +493,7 @@ gimp_image_dispose (GObject *object)
|
|||
|
||||
gimage = GIMP_IMAGE (object);
|
||||
|
||||
undo_free (gimage);
|
||||
gimp_image_undo_free (gimage);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -577,15 +570,15 @@ gimp_image_finalize (GObject *object)
|
|||
gimage->guides = NULL;
|
||||
}
|
||||
|
||||
if (gimage->new_undo_stack)
|
||||
if (gimage->undo_stack)
|
||||
{
|
||||
g_object_unref (gimage->new_undo_stack);
|
||||
gimage->new_undo_stack = NULL;
|
||||
g_object_unref (gimage->undo_stack);
|
||||
gimage->undo_stack = NULL;
|
||||
}
|
||||
if (gimage->new_redo_stack)
|
||||
if (gimage->redo_stack)
|
||||
{
|
||||
g_object_unref (gimage->new_redo_stack);
|
||||
gimage->new_redo_stack = NULL;
|
||||
g_object_unref (gimage->redo_stack);
|
||||
gimage->redo_stack = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
|
@ -643,13 +636,8 @@ gimp_image_get_memsize (GimpObject *object)
|
|||
|
||||
/* FIXME paths */
|
||||
|
||||
memsize += g_slist_length (gimage->undo_stack) * (3 * sizeof (gint) +
|
||||
4 * sizeof (gpointer)); /* FIXME */
|
||||
memsize += g_slist_length (gimage->redo_stack) * (3 * sizeof (gint) +
|
||||
4 * sizeof (gpointer)); /* FIXME */
|
||||
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->new_undo_stack));
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->new_redo_stack));
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->undo_stack));
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (gimage->redo_stack));
|
||||
|
||||
if (gimage->comp_preview)
|
||||
memsize += temp_buf_get_memsize (gimage->comp_preview);
|
||||
|
@ -1538,7 +1526,7 @@ gimp_image_undo_enable (GimpImage *gimage)
|
|||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
/* Free all undo steps as they are now invalidated */
|
||||
undo_free (gimage);
|
||||
gimp_image_undo_free (gimage);
|
||||
|
||||
return gimp_image_undo_thaw (gimage);
|
||||
}
|
||||
|
|
|
@ -151,17 +151,12 @@ struct _GimpImage
|
|||
gboolean qmask_inverted; /* TRUE if qmask is inverted */
|
||||
GimpRGB qmask_color; /* rgba triplet of the color */
|
||||
|
||||
/* Old undo apparatus */
|
||||
GSList *undo_stack; /* stack for undo operations */
|
||||
GSList *redo_stack; /* stack for redo operations */
|
||||
gint undo_bytes; /* bytes in undo stack */
|
||||
gint undo_levels; /* levels in undo stack */
|
||||
GimpUndoStack *undo_stack; /* stack for undo operations */
|
||||
GimpUndoStack *redo_stack; /* stack for redo operations */
|
||||
gint group_count; /* nested undo groups */
|
||||
UndoType pushing_undo_group; /* undo group status flag */
|
||||
GimpUndoType pushing_undo_group; /* undo group status flag */
|
||||
|
||||
/* New undo apparatus */
|
||||
GimpUndoStack *new_undo_stack; /* stack for undo operations */
|
||||
GimpUndoStack *new_redo_stack; /* stack for redo operations */
|
||||
|
||||
/* Composite preview */
|
||||
TempBuf *comp_preview; /* the composite preview */
|
||||
|
@ -206,10 +201,6 @@ struct _GimpImageClass
|
|||
gint event);
|
||||
|
||||
void (* flush) (GimpImage *gimage);
|
||||
|
||||
/* virtual functions */
|
||||
void (* undo) (GimpImage *gimage);
|
||||
void (* redo) (GimpImage *gimage);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
BOOLEAN: BOOLEAN
|
||||
BOOLEAN: OBJECT
|
||||
BOOLEAN: OBJECT, ENUM
|
||||
BOOLEAN: POINTER
|
||||
BOOLEAN: VOID
|
||||
|
||||
|
@ -54,6 +55,8 @@ VOID: INT, OBJECT
|
|||
VOID: INT, POINTER
|
||||
VOID: INT, POINTER, POINTER
|
||||
VOID: OBJECT
|
||||
VOID: OBJECT, ENUM
|
||||
VOID: OBJECT, ENUM, POINTER
|
||||
VOID: OBJECT, INT
|
||||
VOID: OBJECT, INT, POINTER
|
||||
VOID: OBJECT, POINTER
|
||||
|
|
|
@ -31,27 +31,30 @@
|
|||
|
||||
enum
|
||||
{
|
||||
PUSH,
|
||||
POP,
|
||||
FREE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
||||
static void gimp_undo_class_init (GimpUndoClass *klass);
|
||||
static void gimp_undo_init (GimpUndo *undo);
|
||||
static void gimp_undo_class_init (GimpUndoClass *klass);
|
||||
static void gimp_undo_init (GimpUndo *undo);
|
||||
|
||||
static void gimp_undo_finalize (GObject *object);
|
||||
static void gimp_undo_finalize (GObject *object);
|
||||
|
||||
static gsize gimp_undo_get_memsize (GimpObject *object);
|
||||
static gsize gimp_undo_get_memsize (GimpObject *object);
|
||||
|
||||
static TempBuf * gimp_undo_get_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height);
|
||||
static TempBuf * gimp_undo_get_preview (GimpViewable *viewable,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static void gimp_undo_real_push (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
static void gimp_undo_real_pop (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
static void gimp_undo_real_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
static void gimp_undo_real_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
|
||||
static guint undo_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -100,25 +103,28 @@ gimp_undo_class_init (GimpUndoClass *klass)
|
|||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
undo_signals[PUSH] =
|
||||
g_signal_new ("push",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpUndoClass, push),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
undo_signals[POP] =
|
||||
g_signal_new ("pop",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpUndoClass, pop),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
gimp_marshal_VOID__OBJECT_ENUM_POINTER,
|
||||
G_TYPE_NONE, 3,
|
||||
GIMP_TYPE_IMAGE,
|
||||
GIMP_TYPE_UNDO_MODE,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
undo_signals[FREE] =
|
||||
g_signal_new ("free",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpUndoClass, free),
|
||||
NULL, NULL,
|
||||
gimp_marshal_VOID__OBJECT_ENUM,
|
||||
G_TYPE_NONE, 2,
|
||||
GIMP_TYPE_IMAGE,
|
||||
GIMP_TYPE_UNDO_MODE);
|
||||
|
||||
object_class->finalize = gimp_undo_finalize;
|
||||
|
||||
|
@ -126,8 +132,8 @@ gimp_undo_class_init (GimpUndoClass *klass)
|
|||
|
||||
viewable_class->get_preview = gimp_undo_get_preview;
|
||||
|
||||
klass->push = gimp_undo_real_push;
|
||||
klass->pop = gimp_undo_real_pop;
|
||||
klass->free = gimp_undo_real_free;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -147,12 +153,6 @@ gimp_undo_finalize (GObject *object)
|
|||
|
||||
undo = GIMP_UNDO (object);
|
||||
|
||||
if (undo->free_func)
|
||||
{
|
||||
undo->free_func (undo);
|
||||
undo->free_func = NULL;
|
||||
}
|
||||
|
||||
if (undo->preview)
|
||||
{
|
||||
temp_buf_free (undo->preview);
|
||||
|
@ -170,6 +170,8 @@ gimp_undo_get_memsize (GimpObject *object)
|
|||
|
||||
undo = GIMP_UNDO (object);
|
||||
|
||||
memsize += undo->size;
|
||||
|
||||
if (undo->preview)
|
||||
memsize += temp_buf_get_memsize (undo->preview);
|
||||
|
||||
|
@ -185,61 +187,86 @@ gimp_undo_get_preview (GimpViewable *viewable,
|
|||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_undo_new (const gchar *name,
|
||||
gimp_undo_new (GimpUndoType undo_type,
|
||||
const gchar *name,
|
||||
gpointer data,
|
||||
gsize size,
|
||||
gboolean dirties_image,
|
||||
GimpUndoPopFunc pop_func,
|
||||
GimpUndoFreeFunc free_func)
|
||||
{
|
||||
GimpUndo *undo;
|
||||
|
||||
undo = GIMP_UNDO (g_object_new (GIMP_TYPE_UNDO, NULL));
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
//g_return_val_if_fail (size == 0 || data != NULL, NULL);
|
||||
|
||||
undo = g_object_new (GIMP_TYPE_UNDO,
|
||||
"name", name,
|
||||
NULL);
|
||||
|
||||
gimp_object_set_name (GIMP_OBJECT (undo), name);
|
||||
|
||||
undo->data = data;
|
||||
|
||||
undo->pop_func = pop_func;
|
||||
undo->free_func = free_func;
|
||||
undo->undo_type = undo_type;
|
||||
undo->data = data;
|
||||
undo->size = size;
|
||||
undo->dirties_image = dirties_image ? TRUE : FALSE;
|
||||
undo->pop_func = pop_func;
|
||||
undo->free_func = free_func;
|
||||
|
||||
return undo;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_undo_push (GimpUndo *undo,
|
||||
GimpImage *gimage)
|
||||
gimp_undo_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_UNDO (undo));
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (accum != NULL);
|
||||
|
||||
g_signal_emit (undo, undo_signals[PUSH], 0, gimage);
|
||||
g_signal_emit (undo, undo_signals[POP], 0, gimage, undo_mode, accum);
|
||||
|
||||
if (undo->dirties_image)
|
||||
{
|
||||
switch (undo_mode)
|
||||
{
|
||||
case GIMP_UNDO_MODE_UNDO:
|
||||
gimp_image_clean (gimage);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_MODE_REDO:
|
||||
gimp_image_dirty (gimage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_undo_pop (GimpUndo *undo,
|
||||
GimpImage *gimage)
|
||||
gimp_undo_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_UNDO (undo));
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
g_signal_emit (undo, undo_signals[POP], 0, gimage);
|
||||
g_signal_emit (undo, undo_signals[FREE], 0, gimage, undo_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_real_push (GimpUndo *undo,
|
||||
GimpImage *gimage)
|
||||
{
|
||||
/* FIXME: need core_config->undo_preview_size */
|
||||
|
||||
undo->preview = gimp_viewable_get_preview (GIMP_VIEWABLE (gimage),
|
||||
24,
|
||||
24);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_real_pop (GimpUndo *undo,
|
||||
GimpImage *gimage)
|
||||
gimp_undo_real_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
if (undo->pop_func)
|
||||
undo->pop_func (undo, gimage);
|
||||
undo->pop_func (undo, gimage, undo_mode, accum);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_real_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
if (undo->free_func)
|
||||
undo->free_func (undo, gimage, undo_mode);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,18 @@
|
|||
#include "gimpviewable.h"
|
||||
|
||||
|
||||
struct _GimpUndoAccumulator
|
||||
{
|
||||
gboolean mode_changed;
|
||||
gboolean size_changed;
|
||||
gboolean resolution_changed;
|
||||
gboolean unit_changed;
|
||||
gboolean mask_changed;
|
||||
gboolean qmask_changed;
|
||||
gboolean alpha_changed;
|
||||
};
|
||||
|
||||
|
||||
#define GIMP_TYPE_UNDO (gimp_undo_get_type ())
|
||||
#define GIMP_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_UNDO, GimpUndo))
|
||||
#define GIMP_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_UNDO, GimpUndoClass))
|
||||
|
@ -31,18 +43,16 @@
|
|||
#define GIMP_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_UNDO, GimpUndoClass))
|
||||
|
||||
|
||||
typedef gboolean (* GimpUndoPopFunc) (GimpUndo *undo, GimpImage *gimage);
|
||||
typedef void (* GimpUndoFreeFunc) (GimpUndo *undo);
|
||||
|
||||
|
||||
typedef struct _GimpUndoClass GimpUndoClass;
|
||||
|
||||
struct _GimpUndo
|
||||
{
|
||||
GimpViewable parent_instance;
|
||||
|
||||
gpointer data; /* data to implement the undo */
|
||||
gboolean dirties_image; /* TRUE if undo mutates image */
|
||||
GimpUndoType undo_type; /* undo type */
|
||||
gpointer data; /* data to implement the undo */
|
||||
gsize size; /* size of undo item */
|
||||
gboolean dirties_image; /* TRUE if undo mutates image */
|
||||
|
||||
GimpUndoPopFunc pop_func; /* function pointer to undo pop proc */
|
||||
GimpUndoFreeFunc free_func; /* function pointer to free undo data */
|
||||
|
@ -54,23 +64,33 @@ struct _GimpUndoClass
|
|||
{
|
||||
GimpViewableClass parent_class;
|
||||
|
||||
void (* push) (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
void (* pop) (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
void (* pop) (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
void (* free) (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode);
|
||||
};
|
||||
|
||||
|
||||
GType gimp_undo_get_type (void) G_GNUC_CONST;
|
||||
GimpUndo * gimp_undo_new (const gchar *name,
|
||||
gpointer data,
|
||||
gboolean dirties_image,
|
||||
GimpUndoPopFunc pop_func,
|
||||
GimpUndoFreeFunc free_func);
|
||||
void gimp_undo_push (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
void gimp_undo_pop (GimpUndo *undo,
|
||||
GimpImage *gimage);
|
||||
|
||||
GimpUndo * gimp_undo_new (GimpUndoType undo_type,
|
||||
const gchar *name,
|
||||
gpointer data,
|
||||
gsize size,
|
||||
gboolean dirties_image,
|
||||
GimpUndoPopFunc pop_func,
|
||||
GimpUndoFreeFunc free_func);
|
||||
|
||||
void gimp_undo_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
void gimp_undo_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
|
||||
#endif /* __GIMP_UNDO_H__ */
|
||||
|
|
|
@ -28,19 +28,27 @@
|
|||
#include "gimpundostack.h"
|
||||
|
||||
|
||||
static void gimp_undo_stack_class_init (GimpUndoStackClass *klass);
|
||||
static void gimp_undo_stack_init (GimpUndoStack *stack);
|
||||
static void gimp_undo_stack_class_init (GimpUndoStackClass *klass);
|
||||
static void gimp_undo_stack_init (GimpUndoStack *stack);
|
||||
|
||||
static void gimp_undo_stack_finalize (GObject *object);
|
||||
static void gimp_undo_stack_finalize (GObject *object);
|
||||
|
||||
static gsize gimp_undo_stack_get_memsize (GimpObject *object);
|
||||
static gsize gimp_undo_stack_get_memsize (GimpObject *object);
|
||||
|
||||
static void gimp_undo_stack_add_callback (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gpointer data);
|
||||
static void gimp_undo_stack_remove_callback (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gpointer data);
|
||||
static void gimp_undo_stack_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
static void gimp_undo_stack_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
static void gimp_undo_stack_add_callback (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gpointer data);
|
||||
static void gimp_undo_stack_remove_callback (GimpContainer *container,
|
||||
GimpObject *object,
|
||||
gpointer data);
|
||||
|
||||
|
||||
static GimpUndoClass *parent_class = NULL;
|
||||
|
@ -79,15 +87,20 @@ gimp_undo_stack_class_init (GimpUndoStackClass *klass)
|
|||
{
|
||||
GObjectClass *object_class;
|
||||
GimpObjectClass *gimp_object_class;
|
||||
GimpUndoClass *undo_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||
undo_class = GIMP_UNDO_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->finalize = gimp_undo_stack_finalize;
|
||||
|
||||
gimp_object_class->get_memsize = gimp_undo_stack_get_memsize;
|
||||
|
||||
undo_class->pop = gimp_undo_stack_pop;
|
||||
undo_class->free = gimp_undo_stack_free;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -140,6 +153,56 @@ gimp_undo_stack_get_memsize (GimpObject *object)
|
|||
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_stack_pop (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
GimpUndoStack *stack;
|
||||
GList *list;
|
||||
|
||||
stack = GIMP_UNDO_STACK (undo);
|
||||
|
||||
for (list = GIMP_LIST (stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
GimpUndo *child;
|
||||
|
||||
child = GIMP_UNDO (list->data);
|
||||
|
||||
gimp_undo_pop (child, gimage, undo_mode, accum);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_stack_free (GimpUndo *undo,
|
||||
GimpImage *gimage,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
GimpUndoStack *stack;
|
||||
GList *list;
|
||||
|
||||
stack = GIMP_UNDO_STACK (undo);
|
||||
|
||||
for (list = GIMP_LIST (stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
GimpUndo *child;
|
||||
|
||||
child = GIMP_UNDO (list->data);
|
||||
|
||||
gimp_undo_free (child, gimage, undo_mode);
|
||||
g_object_unref (child);
|
||||
}
|
||||
|
||||
while (GIMP_LIST (stack->undos)->list)
|
||||
gimp_container_remove (GIMP_CONTAINER (stack->undos),
|
||||
GIMP_OBJECT (GIMP_LIST (stack->undos)->list->data));
|
||||
}
|
||||
|
||||
GimpUndoStack *
|
||||
gimp_undo_stack_new (GimpImage *gimage)
|
||||
{
|
||||
|
@ -155,30 +218,31 @@ gimp_undo_stack_new (GimpImage *gimage)
|
|||
}
|
||||
|
||||
void
|
||||
gimp_undo_stack_push (GimpUndoStack *stack,
|
||||
GimpUndo *undo)
|
||||
gimp_undo_stack_push_undo (GimpUndoStack *stack,
|
||||
GimpUndo *undo)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_UNDO_STACK (stack));
|
||||
g_return_if_fail (GIMP_IS_UNDO (undo));
|
||||
|
||||
gimp_undo_push (undo, stack->gimage);
|
||||
gimp_container_add (GIMP_CONTAINER (stack->undos), GIMP_OBJECT (undo));
|
||||
g_object_unref (undo);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_undo_stack_pop (GimpUndoStack *stack)
|
||||
gimp_undo_stack_pop_undo (GimpUndoStack *stack,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
GimpObject *object;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_UNDO_STACK (stack), NULL);
|
||||
g_return_val_if_fail (accum != NULL, NULL);
|
||||
|
||||
object = gimp_container_get_child_by_index (GIMP_CONTAINER (stack->undos),0);
|
||||
|
||||
if (object)
|
||||
{
|
||||
gimp_container_remove (GIMP_CONTAINER (stack->undos), object);
|
||||
gimp_undo_pop (GIMP_UNDO (object), stack->gimage);
|
||||
gimp_undo_pop (GIMP_UNDO (object), stack->gimage, undo_mode, accum);
|
||||
|
||||
return GIMP_UNDO (object);
|
||||
}
|
||||
|
@ -186,6 +250,29 @@ gimp_undo_stack_pop (GimpUndoStack *stack)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_undo_stack_free_bottom (GimpUndoStack *stack,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
GimpObject *object;
|
||||
gint n_children;
|
||||
|
||||
g_return_if_fail (GIMP_IS_UNDO_STACK (stack));
|
||||
|
||||
n_children = gimp_container_num_children (GIMP_CONTAINER (stack->undos));
|
||||
|
||||
object = gimp_container_get_child_by_index (GIMP_CONTAINER (stack->undos),
|
||||
n_children - 1);
|
||||
|
||||
if (object)
|
||||
{
|
||||
gimp_container_remove (GIMP_CONTAINER (stack->undos), object);
|
||||
gimp_undo_free (GIMP_UNDO (object), stack->gimage, undo_mode);
|
||||
|
||||
g_object_unref (object);
|
||||
}
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_undo_stack_peek (GimpUndoStack *stack)
|
||||
{
|
||||
|
|
|
@ -47,14 +47,19 @@ struct _GimpUndoStackClass
|
|||
};
|
||||
|
||||
|
||||
GType gimp_undo_stack_get_type (void) G_GNUC_CONST;
|
||||
GType gimp_undo_stack_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpUndoStack * gimp_undo_stack_new (GimpImage *gimage);
|
||||
GimpUndoStack * gimp_undo_stack_new (GimpImage *gimage);
|
||||
|
||||
void gimp_undo_stack_push (GimpUndoStack *stack,
|
||||
GimpUndo *undo);
|
||||
GimpUndo * gimp_undo_stack_pop (GimpUndoStack *stack);
|
||||
GimpUndo * gimp_undo_stack_peek (GimpUndoStack *stack);
|
||||
void gimp_undo_stack_push_undo (GimpUndoStack *stack,
|
||||
GimpUndo *undo);
|
||||
GimpUndo * gimp_undo_stack_pop_undo (GimpUndoStack *stack,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
|
||||
void gimp_undo_stack_free_bottom (GimpUndoStack *stack,
|
||||
GimpUndoMode undo_mode);
|
||||
GimpUndo * gimp_undo_stack_peek (GimpUndoStack *stack);
|
||||
|
||||
|
||||
#endif /* __GIMP_UNDO_STACK_H__ */
|
||||
|
|
|
@ -1673,22 +1673,25 @@ prefs_dialog_new (Gimp *gimp,
|
|||
GTK_BOX (vbox2));
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
table = prefs_table_new (3, GTK_CONTAINER (vbox2), FALSE);
|
||||
table = prefs_table_new (4, GTK_CONTAINER (vbox2), FALSE);
|
||||
#else
|
||||
table = prefs_table_new (2, GTK_CONTAINER (vbox2), FALSE);
|
||||
table = prefs_table_new (3, GTK_CONTAINER (vbox2), FALSE);
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
prefs_spin_button_add (config, "undo-levels", 1.0, 5.0, 0,
|
||||
_("Levels of Undo:"),
|
||||
GTK_TABLE (table), 0);
|
||||
prefs_memsize_entry_add (config, "undo-size",
|
||||
_("Maximum Undo Memory:"),
|
||||
GTK_TABLE (table), 1);
|
||||
prefs_memsize_entry_add (config, "tile-cache-size",
|
||||
_("Tile Cache Size:"),
|
||||
GTK_TABLE (table), 1);
|
||||
GTK_TABLE (table), 2);
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
prefs_spin_button_add (config, "num-processors", 1.0, 4.0, 0,
|
||||
_("Number of Processors to Use:"),
|
||||
GTK_TABLE (table), 2);
|
||||
GTK_TABLE (table), 3);
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
/* File Saving */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "core/gimpedit.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-mask.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
|
||||
#include "display/gimpdisplay.h"
|
||||
|
||||
|
@ -42,8 +43,6 @@
|
|||
#include "dialogs.h"
|
||||
#include "edit-commands.h"
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
|
@ -87,7 +86,7 @@ edit_undo_cmd_callback (GtkWidget *widget,
|
|||
GimpImage *gimage;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
if (undo_pop (gimage))
|
||||
if (gimp_image_undo (gimage))
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
|
||||
|
@ -98,7 +97,7 @@ edit_redo_cmd_callback (GtkWidget *widget,
|
|||
GimpImage *gimage;
|
||||
return_if_no_image (gimage, data);
|
||||
|
||||
if (undo_redo (gimage))
|
||||
if (gimp_image_redo (gimage))
|
||||
gimp_image_flush (gimage);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpobject.h"
|
||||
|
||||
#include "file/file-open.h"
|
||||
|
@ -365,7 +366,7 @@ file_revert_confirm_callback (GtkWidget *widget,
|
|||
|
||||
if (new_gimage)
|
||||
{
|
||||
undo_free (new_gimage);
|
||||
gimp_image_undo_free (new_gimage);
|
||||
|
||||
gimp_displays_reconnect (old_gimage->gimp, old_gimage, new_gimage);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "core/gimplayer.h"
|
||||
#include "core/gimplist.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "plug-in/plug-ins.h"
|
||||
|
||||
|
@ -54,8 +55,6 @@
|
|||
#include "tools-commands.h"
|
||||
#include "view-commands.h"
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
|
@ -1163,16 +1162,23 @@ image_menu_update (GtkItemFactory *item_factory,
|
|||
|
||||
if (gdisp && gimp_image_undo_is_enabled (gimage))
|
||||
{
|
||||
undo_name = (gchar *) undo_get_undo_name (gimage);
|
||||
redo_name = (gchar *) undo_get_redo_name (gimage);
|
||||
GimpUndo *undo;
|
||||
GimpUndo *redo;
|
||||
|
||||
undo = gimp_undo_stack_peek (gimage->undo_stack);
|
||||
redo = gimp_undo_stack_peek (gimage->redo_stack);
|
||||
|
||||
if (undo)
|
||||
undo_name =
|
||||
g_strdup_printf (_("Undo %s"),
|
||||
gimp_object_get_name (GIMP_OBJECT (undo)));
|
||||
|
||||
if (redo)
|
||||
redo_name =
|
||||
g_strdup_printf (_("Redo %s"),
|
||||
gimp_object_get_name (GIMP_OBJECT (redo)));
|
||||
}
|
||||
|
||||
if (undo_name)
|
||||
undo_name = g_strdup_printf (_("Undo %s"), gettext (undo_name));
|
||||
|
||||
if (redo_name)
|
||||
redo_name = g_strdup_printf (_("Redo %s"), gettext (redo_name));
|
||||
|
||||
SET_LABEL ("/Edit/Undo", undo_name ? undo_name : _("Undo"));
|
||||
SET_LABEL ("/Edit/Redo", redo_name ? redo_name : _("Redo"));
|
||||
|
||||
|
|
|
@ -1673,22 +1673,25 @@ prefs_dialog_new (Gimp *gimp,
|
|||
GTK_BOX (vbox2));
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
table = prefs_table_new (3, GTK_CONTAINER (vbox2), FALSE);
|
||||
table = prefs_table_new (4, GTK_CONTAINER (vbox2), FALSE);
|
||||
#else
|
||||
table = prefs_table_new (2, GTK_CONTAINER (vbox2), FALSE);
|
||||
table = prefs_table_new (3, GTK_CONTAINER (vbox2), FALSE);
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
prefs_spin_button_add (config, "undo-levels", 1.0, 5.0, 0,
|
||||
_("Levels of Undo:"),
|
||||
GTK_TABLE (table), 0);
|
||||
prefs_memsize_entry_add (config, "undo-size",
|
||||
_("Maximum Undo Memory:"),
|
||||
GTK_TABLE (table), 1);
|
||||
prefs_memsize_entry_add (config, "tile-cache-size",
|
||||
_("Tile Cache Size:"),
|
||||
GTK_TABLE (table), 1);
|
||||
GTK_TABLE (table), 2);
|
||||
|
||||
#ifdef ENABLE_MP
|
||||
prefs_spin_button_add (config, "num-processors", 1.0, 4.0, 0,
|
||||
_("Number of Processors to Use:"),
|
||||
GTK_TABLE (table), 2);
|
||||
GTK_TABLE (table), 3);
|
||||
#endif /* ENABLE_MP */
|
||||
|
||||
/* File Saving */
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "core/gimplayer.h"
|
||||
#include "core/gimplist.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "plug-in/plug-ins.h"
|
||||
|
||||
|
@ -54,8 +55,6 @@
|
|||
#include "tools-commands.h"
|
||||
#include "view-commands.h"
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
||||
|
@ -1163,16 +1162,23 @@ image_menu_update (GtkItemFactory *item_factory,
|
|||
|
||||
if (gdisp && gimp_image_undo_is_enabled (gimage))
|
||||
{
|
||||
undo_name = (gchar *) undo_get_undo_name (gimage);
|
||||
redo_name = (gchar *) undo_get_redo_name (gimage);
|
||||
GimpUndo *undo;
|
||||
GimpUndo *redo;
|
||||
|
||||
undo = gimp_undo_stack_peek (gimage->undo_stack);
|
||||
redo = gimp_undo_stack_peek (gimage->redo_stack);
|
||||
|
||||
if (undo)
|
||||
undo_name =
|
||||
g_strdup_printf (_("Undo %s"),
|
||||
gimp_object_get_name (GIMP_OBJECT (undo)));
|
||||
|
||||
if (redo)
|
||||
redo_name =
|
||||
g_strdup_printf (_("Redo %s"),
|
||||
gimp_object_get_name (GIMP_OBJECT (redo)));
|
||||
}
|
||||
|
||||
if (undo_name)
|
||||
undo_name = g_strdup_printf (_("Undo %s"), gettext (undo_name));
|
||||
|
||||
if (redo_name)
|
||||
redo_name = g_strdup_printf (_("Redo %s"), gettext (redo_name));
|
||||
|
||||
SET_LABEL ("/Edit/Undo", undo_name ? undo_name : _("Undo"));
|
||||
SET_LABEL ("/Edit/Redo", redo_name ? redo_name : _("Redo"));
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-guides.h"
|
||||
#include "core/gimpimage-mask.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimplayer.h"
|
||||
#include "core/gimplayer-floating-sel.h"
|
||||
#include "core/gimplist.h"
|
||||
|
@ -387,7 +388,7 @@ gimp_edit_selection_tool_button_release (GimpTool *tool,
|
|||
if (state & GDK_BUTTON3_MASK) /* OPERATION CANCELLED */
|
||||
{
|
||||
/* Operation cancelled - undo the undo-group! */
|
||||
undo_pop (gdisp->gimage);
|
||||
gimp_image_undo (gdisp->gimage);
|
||||
}
|
||||
|
||||
gimp_image_flush (gdisp->gimage);
|
||||
|
|
2302
app/undo.c
2302
app/undo.c
File diff suppressed because it is too large
Load Diff
40
app/undo.h
40
app/undo.h
|
@ -20,48 +20,10 @@
|
|||
#define __UNDO_H__
|
||||
|
||||
|
||||
/* Argument to undo_event signal emitted by images */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNDO_PUSHED, /* a new undo has been added to the undo stack */
|
||||
UNDO_EXPIRED, /* an undo has been freed from the undo stack */
|
||||
UNDO_POPPED, /* an undo has been executed and moved to redo stack */
|
||||
UNDO_REDO, /* a redo has been executed and moved to undo stack */
|
||||
UNDO_FREE /* all undo and redo info has been cleared */
|
||||
} undo_event_t;
|
||||
|
||||
|
||||
/* Stack peeking functions */
|
||||
|
||||
typedef gint (*undo_map_fn) (const gchar *undoitemname,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/* main undo functions */
|
||||
|
||||
gboolean undo_pop (GimpImage *gimage);
|
||||
gboolean undo_redo (GimpImage *gimage);
|
||||
void undo_free (GimpImage *gimage);
|
||||
|
||||
const gchar * undo_get_undo_name (GimpImage *gimage);
|
||||
const gchar * undo_get_redo_name (GimpImage *gimage);
|
||||
|
||||
|
||||
void undo_map_over_undo_stack (GimpImage *gimage,
|
||||
undo_map_fn fn,
|
||||
gpointer data);
|
||||
void undo_map_over_redo_stack (GimpImage *gimage,
|
||||
undo_map_fn fn,
|
||||
gpointer data);
|
||||
|
||||
UndoType undo_get_undo_top_type (GimpImage *gimage);
|
||||
|
||||
|
||||
/* undo groups */
|
||||
|
||||
gboolean undo_push_group_start (GimpImage *gimage,
|
||||
UndoType type);
|
||||
GimpUndoType undo_type);
|
||||
gboolean undo_push_group_end (GimpImage *gimage);
|
||||
|
||||
|
||||
|
|
|
@ -63,16 +63,18 @@
|
|||
#include "paint-funcs/paint-funcs.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-mask.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "file/file-utils.h"
|
||||
|
||||
#include "widgets/gimpviewabledialog.h"
|
||||
|
||||
#include "undo.h"
|
||||
#include "undo_types.h"
|
||||
|
||||
#include "libgimp/gimpintl.h"
|
||||
|
||||
|
@ -276,7 +278,7 @@ undo_history_set_pixmap_idle (gpointer data)
|
|||
static GdkGC *gc = NULL;
|
||||
TempBuf *buf = NULL;
|
||||
GdkPixmap *pixmap;
|
||||
UndoType utype;
|
||||
GimpUndoType utype;
|
||||
MaskBuf *mbuf = NULL;
|
||||
guchar *src;
|
||||
gdouble r, g, b, a;
|
||||
|
@ -303,7 +305,7 @@ undo_history_set_pixmap_idle (gpointer data)
|
|||
height = (gint)(((gdouble)height * (gdouble)width ) /(gdouble) idle->gimage->width + 0.5);
|
||||
}
|
||||
|
||||
utype = undo_get_undo_top_type (idle->gimage);
|
||||
utype = gimp_undo_stack_peek (idle->gimage->undo_stack)->undo_type;
|
||||
|
||||
if ((utype != MASK_UNDO && utype != IMAGE_QMASK_UNDO) ||
|
||||
(mbuf = mask_render_preview (idle->gimage, &width, &height)) == NULL)
|
||||
|
@ -507,7 +509,7 @@ undo_history_undo_callback (GtkWidget *widget,
|
|||
{
|
||||
undo_history_st *st = data;
|
||||
|
||||
if (undo_pop (st->gimage))
|
||||
if (gimp_image_undo (st->gimage))
|
||||
gimp_image_flush (st->gimage);
|
||||
}
|
||||
|
||||
|
@ -518,7 +520,7 @@ undo_history_redo_callback (GtkWidget *widget,
|
|||
{
|
||||
undo_history_st *st = data;
|
||||
|
||||
if (undo_redo (st->gimage))
|
||||
if (gimp_image_redo (st->gimage))
|
||||
gimp_image_flush (st->gimage);
|
||||
}
|
||||
|
||||
|
@ -589,7 +591,7 @@ undo_history_undo_event (GtkWidget *widget,
|
|||
gtk_clist_remove (clist, cur_selection + 1);
|
||||
|
||||
/* find out what's new */
|
||||
name = undo_get_undo_name (st->gimage);
|
||||
name = gimp_object_get_name (GIMP_OBJECT (gimp_undo_stack_peek (st->gimage->undo_stack)));
|
||||
namelist[0] = NULL;
|
||||
namelist[1] = NULL;
|
||||
namelist[2] = (char *) name;
|
||||
|
@ -677,12 +679,12 @@ undo_history_select_row_callback (GtkWidget *widget,
|
|||
|
||||
while (cur_selection < st->old_selection)
|
||||
{
|
||||
undo_pop (st->gimage);
|
||||
gimp_image_undo (st->gimage);
|
||||
st->old_selection--;
|
||||
}
|
||||
while (cur_selection > st->old_selection)
|
||||
{
|
||||
undo_redo (st->gimage);
|
||||
gimp_image_redo (st->gimage);
|
||||
st->old_selection++;
|
||||
}
|
||||
|
||||
|
@ -735,9 +737,9 @@ undo_history_clean_callback (GtkWidget *widget,
|
|||
|
||||
|
||||
/* Used to build up initial contents of clist */
|
||||
static gboolean
|
||||
undo_history_init_undo (const gchar *undoitemname,
|
||||
void *data)
|
||||
static void
|
||||
undo_history_init_undo (gpointer undo,
|
||||
gpointer data)
|
||||
{
|
||||
undo_history_st *st = data;
|
||||
gchar *namelist[3];
|
||||
|
@ -745,30 +747,26 @@ undo_history_init_undo (const gchar *undoitemname,
|
|||
|
||||
namelist[0] = NULL;
|
||||
namelist[1] = NULL;
|
||||
namelist[2] = (gchar *) undoitemname;
|
||||
namelist[2] = (gchar *) gimp_object_get_name (GIMP_OBJECT (undo));
|
||||
row = gtk_clist_prepend (GTK_CLIST (st->clist), namelist);
|
||||
gtk_clist_set_pixmap (GTK_CLIST (st->clist), row, 0,
|
||||
clear_pixmap, clear_mask);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ditto */
|
||||
static gboolean
|
||||
undo_history_init_redo (const char *undoitemname,
|
||||
void *data)
|
||||
static void
|
||||
undo_history_init_redo (gpointer undo,
|
||||
gpointer data)
|
||||
{
|
||||
undo_history_st *st = data;
|
||||
gchar *namelist[3];
|
||||
gint row;
|
||||
|
||||
namelist[0] = NULL; namelist[1] = NULL;
|
||||
namelist[2] = (gchar *) undoitemname;
|
||||
namelist[1] = NULL;
|
||||
namelist[2] = (gchar *) gimp_object_get_name (GIMP_OBJECT (undo));
|
||||
row = gtk_clist_append (GTK_CLIST (st->clist), namelist);
|
||||
gtk_clist_set_pixmap (GTK_CLIST (st->clist), row, 0,
|
||||
clear_pixmap, clear_mask);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -859,11 +857,16 @@ undo_history_new (GimpImage *gimage)
|
|||
}
|
||||
|
||||
/* work out the initial contents */
|
||||
undo_map_over_undo_stack (st->gimage, undo_history_init_undo, st);
|
||||
gimp_container_foreach (GIMP_CONTAINER (st->gimage->undo_stack->undos),
|
||||
undo_history_init_undo, st);
|
||||
|
||||
/* force selection to bottom */
|
||||
gtk_clist_select_row (GTK_CLIST (st->clist),
|
||||
GTK_CLIST (st->clist)->rows - 1, -1);
|
||||
undo_map_over_redo_stack (st->gimage, undo_history_init_redo, st);
|
||||
|
||||
gimp_container_foreach (GIMP_CONTAINER (st->gimage->redo_stack->undos),
|
||||
undo_history_init_redo, st);
|
||||
|
||||
undo_history_prepend_special (GTK_CLIST (st->clist));
|
||||
st->old_selection = GPOINTER_TO_INT(GTK_CLIST(st->clist)->selection->data);
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __UNDO_TYPES_H__
|
||||
#define __UNDO_TYPES_H__
|
||||
|
||||
|
||||
/* Undo types which actually do something, unlike the ones in
|
||||
* core/core-types.h, which are only for pushing groups
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IMAGE_UNDO = LAST_UNDO_GROUP + 1,
|
||||
IMAGE_MOD_UNDO,
|
||||
IMAGE_TYPE_UNDO,
|
||||
IMAGE_SIZE_UNDO,
|
||||
IMAGE_RESOLUTION_UNDO,
|
||||
IMAGE_QMASK_UNDO,
|
||||
IMAGE_GUIDE_UNDO,
|
||||
MASK_UNDO,
|
||||
ITEM_RENAME_UNDO,
|
||||
LAYER_ADD_UNDO,
|
||||
LAYER_REMOVE_UNDO,
|
||||
LAYER_MOD_UNDO,
|
||||
LAYER_MASK_ADD_UNDO,
|
||||
LAYER_MASK_REMOVE_UNDO,
|
||||
LAYER_REPOSITION_UNDO,
|
||||
LAYER_DISPLACE_UNDO,
|
||||
CHANNEL_ADD_UNDO,
|
||||
CHANNEL_REMOVE_UNDO,
|
||||
CHANNEL_MOD_UNDO,
|
||||
CHANNEL_REPOSITION_UNDO,
|
||||
VECTORS_ADD_UNDO,
|
||||
VECTORS_REMOVE_UNDO,
|
||||
VECTORS_MOD_UNDO,
|
||||
VECTORS_REPOSITION_UNDO,
|
||||
FS_TO_LAYER_UNDO,
|
||||
FS_RIGOR_UNDO,
|
||||
FS_RELAX_UNDO,
|
||||
TRANSFORM_UNDO,
|
||||
PAINT_UNDO,
|
||||
PARASITE_ATTACH_UNDO,
|
||||
PARASITE_REMOVE_UNDO,
|
||||
|
||||
CANT_UNDO
|
||||
} UndoImplType;
|
||||
|
||||
|
||||
#endif /* __UNDO_TYPES_H__ */
|
Loading…
Reference in New Issue