Updated my CVS. app/undo.c app/undo_history.c app/core/gimpimage.[ch]

2003-01-01 Garry R. Osgood <grosgood@rcn.com>
* MAINTAINERS: Updated my CVS.
* app/undo.c
* app/undo_history.c
* app/core/gimpimage.[ch]
* app/tools/gimpimagemaptool.c
* app/core/gimpimage-merge.c: implementation of LAYER_MERGE
signal emitters and listeners. (see bug #98843); listeners thaw
undo stack (image map tools, usually).
* app/widgets/gimpviewabledialog.c: gimp_viewable_dialog_close ()
Check if the widget has a non-null reference to a window before
using it to synthesize a cancel event. These seven deltas closes bug #98843.
* app/core/gimpimage-merge.c: (gimp_image_merge_layers())
Regardless of merge type, temporarily set composition mode
of bottom layer to NORMAL, then merge. Closes bug #101036.
This commit is contained in:
Garry R. Osgood 2003-01-01 23:40:53 +00:00 committed by Garry R. Osgood
parent 6cd51e1962
commit d8fd3b04c1
10 changed files with 117 additions and 32 deletions

View File

@ -1,3 +1,34 @@
2003-01-01 Garry R. Osgood <grosgood@rcn.com>
* MAINTAINERS: Updated my CVS.
* app/undo.c: Check if LayerUndo object provides a previous
layer before setting such active; in some cases the result of a
redo is an empty image, and prev_layer is not populated. Part of
bug # 98843.
* app/undo_history.c: undo_history_new () Increments reference
count on GimpImage in undo_history_st;
undo_history_shell_destroy_callback () dereferences. Before,
with undo history dialog active on application exit, the GimpImage
ref count would already be zero, with memory reclaimed, when
gimp_dialog_factory_dispose () invoked
undo_history_shell_destroy_callback (). See stack dumps in
bug # 98843; in part closes same.
* app/core/gimpimage-merge.c : gimp_image_merge_layers ()
Regardless of merge type, temporarily set composition mode
of bottom layer to NORMAL, then merge. Closes bug #101036.
Issues LAYER_MERGE signal (see bug #98843); listeners thaw
undo stack (image map tools, usually) in part closes this bug.
* app/core/gimpimage.[ch] Define and implement a LAYER_MERGE
signal.
* app/tools/gimpimagemaptool.c: gimp_image_map_tool_initialize ()
connects its associated GimpImage with dialog's cancel callback
via the GimpImage's LAYER_MERGE signal. gimp_image_map_tool_finalize ()
disconnects. Dismisses dialog in layer merges. In part closes
bug # 98843.
* app/widgets/gimpviewabledialog.c: gimp_viewable_dialog_close ()
Check if the widget has a non-null reference to a window before
using it to synthesize a cancel event.
2003-01-01 Sven Neumann <sven@gimp.org>
* app/gui/menus.c (image_entries): changed some menu entries as

View File

@ -170,14 +170,15 @@ current work:
commit access: yes
Name: Garry R. Osgood
Email: gosgood@idt.net
url: http://idt.net/~gosgood/
Email: grosgood@rcn.com
url: http://users.rcn.com/gosgood/
ircnick:
expertise: Bug fixing.
current work: I fell into this rabbit hole by writing highly verbose patch documentation,
which just goes to show that succinctness is its own reward. My patch documentation
archive is http://idt.net/~gosgood/gimp-patch/
archive is http://users.rcn.com/gosgood/gimp-patch/
commit access: yes
should be committed: Only when they catch me ;)
Name: David Monniaux
Email: monniaux@genievre.ens.fr

View File

@ -296,7 +296,12 @@ gimp_image_merge_layers (GimpImage *gimage,
if ((x2 - x1) == 0 || (y2 - y1) == 0)
return NULL;
/* Start a merge undo group */
/* Tell any listeners about impending layer merges */
gimp_image_layer_merge (gimage);
/* Start a merge undo group. */
undo_push_group_start (gimage, IMAGE_LAYERS_MERGE_UNDO_GROUP);
name = g_strdup (gimp_object_get_name (GIMP_OBJECT (layer)));
@ -376,22 +381,21 @@ gimp_image_merge_layers (GimpImage *gimage,
position =
gimp_container_num_children (gimage->layers) -
gimp_container_get_child_index (gimage->layers, GIMP_OBJECT (layer));
/* set the mode of the bottom layer to normal so that the contents
* aren't lost when merging with the all-alpha merge_layer
* Keep a pointer to it so that we can set the mode right after it's
* been merged so that undo works correctly.
*/
bottom_layer = layer;
bottom_mode = bottom_layer->mode;
/* DISSOLVE_MODE is special since it is the only mode that does not
* work on the projection with the lower layer, but only locally on
* the layers alpha channel.
*/
if (bottom_layer->mode != GIMP_DISSOLVE_MODE)
gimp_layer_set_mode (bottom_layer, GIMP_NORMAL_MODE);
}
/* set the mode of the bottom layer to normal so that the contents
* aren't lost when merging with the all-alpha merge_layer
* Keep a pointer to it so that we can set the mode right after it's
* been merged so that undo works correctly.
*/
bottom_layer = layer;
bottom_mode = bottom_layer->mode;
/* DISSOLVE_MODE is special since it is the only mode that does not
* work on the projection with the lower layer, but only locally on
* the layers alpha channel.
*/
if (bottom_layer->mode != GIMP_DISSOLVE_MODE)
gimp_layer_set_mode (bottom_layer, GIMP_NORMAL_MODE);
/* Copy the tattoo and parasites of the bottom layer to the new layer */
gimp_item_set_tattoo (GIMP_ITEM (merge_layer),

View File

@ -1684,8 +1684,11 @@ undo_pop_layer (GimpImage *gimage,
/* record the current position */
lu->prev_position = gimp_image_get_layer_index (gimage, lu->layer);
/* set the previous layer */
gimp_image_set_active_layer (gimage, lu->prev_layer);
/* if exists, set the previous layer */
/* (counterexample: result layer added after a merge op has no previous layer.) */
if(GIMP_IS_LAYER (lu->prev_layer))
gimp_image_set_active_layer (gimage, lu->prev_layer);
/* remove the layer */
gimp_container_remove (gimage->layers, GIMP_OBJECT (lu->layer));

View File

@ -84,7 +84,6 @@ enum
UNIT_CHANGED,
QMASK_CHANGED,
SELECTION_CONTROL,
CLEAN,
DIRTY,
UPDATE,
@ -92,6 +91,7 @@ enum
COLORMAP_CHANGED,
UNDO_EVENT,
FLUSH,
LAYER_MERGE,
LAST_SIGNAL
};
@ -375,6 +375,15 @@ gimp_image_class_init (GimpImageClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gimp_image_signals[LAYER_MERGE] =
g_signal_new ("layer_merge",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpImageClass, layer_merge),
NULL, NULL,
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
object_class->dispose = gimp_image_dispose;
object_class->finalize = gimp_image_finalize;
@ -404,6 +413,8 @@ gimp_image_class_init (GimpImageClass *klass)
klass->undo_event = NULL;
klass->undo = gimp_image_undo;
klass->redo = gimp_image_redo;
klass->flush = NULL;
klass->layer_merge = NULL;
gimp_image_color_hash_init ();
}
@ -1646,6 +1657,16 @@ gimp_image_flush (GimpImage *gimage)
g_signal_emit (G_OBJECT (gimage), gimp_image_signals[FLUSH], 0);
}
/* Post notification of a layer merge */
void
gimp_image_layer_merge (GimpImage *gimage)
{
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_signal_emit (G_OBJECT (gimage), gimp_image_signals[LAYER_MERGE], 0);
}
/* color transforms / utilities */

View File

@ -207,6 +207,7 @@ struct _GimpImageClass
void (* redo) (GimpImage *gimage);
void (* flush) (GimpImage *gimage);
void (* layer_merge) (GimpImage *gimage);
};
@ -314,6 +315,10 @@ void gimp_image_clean_all (GimpImage *gimage);
void gimp_image_flush (GimpImage *gimage);
/* Post notification of layer mergers */
void gimp_image_layer_merge (GimpImage *gimage);
/* color transforms / utilities */

View File

@ -172,6 +172,11 @@ gimp_image_map_tool_finalize (GObject *object)
gtk_widget_destroy (image_map_tool->shell);
image_map_tool->shell = NULL;
image_map_tool->main_vbox = NULL;
g_signal_handlers_disconnect_by_func (
gimp_item_get_image (GIMP_ITEM (image_map_tool->drawable)),
gimp_image_map_tool_cancel_clicked,
image_map_tool
);
}
G_OBJECT_CLASS (parent_class)->finalize (object);
@ -256,6 +261,10 @@ gimp_image_map_tool_initialize (GimpTool *tool,
G_CALLBACK (gimp_image_map_tool_flush),
image_map_tool);
g_signal_connect (G_OBJECT (gdisp->gimage), "layer_merge",
G_CALLBACK (gimp_image_map_tool_cancel_clicked),
image_map_tool);
gimp_display_shell_set_menu_sensitivity (GIMP_DISPLAY_SHELL (gdisp->shell),
gdisp->gimage->gimp, FALSE);
}

View File

@ -1684,8 +1684,11 @@ undo_pop_layer (GimpImage *gimage,
/* record the current position */
lu->prev_position = gimp_image_get_layer_index (gimage, lu->layer);
/* set the previous layer */
gimp_image_set_active_layer (gimage, lu->prev_layer);
/* if exists, set the previous layer */
/* (counterexample: result layer added after a merge op has no previous layer.) */
if(GIMP_IS_LAYER (lu->prev_layer))
gimp_image_set_active_layer (gimage, lu->prev_layer);
/* remove the layer */
gimp_container_remove (gimage->layers, GIMP_OBJECT (lu->layer));

View File

@ -493,6 +493,8 @@ undo_history_shell_destroy_callback (GtkWidget *widget,
g_signal_handlers_disconnect_by_func (G_OBJECT (st->gimage),
undo_history_clean_callback,
st);
g_object_unref(G_OBJECT(st->gimage));
}
g_free (st);
@ -784,6 +786,7 @@ undo_history_new (GimpImage *gimage)
st = g_new0 (undo_history_st, 1);
st->gimage = gimage;
g_object_ref(G_OBJECT(gimage));
st->preview_size = gimage->gimp->config->preview_size;
/* gimage signals */

View File

@ -339,16 +339,21 @@ gimp_viewable_dialog_close (GimpViewableDialog *dialog)
GdkEventAny event;
widget = GTK_WIDGET (dialog);
/* Paranoia: Widget realized in a window? */
if(G_IS_OBJECT (widget->window) == TRUE)
{
/* Synthesize delete_event to close dialog. */
/* Synthesize delete_event to close dialog. */
event.type = GDK_DELETE;
event.window = widget->window;
event.send_event = TRUE;
event.type = GDK_DELETE;
event.window = widget->window;
event.send_event = TRUE;
g_object_ref (G_OBJECT (event.window));
g_object_ref (G_OBJECT (event.window));
gtk_main_do_event ((GdkEvent *) &event);
gtk_main_do_event ((GdkEvent *) &event);
g_object_unref (G_OBJECT (event.window));
g_object_unref (G_OBJECT (event.window));
}
}