1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#include <glib-object.h>
25
#include "libgimpbase/gimpbase.h"
27
#include "core-types.h"
29
#include "base/temp-buf.h"
31
#include "config/gimpcoreconfig.h"
34
#include "gimpimage.h"
35
#include "gimpmarshal.h"
37
#include "gimpundostack.h"
39
#include "gimp-intl.h"
62
static void gimp_undo_class_init (GimpUndoClass *klass);
64
static GObject * gimp_undo_constructor (GType type,
66
GObjectConstructParam *params);
67
static void gimp_undo_finalize (GObject *object);
68
static void gimp_undo_set_property (GObject *object,
72
static void gimp_undo_get_property (GObject *object,
77
static gint64 gimp_undo_get_memsize (GimpObject *object,
80
static gboolean gimp_undo_get_popup_size (GimpViewable *viewable,
86
static TempBuf * gimp_undo_get_new_preview (GimpViewable *viewable,
90
static void gimp_undo_real_pop (GimpUndo *undo,
91
GimpUndoMode undo_mode,
92
GimpUndoAccumulator *accum);
93
static void gimp_undo_real_free (GimpUndo *undo,
94
GimpUndoMode undo_mode);
96
static gboolean gimp_undo_create_preview_idle (gpointer data);
97
static void gimp_undo_create_preview_private (GimpUndo *undo);
100
static guint undo_signals[LAST_SIGNAL] = { 0 };
102
static GimpViewableClass *parent_class = NULL;
106
gimp_undo_get_type (void)
108
static GType undo_type = 0;
112
static const GTypeInfo undo_info =
114
sizeof (GimpUndoClass),
115
(GBaseInitFunc) NULL,
116
(GBaseFinalizeFunc) NULL,
117
(GClassInitFunc) gimp_undo_class_init,
118
NULL, /* class_finalize */
119
NULL, /* class_data */
122
NULL /* instance_init */
125
undo_type = g_type_register_static (GIMP_TYPE_VIEWABLE,
134
gimp_undo_class_init (GimpUndoClass *klass)
136
GObjectClass *object_class = G_OBJECT_CLASS (klass);
137
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
138
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
140
parent_class = g_type_class_peek_parent (klass);
144
G_TYPE_FROM_CLASS (klass),
146
G_STRUCT_OFFSET (GimpUndoClass, pop),
148
gimp_marshal_VOID__ENUM_POINTER,
154
g_signal_new ("free",
155
G_TYPE_FROM_CLASS (klass),
157
G_STRUCT_OFFSET (GimpUndoClass, free),
159
gimp_marshal_VOID__ENUM,
161
GIMP_TYPE_UNDO_MODE);
163
object_class->constructor = gimp_undo_constructor;
164
object_class->finalize = gimp_undo_finalize;
165
object_class->set_property = gimp_undo_set_property;
166
object_class->get_property = gimp_undo_get_property;
168
gimp_object_class->get_memsize = gimp_undo_get_memsize;
170
viewable_class->default_stock_id = "gtk-undo";
171
viewable_class->get_popup_size = gimp_undo_get_popup_size;
172
viewable_class->get_new_preview = gimp_undo_get_new_preview;
174
klass->pop = gimp_undo_real_pop;
175
klass->free = gimp_undo_real_free;
177
g_object_class_install_property (object_class, PROP_IMAGE,
178
g_param_spec_object ("image", NULL, NULL,
181
G_PARAM_CONSTRUCT_ONLY));
183
g_object_class_install_property (object_class, PROP_UNDO_TYPE,
184
g_param_spec_enum ("undo-type", NULL, NULL,
186
GIMP_UNDO_GROUP_NONE,
188
G_PARAM_CONSTRUCT_ONLY));
190
g_object_class_install_property (object_class, PROP_DIRTY_MASK,
191
g_param_spec_flags ("dirty-mask",
193
GIMP_TYPE_DIRTY_MASK,
196
G_PARAM_CONSTRUCT_ONLY));
198
g_object_class_install_property (object_class, PROP_DATA,
199
g_param_spec_pointer ("data", NULL, NULL,
201
G_PARAM_CONSTRUCT_ONLY));
203
g_object_class_install_property (object_class, PROP_SIZE,
204
g_param_spec_int64 ("size", NULL, NULL,
209
g_object_class_install_property (object_class, PROP_POP_FUNC,
210
g_param_spec_pointer ("pop-func", NULL, NULL,
212
G_PARAM_CONSTRUCT_ONLY));
214
g_object_class_install_property (object_class, PROP_FREE_FUNC,
215
g_param_spec_pointer ("free-func", NULL, NULL,
217
G_PARAM_CONSTRUCT_ONLY));
221
gimp_undo_constructor (GType type,
223
GObjectConstructParam *params)
228
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
230
undo = GIMP_UNDO (object);
232
g_assert (GIMP_IS_IMAGE (undo->gimage));
234
undo->time = time (NULL);
240
gimp_undo_finalize (GObject *object)
242
GimpUndo *undo = GIMP_UNDO (object);
244
if (undo->preview_idle_id)
246
g_source_remove (undo->preview_idle_id);
247
undo->preview_idle_id = 0;
252
temp_buf_free (undo->preview);
253
undo->preview = NULL;
256
G_OBJECT_CLASS (parent_class)->finalize (object);
260
gimp_undo_set_property (GObject *object,
265
GimpUndo *undo = GIMP_UNDO (object);
271
undo->gimage = (GimpImage *) g_value_get_object (value);
274
undo->undo_type = g_value_get_enum (value);
276
case PROP_DIRTY_MASK:
277
undo->dirty_mask = g_value_get_flags (value);
280
undo->data = g_value_get_pointer (value);
283
undo->size = g_value_get_int64 (value);
286
undo->pop_func = g_value_get_pointer (value);
289
undo->free_func = g_value_get_pointer (value);
292
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
298
gimp_undo_get_property (GObject *object,
303
GimpUndo *undo = GIMP_UNDO (object);
308
g_value_set_object (value, undo->gimage);
311
g_value_set_enum (value, undo->undo_type);
313
case PROP_DIRTY_MASK:
314
g_value_set_flags (value, undo->dirty_mask);
317
g_value_set_pointer (value, undo->data);
320
g_value_set_int64 (value, undo->size);
323
g_value_set_pointer (value, undo->pop_func);
326
g_value_set_pointer (value, undo->free_func);
329
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
335
gimp_undo_get_memsize (GimpObject *object,
338
GimpUndo *undo = GIMP_UNDO (object);
339
gint64 memsize = undo->size;
342
*gui_size += temp_buf_get_memsize (undo->preview);
344
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
349
gimp_undo_get_popup_size (GimpViewable *viewable,
352
gboolean dot_for_dot,
356
GimpUndo *undo = GIMP_UNDO (viewable);
359
(undo->preview->width > width || undo->preview->height > height))
361
*popup_width = undo->preview->width;
362
*popup_height = undo->preview->height;
371
gimp_undo_get_new_preview (GimpViewable *viewable,
375
GimpUndo *undo = GIMP_UNDO (viewable);
382
gimp_viewable_calc_preview_size (undo->preview->width,
383
undo->preview->height,
391
if (preview_width < undo->preview->width &&
392
preview_height < undo->preview->height)
394
return temp_buf_scale (undo->preview, preview_width, preview_height);
397
return temp_buf_copy (undo->preview, NULL);
404
gimp_undo_real_pop (GimpUndo *undo,
405
GimpUndoMode undo_mode,
406
GimpUndoAccumulator *accum)
409
undo->pop_func (undo, undo_mode, accum);
413
gimp_undo_real_free (GimpUndo *undo,
414
GimpUndoMode undo_mode)
417
undo->free_func (undo, undo_mode);
421
gimp_undo_pop (GimpUndo *undo,
422
GimpUndoMode undo_mode,
423
GimpUndoAccumulator *accum)
425
g_return_if_fail (GIMP_IS_UNDO (undo));
426
g_return_if_fail (accum != NULL);
428
if (undo->dirty_mask != GIMP_DIRTY_NONE)
432
case GIMP_UNDO_MODE_UNDO:
433
gimp_image_clean (undo->gimage, undo->dirty_mask);
436
case GIMP_UNDO_MODE_REDO:
437
gimp_image_dirty (undo->gimage, undo->dirty_mask);
442
g_signal_emit (undo, undo_signals[POP], 0, undo_mode, accum);
446
gimp_undo_free (GimpUndo *undo,
447
GimpUndoMode undo_mode)
449
g_return_if_fail (GIMP_IS_UNDO (undo));
451
g_signal_emit (undo, undo_signals[FREE], 0, undo_mode);
455
gimp_undo_create_preview (GimpUndo *undo,
458
g_return_if_fail (GIMP_IS_UNDO (undo));
460
if (undo->preview || undo->preview_idle_id)
464
gimp_undo_create_preview_private (undo);
466
undo->preview_idle_id = g_idle_add (gimp_undo_create_preview_idle, undo);
470
gimp_undo_create_preview_idle (gpointer data)
472
GimpUndo *undo = GIMP_UNDO (data);
474
if (undo == gimp_undo_stack_peek (undo->gimage->undo_stack))
476
gimp_undo_create_preview_private (undo);
479
undo->preview_idle_id = 0;
485
gimp_undo_create_preview_private (GimpUndo *undo)
487
GimpImage *image = undo->gimage;
488
GimpViewable *preview_viewable;
489
GimpViewSize preview_size;
493
switch (undo->undo_type)
495
case GIMP_UNDO_GROUP_IMAGE_QMASK:
496
case GIMP_UNDO_GROUP_MASK:
498
preview_viewable = GIMP_VIEWABLE (gimp_image_get_mask (image));
502
preview_viewable = GIMP_VIEWABLE (image);
506
preview_size = image->gimp->config->undo_preview_size;
508
if (image->width <= preview_size && image->height <= preview_size)
510
width = image->width;
511
height = image->height;
515
if (image->width > image->height)
517
width = preview_size;
518
height = MAX (1, (image->height * preview_size / image->width));
522
height = preview_size;
523
width = MAX (1, (image->width * preview_size / image->height));
527
undo->preview = gimp_viewable_get_new_preview (preview_viewable,
530
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (undo));
534
gimp_undo_refresh_preview (GimpUndo *undo)
536
g_return_if_fail (GIMP_IS_UNDO (undo));
538
if (undo->preview_idle_id)
543
temp_buf_free (undo->preview);
544
undo->preview = NULL;
545
gimp_undo_create_preview (undo, FALSE);
550
gimp_undo_type_to_name (GimpUndoType type)
554
if (gimp_enum_get_value (GIMP_TYPE_UNDO_TYPE, type, NULL, NULL, &desc, NULL))