app/core/Makefile.am app/core/core-types.h app/core/gimpchannelundo.[ch]

2007-01-31  Michael Natterer  <mitch@gimp.org>

	* app/core/Makefile.am
	* app/core/core-types.h
	* app/core/gimpchannelundo.[ch]
	* app/core/gimplayerundo.[ch]
	* app/core/gimplayermaskundo.[ch]: new undo classes implementing
	channel, layer and layer mask add and remove undos.

	* app/vectors/Makefile.am
	* app/vectors/vectors-types.h
	* app/vectors/gimpvectorsundo.[ch]: vectors add and remove undos.

	* app/core/gimpimage-undo-push.[ch]: use the new undo classes.
	Removed "position" parameter from all "add" functions because
	it's useless.

	* app/core/gimpimage.c: changed accordingly.


svn path=/trunk/; revision=21822
This commit is contained in:
Michael Natterer 2007-01-31 12:33:03 +00:00 committed by Michael Natterer
parent 3cd8d4849c
commit d388d58494
16 changed files with 1233 additions and 506 deletions

View file

@ -1,3 +1,22 @@
2007-01-31 Michael Natterer <mitch@gimp.org>
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpchannelundo.[ch]
* app/core/gimplayerundo.[ch]
* app/core/gimplayermaskundo.[ch]: new undo classes implementing
channel, layer and layer mask add and remove undos.
* app/vectors/Makefile.am
* app/vectors/vectors-types.h
* app/vectors/gimpvectorsundo.[ch]: vectors add and remove undos.
* app/core/gimpimage-undo-push.[ch]: use the new undo classes.
Removed "position" parameter from all "add" functions because
it's useless.
* app/core/gimpimage.c: changed accordingly.
2007-01-31 Sven Neumann <sven@gimp.org>
* plug-ins/common/screenshot.c (select_window_x11): if we can't

View file

@ -78,6 +78,8 @@ libappcore_a_sources = \
gimpchannel-select.h \
gimpchannelpropundo.c \
gimpchannelpropundo.h \
gimpchannelundo.c \
gimpchannelundo.h \
gimpcontainer.c \
gimpcontainer.h \
gimpcontainer-filter.c \
@ -210,8 +212,12 @@ libappcore_a_sources = \
gimplayer-floating-sel.h \
gimplayermask.c \
gimplayermask.h \
gimplayermaskundo.c \
gimplayermaskundo.h \
gimplayerpropundo.c \
gimplayerpropundo.h \
gimplayerundo.c \
gimplayerundo.h \
gimplist.c \
gimplist.h \
gimpmaskundo.c \

View file

@ -113,8 +113,11 @@ typedef struct _GimpUndo GimpUndo;
typedef struct _GimpImageUndo GimpImageUndo;
typedef struct _GimpItemUndo GimpItemUndo;
typedef struct _GimpItemPropUndo GimpItemPropUndo;
typedef struct _GimpChannelUndo GimpChannelUndo;
typedef struct _GimpChannelPropUndo GimpChannelPropUndo;
typedef struct _GimpDrawableUndo GimpDrawableUndo;
typedef struct _GimpLayerMaskUndo GimpLayerMaskUndo;
typedef struct _GimpLayerUndo GimpLayerUndo;
typedef struct _GimpLayerPropUndo GimpLayerPropUndo;
typedef struct _GimpMaskUndo GimpMaskUndo;
typedef struct _GimpGuideUndo GimpGuideUndo;

221
app/core/gimpchannelundo.c Normal file
View file

@ -0,0 +1,221 @@
/* GIMP - The GNU 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.
*/
#include "config.h"
#include <glib-object.h>
#include "core-types.h"
#include "gimpcontainer.h"
#include "gimpimage.h"
#include "gimpchannel.h"
#include "gimpchannelundo.h"
enum
{
PROP_0,
PROP_PREV_POSITION,
PROP_PREV_CHANNEL
};
static GObject * gimp_channel_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_channel_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_channel_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_channel_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_channel_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
G_DEFINE_TYPE (GimpChannelUndo, gimp_channel_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_channel_undo_parent_class
static void
gimp_channel_undo_class_init (GimpChannelUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructor = gimp_channel_undo_constructor;
object_class->set_property = gimp_channel_undo_set_property;
object_class->get_property = gimp_channel_undo_get_property;
gimp_object_class->get_memsize = gimp_channel_undo_get_memsize;
undo_class->pop = gimp_channel_undo_pop;
g_object_class_install_property (object_class, PROP_PREV_POSITION,
g_param_spec_int ("prev-position", NULL, NULL,
0, G_MAXINT, 0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_CHANNEL,
g_param_spec_object ("prev-channel", NULL, NULL,
GIMP_TYPE_CHANNEL,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_channel_undo_init (GimpChannelUndo *undo)
{
}
static GObject *
gimp_channel_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GimpChannelUndo *channel_undo;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
channel_undo = GIMP_CHANNEL_UNDO (object);
g_assert (GIMP_IS_CHANNEL (GIMP_ITEM_UNDO (object)->item));
return object;
}
static void
gimp_channel_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpChannelUndo *channel_undo = GIMP_CHANNEL_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
channel_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_CHANNEL:
channel_undo->prev_channel = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_channel_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpChannelUndo *channel_undo = GIMP_CHANNEL_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
g_value_set_int (value, channel_undo->prev_position);
break;
case PROP_PREV_CHANNEL:
g_value_set_object (value, channel_undo->prev_channel);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_channel_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpItemUndo *item_undo = GIMP_ITEM_UNDO (object);
gint64 memsize = 0;
if (! gimp_item_is_attached (item_undo->item))
memsize += gimp_object_get_memsize (GIMP_OBJECT (item_undo->item),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_channel_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpChannelUndo *channel_undo = GIMP_CHANNEL_UNDO (undo);
GimpChannel *channel = GIMP_CHANNEL (GIMP_ITEM_UNDO (undo)->item);
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_CHANNEL_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_CHANNEL_REMOVE))
{
/* remove channel */
/* record the current position */
channel_undo->prev_position = gimp_image_get_channel_index (undo->image,
channel);
gimp_container_remove (undo->image->channels, GIMP_OBJECT (channel));
gimp_item_removed (GIMP_ITEM (channel));
if (channel == gimp_image_get_active_channel (undo->image))
{
if (channel_undo->prev_channel)
gimp_image_set_active_channel (undo->image,
channel_undo->prev_channel);
else
gimp_image_unset_active_channel (undo->image);
}
}
else
{
/* restore channel */
/* record the active channel */
channel_undo->prev_channel = gimp_image_get_active_channel (undo->image);
gimp_container_insert (undo->image->channels, GIMP_OBJECT (channel),
channel_undo->prev_position);
gimp_image_set_active_channel (undo->image, channel);
GIMP_ITEM (channel)->removed = FALSE;
}
}

View file

@ -0,0 +1,53 @@
/* GIMP - The GNU 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 __GIMP_CHANNEL_UNDO_H__
#define __GIMP_CHANNEL_UNDO_H__
#include "gimpitemundo.h"
#define GIMP_TYPE_CHANNEL_UNDO (gimp_channel_undo_get_type ())
#define GIMP_CHANNEL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CHANNEL_UNDO, GimpChannelUndo))
#define GIMP_CHANNEL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CHANNEL_UNDO, GimpChannelUndoClass))
#define GIMP_IS_CHANNEL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CHANNEL_UNDO))
#define GIMP_IS_CHANNEL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CHANNEL_UNDO))
#define GIMP_CHANNEL_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CHANNEL_UNDO, GimpChannelUndoClass))
typedef struct _GimpChannelUndoClass GimpChannelUndoClass;
struct _GimpChannelUndo
{
GimpItemUndo parent_instance;
gint prev_position; /* former position in list */
GimpChannel *prev_channel; /* previous active channel */
};
struct _GimpChannelUndoClass
{
GimpItemUndoClass parent_class;
};
GType gimp_channel_undo_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_CHANNEL_UNDO_H__ */

View file

@ -30,6 +30,7 @@
#include "gimp.h"
#include "gimp-parasites.h"
#include "gimpchannelpropundo.h"
#include "gimpchannelundo.h"
#include "gimpdrawableundo.h"
#include "gimpgrid.h"
#include "gimpguide.h"
@ -42,8 +43,9 @@
#include "gimplayer.h"
#include "gimplayer-floating-sel.h"
#include "gimplayermask.h"
#include "gimplayermaskundo.h"
#include "gimplayerpropundo.h"
#include "gimplist.h"
#include "gimplayerundo.h"
#include "gimpmaskundo.h"
#include "gimpparasitelist.h"
#include "gimpsamplepoint.h"
@ -55,6 +57,7 @@
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectorspropundo.h"
#include "vectors/gimpvectorsundo.h"
#include "gimp-intl.h"
@ -435,31 +438,10 @@ gimp_image_undo_push_item_linked (GimpImage *image,
/* Layer Add/Remove Undo */
/***************************/
typedef struct _LayerUndo LayerUndo;
struct _LayerUndo
{
gint prev_position; /* former position in list */
GimpLayer *prev_layer; /* previous active layer */
};
static GimpUndo * undo_push_layer (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpLayer *layer,
gint prev_position,
GimpLayer *prev_layer);
static gboolean undo_pop_layer (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_layer (GimpUndo *undo,
GimpUndoMode undo_mode);
GimpUndo *
gimp_image_undo_push_layer_add (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer,
gint prev_position,
GimpLayer *prev_layer)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -468,8 +450,14 @@ gimp_image_undo_push_layer_add (GimpImage *image,
g_return_val_if_fail (prev_layer == NULL || GIMP_IS_LAYER (prev_layer),
NULL);
return undo_push_layer (image, undo_desc, GIMP_UNDO_LAYER_ADD,
layer, prev_position, prev_layer);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_UNDO,
0, 0,
GIMP_UNDO_LAYER_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", layer,
"prev-layer", prev_layer,
NULL);
}
GimpUndo *
@ -485,145 +473,15 @@ gimp_image_undo_push_layer_remove (GimpImage *image,
g_return_val_if_fail (prev_layer == NULL || GIMP_IS_LAYER (prev_layer),
NULL);
return undo_push_layer (image, undo_desc, GIMP_UNDO_LAYER_REMOVE,
layer, prev_position, prev_layer);
}
static GimpUndo *
undo_push_layer (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpLayer *layer,
gint prev_position,
GimpLayer *prev_layer)
{
GimpUndo *new;
gint64 size;
size = sizeof (LayerUndo);
if (type == GIMP_UNDO_LAYER_REMOVE)
size += gimp_object_get_memsize (GIMP_OBJECT (layer), NULL);
if ((new = gimp_image_undo_push (image, GIMP_TYPE_ITEM_UNDO,
size, sizeof (LayerUndo),
type, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_layer,
undo_free_layer,
"item", layer,
NULL)))
{
LayerUndo *lu = new->data;
lu->prev_position = prev_position;
lu->prev_layer = prev_layer;
return new;
}
return NULL;
}
static gboolean
undo_pop_layer (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
LayerUndo *lu = undo->data;
GimpLayer *layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
gboolean old_has_alpha;
old_has_alpha = gimp_image_has_alpha (undo->image);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_LAYER_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_LAYER_REMOVE))
{
/* remove layer */
undo->size += gimp_object_get_memsize (GIMP_OBJECT (layer), NULL);
/* record the current position */
lu->prev_position = gimp_image_get_layer_index (undo->image, layer);
gimp_container_remove (undo->image->layers, GIMP_OBJECT (layer));
undo->image->layer_stack = g_slist_remove (undo->image->layer_stack,
layer);
if (gimp_layer_is_floating_sel (layer))
{
/* invalidate the boundary *before* setting the
* floating_sel pointer to NULL because the selection's
* outline is affected by the floating_sel and won't be
* completely cleared otherwise (bug #160247).
*/
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
undo->image->floating_sel = NULL;
/* activate the underlying drawable */
floating_sel_activate_drawable (layer);
gimp_image_floating_selection_changed (undo->image);
}
else if (layer == gimp_image_get_active_layer (undo->image))
{
if (lu->prev_layer)
{
gimp_image_set_active_layer (undo->image, lu->prev_layer);
}
else if (undo->image->layer_stack)
{
gimp_image_set_active_layer (undo->image,
undo->image->layer_stack->data);
}
else
{
gimp_image_set_active_layer (undo->image, NULL);
}
}
gimp_item_removed (GIMP_ITEM (layer));
}
else
{
/* restore layer */
undo->size -= gimp_object_get_memsize (GIMP_OBJECT (layer), NULL);
/* record the active layer */
lu->prev_layer = gimp_image_get_active_layer (undo->image);
/* if this is a floating selection, set the fs pointer */
if (gimp_layer_is_floating_sel (layer))
undo->image->floating_sel = layer;
gimp_container_insert (undo->image->layers,
GIMP_OBJECT (layer), lu->prev_position);
gimp_image_set_active_layer (undo->image, layer);
if (gimp_layer_is_floating_sel (layer))
gimp_image_floating_selection_changed (undo->image);
GIMP_ITEM (layer)->removed = FALSE;
if (layer->mask)
GIMP_ITEM (layer->mask)->removed = FALSE;
}
if (old_has_alpha != gimp_image_has_alpha (undo->image))
accum->alpha_changed = TRUE;
return TRUE;
}
static void
undo_free_layer (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_UNDO,
0, 0,
GIMP_UNDO_LAYER_REMOVE, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", layer,
"prev-position", prev_position,
"prev-layer", prev_layer,
NULL);
}
@ -751,24 +609,6 @@ gimp_image_undo_push_text_layer_modified (GimpImage *image,
/* Layer Mask Add/Remove Undo */
/********************************/
typedef struct _LayerMaskUndo LayerMaskUndo;
struct _LayerMaskUndo
{
GimpLayerMask *mask;
};
static GimpUndo * undo_push_layer_mask (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpLayer *layer,
GimpLayerMask *mask);
static gboolean undo_pop_layer_mask (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_layer_mask (GimpUndo *undo,
GimpUndoMode undo_mode);
GimpUndo *
gimp_image_undo_push_layer_mask_add (GimpImage *image,
const gchar *undo_desc,
@ -781,8 +621,14 @@ gimp_image_undo_push_layer_mask_add (GimpImage *image,
g_return_val_if_fail (GIMP_IS_LAYER_MASK (mask), NULL);
g_return_val_if_fail (! gimp_item_is_attached (GIMP_ITEM (mask)), NULL);
return undo_push_layer_mask (image, undo_desc, GIMP_UNDO_LAYER_MASK_ADD,
layer, mask);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_MASK_UNDO,
0, 0,
GIMP_UNDO_LAYER_MASK_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", layer,
"layer-mask", mask,
NULL);
}
GimpUndo *
@ -796,89 +642,17 @@ gimp_image_undo_push_layer_mask_remove (GimpImage *image,
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
g_return_val_if_fail (GIMP_IS_LAYER_MASK (mask), NULL);
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (mask)), NULL);
g_return_val_if_fail (mask->layer == layer, NULL);
g_return_val_if_fail (layer->mask == mask, NULL);
g_return_val_if_fail (gimp_layer_mask_get_layer (mask) == layer, NULL);
g_return_val_if_fail (gimp_layer_get_mask (layer) == mask, NULL);
return undo_push_layer_mask (image, undo_desc, GIMP_UNDO_LAYER_MASK_REMOVE,
layer, mask);
}
static GimpUndo *
undo_push_layer_mask (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpLayer *layer,
GimpLayerMask *mask)
{
GimpUndo *new;
gint64 size;
size = sizeof (LayerMaskUndo);
if (type == GIMP_UNDO_LAYER_MASK_REMOVE)
size += gimp_object_get_memsize (GIMP_OBJECT (mask), NULL);
if ((new = gimp_image_undo_push (image, GIMP_TYPE_ITEM_UNDO,
size, sizeof (LayerMaskUndo),
type, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_layer_mask,
undo_free_layer_mask,
"item", layer,
NULL)))
{
LayerMaskUndo *lmu = new->data;
lmu->mask = g_object_ref (mask);
return new;
}
return NULL;
}
static gboolean
undo_pop_layer_mask (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
LayerMaskUndo *lmu = undo->data;
GimpLayer *layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_LAYER_MASK_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_LAYER_MASK_REMOVE))
{
/* remove layer mask */
undo->size += gimp_object_get_memsize (GIMP_OBJECT (lmu->mask), NULL);
gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
}
else
{
/* restore layer */
undo->size -= gimp_object_get_memsize (GIMP_OBJECT (lmu->mask), NULL);
gimp_layer_add_mask (layer, lmu->mask, FALSE);
GIMP_ITEM (lmu->mask)->removed = FALSE;
}
return TRUE;
}
static void
undo_free_layer_mask (GimpUndo *undo,
GimpUndoMode undo_mode)
{
LayerMaskUndo *lmu = undo->data;
g_object_unref (lmu->mask);
g_free (lmu);
return gimp_image_undo_push (image, GIMP_TYPE_LAYER_MASK_UNDO,
0, 0,
GIMP_UNDO_LAYER_MASK_REMOVE, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", layer,
"layer-mask", mask,
NULL);
}
@ -1002,31 +776,10 @@ undo_free_layer_mask_properties (GimpUndo *undo,
/* Add/Remove Channel Undo */
/*****************************/
typedef struct _ChannelUndo ChannelUndo;
struct _ChannelUndo
{
gint prev_position; /* former position in list */
GimpChannel *prev_channel; /* previous active channel */
};
static GimpUndo * undo_push_channel (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpChannel *channel,
gint prev_position,
GimpChannel *prev_channel);
static gboolean undo_pop_channel (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_channel (GimpUndo *undo,
GimpUndoMode undo_mode);
GimpUndo *
gimp_image_undo_push_channel_add (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel,
gint prev_position,
GimpChannel *prev_channel)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -1035,8 +788,14 @@ gimp_image_undo_push_channel_add (GimpImage *image,
g_return_val_if_fail (prev_channel == NULL || GIMP_IS_CHANNEL (prev_channel),
NULL);
return undo_push_channel (image, undo_desc, GIMP_UNDO_CHANNEL_ADD,
channel, prev_position, prev_channel);
return gimp_image_undo_push (image, GIMP_TYPE_CHANNEL_UNDO,
0, 0,
GIMP_UNDO_CHANNEL_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", channel,
"prev-channel", prev_channel,
NULL);
}
GimpUndo *
@ -1052,102 +811,15 @@ gimp_image_undo_push_channel_remove (GimpImage *image,
g_return_val_if_fail (prev_channel == NULL || GIMP_IS_CHANNEL (prev_channel),
NULL);
return undo_push_channel (image, undo_desc, GIMP_UNDO_CHANNEL_REMOVE,
channel, prev_position, prev_channel);
}
static GimpUndo *
undo_push_channel (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpChannel *channel,
gint prev_position,
GimpChannel *prev_channel)
{
GimpUndo *new;
gint64 size;
size = sizeof (ChannelUndo);
if (type == GIMP_UNDO_CHANNEL_REMOVE)
size += gimp_object_get_memsize (GIMP_OBJECT (channel), NULL);
if ((new = gimp_image_undo_push (image, GIMP_TYPE_ITEM_UNDO,
size, sizeof (ChannelUndo),
type, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_channel,
undo_free_channel,
"item", channel,
NULL)))
{
ChannelUndo *cu = new->data;
cu->prev_position = prev_position;
cu->prev_channel = prev_channel;
return new;
}
return NULL;
}
static gboolean
undo_pop_channel (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
ChannelUndo *cu = undo->data;
GimpChannel *channel = GIMP_CHANNEL (GIMP_ITEM_UNDO (undo)->item);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_CHANNEL_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_CHANNEL_REMOVE))
{
/* remove channel */
undo->size += gimp_object_get_memsize (GIMP_OBJECT (channel), NULL);
/* record the current position */
cu->prev_position = gimp_image_get_channel_index (undo->image,
channel);
gimp_container_remove (undo->image->channels, GIMP_OBJECT (channel));
gimp_item_removed (GIMP_ITEM (channel));
if (channel == gimp_image_get_active_channel (undo->image))
{
if (cu->prev_channel)
gimp_image_set_active_channel (undo->image, cu->prev_channel);
else
gimp_image_unset_active_channel (undo->image);
}
}
else
{
/* restore channel */
undo->size -= gimp_object_get_memsize (GIMP_OBJECT (channel), NULL);
/* record the active channel */
cu->prev_channel = gimp_image_get_active_channel (undo->image);
gimp_container_insert (undo->image->channels,
GIMP_OBJECT (channel), cu->prev_position);
gimp_image_set_active_channel (undo->image, channel);
GIMP_ITEM (channel)->removed = FALSE;
}
return TRUE;
}
static void
undo_free_channel (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
return gimp_image_undo_push (image, GIMP_TYPE_CHANNEL_UNDO,
0, 0,
GIMP_UNDO_CHANNEL_REMOVE, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", channel,
"prev-position", prev_position,
"prev-channel", prev_channel,
NULL);
}
@ -1196,31 +868,10 @@ gimp_image_undo_push_channel_color (GimpImage *image,
/* Add/Remove Vectors Undo */
/*****************************/
typedef struct _VectorsUndo VectorsUndo;
struct _VectorsUndo
{
gint prev_position; /* former position in list */
GimpVectors *prev_vectors; /* previous active vectors */
};
static GimpUndo * undo_push_vectors (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpVectors *vectors,
gint prev_position,
GimpVectors *prev_vectors);
static gboolean undo_pop_vectors (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void undo_free_vectors (GimpUndo *undo,
GimpUndoMode undo_mode);
GimpUndo *
gimp_image_undo_push_vectors_add (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors,
gint prev_position,
GimpVectors *prev_vectors)
{
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
@ -1229,8 +880,14 @@ gimp_image_undo_push_vectors_add (GimpImage *image,
g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors),
NULL);
return undo_push_vectors (image, undo_desc, GIMP_UNDO_VECTORS_ADD,
vectors, prev_position, prev_vectors);
return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO,
0, 0,
GIMP_UNDO_VECTORS_ADD, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", vectors,
"prev-vectors", prev_vectors,
NULL);
}
GimpUndo *
@ -1246,97 +903,15 @@ gimp_image_undo_push_vectors_remove (GimpImage *image,
g_return_val_if_fail (prev_vectors == NULL || GIMP_IS_VECTORS (prev_vectors),
NULL);
return undo_push_vectors (image, undo_desc, GIMP_UNDO_VECTORS_REMOVE,
vectors, prev_position, prev_vectors);
}
static GimpUndo *
undo_push_vectors (GimpImage *image,
const gchar *undo_desc,
GimpUndoType type,
GimpVectors *vectors,
gint prev_position,
GimpVectors *prev_vectors)
{
GimpUndo *new;
gint64 size;
size = sizeof (VectorsUndo);
if (type == GIMP_UNDO_VECTORS_REMOVE)
size += gimp_object_get_memsize (GIMP_OBJECT (vectors), NULL);
if ((new = gimp_image_undo_push (image, GIMP_TYPE_ITEM_UNDO,
size, sizeof (VectorsUndo),
type, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
undo_pop_vectors,
undo_free_vectors,
"item", vectors,
NULL)))
{
VectorsUndo *vu = new->data;
vu->prev_position = prev_position;
vu->prev_vectors = prev_vectors;
return new;
}
return NULL;
}
static gboolean
undo_pop_vectors (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
VectorsUndo *vu = undo->data;
GimpVectors *vectors = GIMP_VECTORS (GIMP_ITEM_UNDO (undo)->item);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_VECTORS_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_VECTORS_REMOVE))
{
/* remove vectors */
undo->size += gimp_object_get_memsize (GIMP_OBJECT (vectors), NULL);
/* record the current position */
vu->prev_position = gimp_image_get_vectors_index (undo->image,
vectors);
gimp_container_remove (undo->image->vectors, GIMP_OBJECT (vectors));
gimp_item_removed (GIMP_ITEM (vectors));
if (vectors == gimp_image_get_active_vectors (undo->image))
gimp_image_set_active_vectors (undo->image, vu->prev_vectors);
}
else
{
/* restore vectors */
undo->size -= gimp_object_get_memsize (GIMP_OBJECT (vectors), NULL);
/* record the active vectors */
vu->prev_vectors = gimp_image_get_active_vectors (undo->image);
gimp_container_insert (undo->image->vectors,
GIMP_OBJECT (vectors), vu->prev_position);
gimp_image_set_active_vectors (undo->image, vectors);
GIMP_ITEM (vectors)->removed = FALSE;
}
return TRUE;
}
static void
undo_free_vectors (GimpUndo *undo,
GimpUndoMode undo_mode)
{
g_free (undo->data);
return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_UNDO,
0, 0,
GIMP_UNDO_VECTORS_REMOVE, undo_desc,
GIMP_DIRTY_IMAGE_STRUCTURE,
NULL, NULL,
"item", vectors,
"prev-position", prev_position,
"prev-vectors", prev_vectors,
NULL);
}

View file

@ -45,7 +45,7 @@ GimpUndo * gimp_image_undo_push_sample_point (GimpImage *image,
GimpSamplePoint *sample_point);
/* drawable undo */
/* drawable undos */
GimpUndo * gimp_image_undo_push_drawable (GimpImage *image,
const gchar *undo_desc,
@ -89,7 +89,6 @@ GimpUndo * gimp_image_undo_push_item_linked (GimpImage *image,
GimpUndo * gimp_image_undo_push_layer_add (GimpImage *image,
const gchar *undo_desc,
GimpLayer *layer,
gint prev_position,
GimpLayer *prev_layer);
GimpUndo * gimp_image_undo_push_layer_remove (GimpImage *image,
const gchar *undo_desc,
@ -144,7 +143,6 @@ GimpUndo * gimp_image_undo_push_layer_mask_show (GimpImage *image,
GimpUndo * gimp_image_undo_push_channel_add (GimpImage *image,
const gchar *undo_desc,
GimpChannel *channel,
gint prev_position,
GimpChannel *prev_channel);
GimpUndo * gimp_image_undo_push_channel_remove (GimpImage *image,
const gchar *undo_desc,
@ -164,7 +162,6 @@ GimpUndo * gimp_image_undo_push_channel_color (GimpImage *image,
GimpUndo * gimp_image_undo_push_vectors_add (GimpImage *image,
const gchar *undo_desc,
GimpVectors *vectors,
gint prev_position,
GimpVectors *prev_vectors);
GimpUndo * gimp_image_undo_push_vectors_remove (GimpImage *image,
const gchar *undo_desc,

View file

@ -2814,7 +2814,7 @@ gimp_image_add_layer (GimpImage *image,
old_has_alpha = gimp_image_has_alpha (image);
gimp_image_undo_push_layer_add (image, _("Add Layer"),
layer, 0, active_layer);
layer, active_layer);
gimp_item_set_image (GIMP_ITEM (layer), image);
@ -3157,7 +3157,7 @@ gimp_image_add_channel (GimpImage *image,
active_channel = gimp_image_get_active_channel (image);
gimp_image_undo_push_channel_add (image, _("Add Channel"),
channel, 0, active_channel);
channel, active_channel);
gimp_item_set_image (GIMP_ITEM (channel), image);
@ -3409,7 +3409,7 @@ gimp_image_add_vectors (GimpImage *image,
active_vectors = gimp_image_get_active_vectors (image);
gimp_image_undo_push_vectors_add (image, _("Add Path"),
vectors, 0, active_vectors);
vectors, active_vectors);
gimp_item_set_image (GIMP_ITEM (vectors), image);

View file

@ -0,0 +1,210 @@
/* GIMP - The GNU 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.
*/
#include "config.h"
#include <glib-object.h>
#include "core-types.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayermask.h"
#include "gimplayermaskundo.h"
enum
{
PROP_0,
PROP_LAYER_MASK
};
static GObject * gimp_layer_mask_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_layer_mask_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_layer_mask_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_layer_mask_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_layer_mask_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void gimp_layer_mask_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode);
G_DEFINE_TYPE (GimpLayerMaskUndo, gimp_layer_mask_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_layer_mask_undo_parent_class
static void
gimp_layer_mask_undo_class_init (GimpLayerMaskUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructor = gimp_layer_mask_undo_constructor;
object_class->set_property = gimp_layer_mask_undo_set_property;
object_class->get_property = gimp_layer_mask_undo_get_property;
gimp_object_class->get_memsize = gimp_layer_mask_undo_get_memsize;
undo_class->pop = gimp_layer_mask_undo_pop;
undo_class->free = gimp_layer_mask_undo_free;
g_object_class_install_property (object_class, PROP_LAYER_MASK,
g_param_spec_object ("layer-mask", NULL, NULL,
GIMP_TYPE_LAYER_MASK,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_layer_mask_undo_init (GimpLayerMaskUndo *undo)
{
}
static GObject *
gimp_layer_mask_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GimpLayerMaskUndo *layer_mask_undo;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
layer_mask_undo = GIMP_LAYER_MASK_UNDO (object);
g_assert (GIMP_IS_LAYER (GIMP_ITEM_UNDO (object)->item));
g_assert (GIMP_IS_LAYER_MASK (layer_mask_undo->layer_mask));
return object;
}
static void
gimp_layer_mask_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLayerMaskUndo *layer_mask_undo = GIMP_LAYER_MASK_UNDO (object);
switch (property_id)
{
case PROP_LAYER_MASK:
layer_mask_undo->layer_mask = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_layer_mask_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLayerMaskUndo *layer_mask_undo = GIMP_LAYER_MASK_UNDO (object);
switch (property_id)
{
case PROP_LAYER_MASK:
g_value_set_object (value, layer_mask_undo->layer_mask);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_layer_mask_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpLayerMaskUndo *layer_mask_undo = GIMP_LAYER_MASK_UNDO (object);
GimpLayer *layer = GIMP_LAYER (GIMP_ITEM_UNDO (object)->item);
gint64 memsize = 0;
/* don't use !gimp_item_is_attached() here */
if (gimp_layer_get_mask (layer) != layer_mask_undo->layer_mask)
memsize += gimp_object_get_memsize (GIMP_OBJECT (layer_mask_undo->layer_mask),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_layer_mask_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpLayerMaskUndo *layer_mask_undo = GIMP_LAYER_MASK_UNDO (undo);
GimpLayer *layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_LAYER_MASK_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_LAYER_MASK_REMOVE))
{
/* remove layer mask */
gimp_layer_apply_mask (layer, GIMP_MASK_DISCARD, FALSE);
}
else
{
/* restore layer mask */
gimp_layer_add_mask (layer, layer_mask_undo->layer_mask, FALSE);
GIMP_ITEM (layer_mask_undo->layer_mask)->removed = FALSE;
}
}
static void
gimp_layer_mask_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode)
{
GimpLayerMaskUndo *layer_mask_undo = GIMP_LAYER_MASK_UNDO (undo);
if (layer_mask_undo->layer_mask)
{
g_object_unref (layer_mask_undo->layer_mask);
layer_mask_undo->layer_mask = NULL;
}
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
}

View file

@ -0,0 +1,52 @@
/* GIMP - The GNU 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 __GIMP_LAYER_MASK_UNDO_H__
#define __GIMP_LAYER_MASK_UNDO_H__
#include "gimpitemundo.h"
#define GIMP_TYPE_LAYER_MASK_UNDO (gimp_layer_mask_undo_get_type ())
#define GIMP_LAYER_MASK_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LAYER_MASK_UNDO, GimpLayerMaskUndo))
#define GIMP_LAYER_MASK_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LAYER_MASK_UNDO, GimpLayerMaskUndoClass))
#define GIMP_IS_LAYER_MASK_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LAYER_MASK_UNDO))
#define GIMP_IS_LAYER_MASK_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LAYER_MASK_UNDO))
#define GIMP_LAYER_MASK_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_LAYER_MASK_UNDO, GimpLayerMaskUndoClass))
typedef struct _GimpLayerMaskUndoClass GimpLayerMaskUndoClass;
struct _GimpLayerMaskUndo
{
GimpItemUndo parent_instance;
GimpLayerMask *layer_mask;
};
struct _GimpLayerMaskUndoClass
{
GimpItemUndoClass parent_class;
};
GType gimp_layer_mask_undo_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_LAYER_MASK_UNDO_H__ */

265
app/core/gimplayerundo.c Normal file
View file

@ -0,0 +1,265 @@
/* GIMP - The GNU 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.
*/
#include "config.h"
#include <glib-object.h>
#include "core-types.h"
#include "gimpcontainer.h"
#include "gimpimage.h"
#include "gimplayer.h"
#include "gimplayer-floating-sel.h"
#include "gimplayerundo.h"
enum
{
PROP_0,
PROP_PREV_POSITION,
PROP_PREV_LAYER
};
static GObject * gimp_layer_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
G_DEFINE_TYPE (GimpLayerUndo, gimp_layer_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_layer_undo_parent_class
static void
gimp_layer_undo_class_init (GimpLayerUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructor = gimp_layer_undo_constructor;
object_class->set_property = gimp_layer_undo_set_property;
object_class->get_property = gimp_layer_undo_get_property;
gimp_object_class->get_memsize = gimp_layer_undo_get_memsize;
undo_class->pop = gimp_layer_undo_pop;
g_object_class_install_property (object_class, PROP_PREV_POSITION,
g_param_spec_int ("prev-position", NULL, NULL,
0, G_MAXINT, 0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_LAYER,
g_param_spec_object ("prev-layer", NULL, NULL,
GIMP_TYPE_LAYER,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_layer_undo_init (GimpLayerUndo *undo)
{
}
static GObject *
gimp_layer_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GimpLayerUndo *layer_undo;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
layer_undo = GIMP_LAYER_UNDO (object);
g_assert (GIMP_IS_LAYER (GIMP_ITEM_UNDO (object)->item));
return object;
}
static void
gimp_layer_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpLayerUndo *layer_undo = GIMP_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
layer_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_LAYER:
layer_undo->prev_layer = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_layer_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpLayerUndo *layer_undo = GIMP_LAYER_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
g_value_set_int (value, layer_undo->prev_position);
break;
case PROP_PREV_LAYER:
g_value_set_object (value, layer_undo->prev_layer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_layer_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpItemUndo *item_undo = GIMP_ITEM_UNDO (object);
gint64 memsize = 0;
if (! gimp_item_is_attached (item_undo->item))
memsize += gimp_object_get_memsize (GIMP_OBJECT (item_undo->item),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_layer_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpLayerUndo *layer_undo = GIMP_LAYER_UNDO (undo);
GimpLayer *layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item);
gboolean old_has_alpha;
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
old_has_alpha = gimp_image_has_alpha (undo->image);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_LAYER_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_LAYER_REMOVE))
{
/* remove layer */
/* record the current position */
layer_undo->prev_position = gimp_image_get_layer_index (undo->image,
layer);
gimp_container_remove (undo->image->layers, GIMP_OBJECT (layer));
undo->image->layer_stack = g_slist_remove (undo->image->layer_stack,
layer);
if (gimp_layer_is_floating_sel (layer))
{
/* invalidate the boundary *before* setting the
* floating_sel pointer to NULL because the selection's
* outline is affected by the floating_sel and won't be
* completely cleared otherwise (bug #160247).
*/
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
undo->image->floating_sel = NULL;
/* activate the underlying drawable */
floating_sel_activate_drawable (layer);
gimp_image_floating_selection_changed (undo->image);
}
else if (layer == gimp_image_get_active_layer (undo->image))
{
if (layer_undo->prev_layer)
{
gimp_image_set_active_layer (undo->image, layer_undo->prev_layer);
}
else if (undo->image->layer_stack)
{
gimp_image_set_active_layer (undo->image,
undo->image->layer_stack->data);
}
else
{
gimp_image_set_active_layer (undo->image, NULL);
}
}
gimp_item_removed (GIMP_ITEM (layer));
}
else
{
/* restore layer */
/* record the active layer */
layer_undo->prev_layer = gimp_image_get_active_layer (undo->image);
/* if this is a floating selection, set the fs pointer */
if (gimp_layer_is_floating_sel (layer))
undo->image->floating_sel = layer;
gimp_container_insert (undo->image->layers,
GIMP_OBJECT (layer), layer_undo->prev_position);
gimp_image_set_active_layer (undo->image, layer);
if (gimp_layer_is_floating_sel (layer))
gimp_image_floating_selection_changed (undo->image);
GIMP_ITEM (layer)->removed = FALSE;
if (layer->mask)
GIMP_ITEM (layer->mask)->removed = FALSE;
}
if (old_has_alpha != gimp_image_has_alpha (undo->image))
accum->alpha_changed = TRUE;
}

53
app/core/gimplayerundo.h Normal file
View file

@ -0,0 +1,53 @@
/* GIMP - The GNU 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 __GIMP_LAYER_UNDO_H__
#define __GIMP_LAYER_UNDO_H__
#include "gimpitemundo.h"
#define GIMP_TYPE_LAYER_UNDO (gimp_layer_undo_get_type ())
#define GIMP_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LAYER_UNDO, GimpLayerUndo))
#define GIMP_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LAYER_UNDO, GimpLayerUndoClass))
#define GIMP_IS_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LAYER_UNDO))
#define GIMP_IS_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LAYER_UNDO))
#define GIMP_LAYER_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_LAYER_UNDO, GimpLayerUndoClass))
typedef struct _GimpLayerUndoClass GimpLayerUndoClass;
struct _GimpLayerUndo
{
GimpItemUndo parent_instance;
gint prev_position; /* former position in list */
GimpLayer *prev_layer; /* previous active layer */
};
struct _GimpLayerUndoClass
{
GimpItemUndoClass parent_class;
};
GType gimp_layer_undo_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_LAYER_UNDO_H__ */

View file

@ -39,6 +39,8 @@ libappvectors_a_SOURCES = \
gimpvectors-warp.c \
gimpvectors-warp.h \
gimpvectorspropundo.c \
gimpvectorspropundo.h
gimpvectorspropundo.h \
gimpvectorsundo.c \
gimpvectorsundo.h
EXTRA_DIST = makefile.msc

View file

@ -0,0 +1,217 @@
/* GIMP - The GNU 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.
*/
#include "config.h"
#include <glib-object.h>
#include "vectors-types.h"
#include "core/gimpcontainer.h"
#include "core/gimpimage.h"
#include "gimpvectors.h"
#include "gimpvectorsundo.h"
enum
{
PROP_0,
PROP_PREV_POSITION,
PROP_PREV_VECTORS
};
static GObject * gimp_vectors_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_vectors_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_vectors_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gint64 gimp_vectors_undo_get_memsize (GimpObject *object,
gint64 *gui_size);
static void gimp_vectors_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
G_DEFINE_TYPE (GimpVectorsUndo, gimp_vectors_undo, GIMP_TYPE_ITEM_UNDO)
#define parent_class gimp_vectors_undo_parent_class
static void
gimp_vectors_undo_class_init (GimpVectorsUndoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
object_class->constructor = gimp_vectors_undo_constructor;
object_class->set_property = gimp_vectors_undo_set_property;
object_class->get_property = gimp_vectors_undo_get_property;
gimp_object_class->get_memsize = gimp_vectors_undo_get_memsize;
undo_class->pop = gimp_vectors_undo_pop;
g_object_class_install_property (object_class, PROP_PREV_POSITION,
g_param_spec_int ("prev-position", NULL, NULL,
0, G_MAXINT, 0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PREV_VECTORS,
g_param_spec_object ("prev-vectors", NULL, NULL,
GIMP_TYPE_VECTORS,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_vectors_undo_init (GimpVectorsUndo *undo)
{
}
static GObject *
gimp_vectors_undo_constructor (GType type,
guint n_params,
GObjectConstructParam *params)
{
GObject *object;
GimpVectorsUndo *vectors_undo;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
vectors_undo = GIMP_VECTORS_UNDO (object);
g_assert (GIMP_IS_VECTORS (GIMP_ITEM_UNDO (object)->item));
return object;
}
static void
gimp_vectors_undo_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpVectorsUndo *vectors_undo = GIMP_VECTORS_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
vectors_undo->prev_position = g_value_get_int (value);
break;
case PROP_PREV_VECTORS:
vectors_undo->prev_vectors = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_vectors_undo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpVectorsUndo *vectors_undo = GIMP_VECTORS_UNDO (object);
switch (property_id)
{
case PROP_PREV_POSITION:
g_value_set_int (value, vectors_undo->prev_position);
break;
case PROP_PREV_VECTORS:
g_value_set_object (value, vectors_undo->prev_vectors);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gint64
gimp_vectors_undo_get_memsize (GimpObject *object,
gint64 *gui_size)
{
GimpItemUndo *item_undo = GIMP_ITEM_UNDO (object);
gint64 memsize = 0;
if (! gimp_item_is_attached (item_undo->item))
memsize += gimp_object_get_memsize (GIMP_OBJECT (item_undo->item),
gui_size);
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
gui_size);
}
static void
gimp_vectors_undo_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum)
{
GimpVectorsUndo *vectors_undo = GIMP_VECTORS_UNDO (undo);
GimpVectors *vectors = GIMP_VECTORS (GIMP_ITEM_UNDO (undo)->item);
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
if ((undo_mode == GIMP_UNDO_MODE_UNDO &&
undo->undo_type == GIMP_UNDO_VECTORS_ADD) ||
(undo_mode == GIMP_UNDO_MODE_REDO &&
undo->undo_type == GIMP_UNDO_VECTORS_REMOVE))
{
/* remove vectors */
/* record the current position */
vectors_undo->prev_position = gimp_image_get_vectors_index (undo->image,
vectors);
gimp_container_remove (undo->image->vectors, GIMP_OBJECT (vectors));
gimp_item_removed (GIMP_ITEM (vectors));
if (vectors == gimp_image_get_active_vectors (undo->image))
gimp_image_set_active_vectors (undo->image,
vectors_undo->prev_vectors);
}
else
{
/* restore vectors */
/* record the active vectors */
vectors_undo->prev_vectors = gimp_image_get_active_vectors (undo->image);
gimp_container_insert (undo->image->vectors, GIMP_OBJECT (vectors),
vectors_undo->prev_position);
gimp_image_set_active_vectors (undo->image, vectors);
GIMP_ITEM (vectors)->removed = FALSE;
}
}

View file

@ -0,0 +1,53 @@
/* GIMP - The GNU 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 __GIMP_VECTORS_UNDO_H__
#define __GIMP_VECTORS_UNDO_H__
#include "core/gimpitemundo.h"
#define GIMP_TYPE_VECTORS_UNDO (gimp_vectors_undo_get_type ())
#define GIMP_VECTORS_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTORS_UNDO, GimpVectorsUndo))
#define GIMP_VECTORS_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTORS_UNDO, GimpVectorsUndoClass))
#define GIMP_IS_VECTORS_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTORS_UNDO))
#define GIMP_IS_VECTORS_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTORS_UNDO))
#define GIMP_VECTORS_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTORS_UNDO, GimpVectorsUndoClass))
typedef struct _GimpVectorsUndoClass GimpVectorsUndoClass;
struct _GimpVectorsUndo
{
GimpItemUndo parent_instance;
gint prev_position; /* former position in list */
GimpVectors *prev_vectors; /* previous active vectors */
};
struct _GimpVectorsUndoClass
{
GimpItemUndoClass parent_class;
};
GType gimp_vectors_undo_get_type (void) G_GNUC_CONST;
#endif /* __GIMP_VECTORS_UNDO_H__ */

View file

@ -29,6 +29,7 @@
typedef struct _GimpAnchor GimpAnchor;
typedef struct _GimpVectors GimpVectors;
typedef struct _GimpVectorsUndo GimpVectorsUndo;
typedef struct _GimpVectorsPropUndo GimpVectorsPropUndo;
typedef struct _GimpStroke GimpStroke;
typedef struct _GimpBezierStroke GimpBezierStroke;