added GIMP_UNDO_EVENT_UNDO_FREEZE and GIMP_UNDO_EVENT_UNDO_THAW.
2003-11-25 Michael Natterer <mitch@gimp.org> * app/core/core-enums.[ch]: added GIMP_UNDO_EVENT_UNDO_FREEZE and GIMP_UNDO_EVENT_UNDO_THAW. * app/core/gimpimage.c: emit undo events in gimp_image_undo_freeze() and gimp_image_undo_thaw(). * app/widgets/gimpundoeditor.c: made it aware of FREEZE/THAW signals and robust against evil stuff like freezing/thawing the undo in the middle of an open undo group. Fixes bug #124421. * plug-ins/script-fu/scripts/circuit.scm: push and undo group instead of disabling/enabling undo.
This commit is contained in:
parent
74550b029c
commit
29ddc678d3
6 changed files with 167 additions and 93 deletions
15
ChangeLog
15
ChangeLog
|
|
@ -1,3 +1,18 @@
|
|||
2003-11-25 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/core/core-enums.[ch]: added GIMP_UNDO_EVENT_UNDO_FREEZE
|
||||
and GIMP_UNDO_EVENT_UNDO_THAW.
|
||||
|
||||
* app/core/gimpimage.c: emit undo events in
|
||||
gimp_image_undo_freeze() and gimp_image_undo_thaw().
|
||||
|
||||
* app/widgets/gimpundoeditor.c: made it aware of FREEZE/THAW signals
|
||||
and robust against evil stuff like freezing/thawing the undo
|
||||
in the middle of an open undo group. Fixes bug #124421.
|
||||
|
||||
* plug-ins/script-fu/scripts/circuit.scm: push and undo group
|
||||
instead of disabling/enabling undo.
|
||||
|
||||
2003-11-25 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/gui/dialogs.c (toplevel_entries): remember the size of the
|
||||
|
|
|
|||
|
|
@ -530,6 +530,8 @@ static const GEnumValue gimp_undo_event_enum_values[] =
|
|||
{ GIMP_UNDO_EVENT_UNDO, "GIMP_UNDO_EVENT_UNDO", "undo" },
|
||||
{ GIMP_UNDO_EVENT_REDO, "GIMP_UNDO_EVENT_REDO", "redo" },
|
||||
{ GIMP_UNDO_EVENT_UNDO_FREE, "GIMP_UNDO_EVENT_UNDO_FREE", "undo-free" },
|
||||
{ GIMP_UNDO_EVENT_UNDO_FREEZE, "GIMP_UNDO_EVENT_UNDO_FREEZE", "undo-freeze" },
|
||||
{ GIMP_UNDO_EVENT_UNDO_THAW, "GIMP_UNDO_EVENT_UNDO_THAW", "undo-thaw" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -370,7 +370,9 @@ typedef enum /*< pdb-skip >*/
|
|||
GIMP_UNDO_EVENT_REDO_EXPIRED, /* a redo has been freed from the redo stack */
|
||||
GIMP_UNDO_EVENT_UNDO, /* an undo has been executed */
|
||||
GIMP_UNDO_EVENT_REDO, /* a redo has been executed */
|
||||
GIMP_UNDO_EVENT_UNDO_FREE /* all undo and redo info has been cleared */
|
||||
GIMP_UNDO_EVENT_UNDO_FREE, /* all undo and redo info has been cleared */
|
||||
GIMP_UNDO_EVENT_UNDO_FREEZE, /* undo has been frozen */
|
||||
GIMP_UNDO_EVENT_UNDO_THAW /* undo has been thawn */
|
||||
} GimpUndoEvent;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1475,6 +1475,8 @@ gimp_image_undo_freeze (GimpImage *gimage)
|
|||
|
||||
gimage->undo_on = FALSE;
|
||||
|
||||
gimp_image_undo_event (gimage, GIMP_UNDO_EVENT_UNDO_FREEZE, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1485,6 +1487,8 @@ gimp_image_undo_thaw (GimpImage *gimage)
|
|||
|
||||
gimage->undo_on = TRUE;
|
||||
|
||||
gimp_image_undo_event (gimage, GIMP_UNDO_EVENT_UNDO_THAW, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1502,7 +1506,10 @@ gimp_image_undo_event (GimpImage *gimage,
|
|||
GimpUndo *undo)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
g_return_if_fail (event == GIMP_UNDO_EVENT_UNDO_FREE || GIMP_IS_UNDO (undo));
|
||||
g_return_if_fail (((event == GIMP_UNDO_EVENT_UNDO_FREE ||
|
||||
event == GIMP_UNDO_EVENT_UNDO_FREEZE ||
|
||||
event == GIMP_UNDO_EVENT_UNDO_THAW) && undo == NULL) ||
|
||||
GIMP_IS_UNDO (undo));
|
||||
|
||||
g_signal_emit (gimage, gimp_image_signals[UNDO_EVENT], 0, event, undo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ static void gimp_undo_editor_init (GimpUndoEditor *undo_editor);
|
|||
static void gimp_undo_editor_set_image (GimpImageEditor *editor,
|
||||
GimpImage *gimage);
|
||||
|
||||
static void gimp_undo_editor_fill (GimpUndoEditor *editor);
|
||||
static void gimp_undo_editor_clear (GimpUndoEditor *editor);
|
||||
|
||||
static void gimp_undo_editor_undo_clicked (GtkWidget *widget,
|
||||
GimpImageEditor *editor);
|
||||
static void gimp_undo_editor_redo_clicked (GtkWidget *widget,
|
||||
|
|
@ -138,19 +141,11 @@ static void
|
|||
gimp_undo_editor_set_image (GimpImageEditor *image_editor,
|
||||
GimpImage *gimage)
|
||||
{
|
||||
GimpUndoEditor *editor;
|
||||
|
||||
editor = GIMP_UNDO_EDITOR (image_editor);
|
||||
GimpUndoEditor *editor = GIMP_UNDO_EDITOR (image_editor);
|
||||
|
||||
if (image_editor->gimage)
|
||||
{
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (editor->view),
|
||||
NULL);
|
||||
g_object_unref (editor->container);
|
||||
editor->container = NULL;
|
||||
|
||||
g_object_unref (editor->base_item);
|
||||
editor->base_item = NULL;
|
||||
gimp_undo_editor_clear (editor);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (image_editor->gimage,
|
||||
gimp_undo_editor_undo_event,
|
||||
|
|
@ -159,78 +154,11 @@ gimp_undo_editor_set_image (GimpImageEditor *image_editor,
|
|||
|
||||
GIMP_IMAGE_EDITOR_CLASS (parent_class)->set_image (image_editor, gimage);
|
||||
|
||||
if (gimage)
|
||||
if (image_editor->gimage)
|
||||
{
|
||||
GimpUndo *top_undo_item;
|
||||
GimpUndo *top_redo_item;
|
||||
GList *list;
|
||||
gimp_undo_editor_fill (editor);
|
||||
|
||||
/* create a container as model for the undo history list */
|
||||
editor->container = gimp_list_new (GIMP_TYPE_UNDO,
|
||||
GIMP_CONTAINER_POLICY_STRONG);
|
||||
editor->base_item = gimp_undo_new (gimage,
|
||||
GIMP_UNDO_GROUP_NONE,
|
||||
_("[ Base Image ]"),
|
||||
NULL, 0, FALSE, NULL, NULL);
|
||||
|
||||
/* the list prepends its items, so first add the redo items... */
|
||||
for (list = GIMP_LIST (gimage->redo_stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (list->data));
|
||||
}
|
||||
|
||||
/* ...reverse the list so the redo items are in ascending order... */
|
||||
gimp_list_reverse (GIMP_LIST (editor->container));
|
||||
|
||||
/* ...then add the undo items in descending order... */
|
||||
for (list = GIMP_LIST (gimage->undo_stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (list->data));
|
||||
}
|
||||
|
||||
/* ...finally, the first item is the special "base_item" which stands
|
||||
* for the image with no more undos available to pop
|
||||
*/
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (editor->base_item));
|
||||
|
||||
/* display the container */
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (editor->view),
|
||||
editor->container);
|
||||
|
||||
/* get the top item of both stacks */
|
||||
top_undo_item = gimp_undo_stack_peek (gimage->undo_stack);
|
||||
top_redo_item = gimp_undo_stack_peek (gimage->redo_stack);
|
||||
|
||||
gtk_widget_set_sensitive (editor->undo_button, top_undo_item != NULL);
|
||||
gtk_widget_set_sensitive (editor->redo_button, top_redo_item != NULL);
|
||||
|
||||
g_signal_handlers_block_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
/* select the current state of the image */
|
||||
if (top_undo_item)
|
||||
{
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
GIMP_VIEWABLE (top_undo_item));
|
||||
gimp_undo_create_preview (top_undo_item, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
GIMP_VIEWABLE (editor->base_item));
|
||||
gimp_undo_create_preview (editor->base_item, TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
g_signal_connect (gimage, "undo_event",
|
||||
g_signal_connect (image_editor->gimage, "undo_event",
|
||||
G_CALLBACK (gimp_undo_editor_undo_event),
|
||||
editor);
|
||||
}
|
||||
|
|
@ -257,6 +185,107 @@ gimp_undo_editor_new (GimpImage *gimage)
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_undo_editor_fill (GimpUndoEditor *editor)
|
||||
{
|
||||
GimpImage *gimage;
|
||||
GimpUndo *top_undo_item;
|
||||
GimpUndo *top_redo_item;
|
||||
GList *list;
|
||||
|
||||
gimage = GIMP_IMAGE_EDITOR (editor)->gimage;
|
||||
|
||||
/* create a container as model for the undo history list */
|
||||
editor->container = gimp_list_new (GIMP_TYPE_UNDO,
|
||||
GIMP_CONTAINER_POLICY_STRONG);
|
||||
editor->base_item = gimp_undo_new (gimage,
|
||||
GIMP_UNDO_GROUP_NONE,
|
||||
_("[ Base Image ]"),
|
||||
NULL, 0, FALSE, NULL, NULL);
|
||||
|
||||
/* the list prepends its items, so first add the redo items... */
|
||||
for (list = GIMP_LIST (gimage->redo_stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (list->data));
|
||||
}
|
||||
|
||||
/* ...reverse the list so the redo items are in ascending order... */
|
||||
gimp_list_reverse (GIMP_LIST (editor->container));
|
||||
|
||||
/* ...then add the undo items in descending order... */
|
||||
for (list = GIMP_LIST (gimage->undo_stack->undos)->list;
|
||||
list;
|
||||
list = g_list_next (list))
|
||||
{
|
||||
/* Don't add the topmost item if it is an open undo group,
|
||||
* it will be added upon closing of the group.
|
||||
*/
|
||||
if (list->prev || ! GIMP_IS_UNDO_STACK (list->data) ||
|
||||
gimage->pushing_undo_group == GIMP_UNDO_GROUP_NONE)
|
||||
{
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (list->data));
|
||||
}
|
||||
}
|
||||
|
||||
/* ...finally, the first item is the special "base_item" which stands
|
||||
* for the image with no more undos available to pop
|
||||
*/
|
||||
gimp_container_add (editor->container, GIMP_OBJECT (editor->base_item));
|
||||
|
||||
/* display the container */
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (editor->view),
|
||||
editor->container);
|
||||
|
||||
/* get the top item of both stacks */
|
||||
top_undo_item = gimp_undo_stack_peek (gimage->undo_stack);
|
||||
top_redo_item = gimp_undo_stack_peek (gimage->redo_stack);
|
||||
|
||||
gtk_widget_set_sensitive (editor->undo_button, top_undo_item != NULL);
|
||||
gtk_widget_set_sensitive (editor->redo_button, top_redo_item != NULL);
|
||||
|
||||
g_signal_handlers_block_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
/* select the current state of the image */
|
||||
if (top_undo_item)
|
||||
{
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
GIMP_VIEWABLE (top_undo_item));
|
||||
gimp_undo_create_preview (top_undo_item, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
GIMP_VIEWABLE (editor->base_item));
|
||||
gimp_undo_create_preview (editor->base_item, TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_editor_clear (GimpUndoEditor *editor)
|
||||
{
|
||||
if (editor->container)
|
||||
{
|
||||
gimp_container_view_set_container (GIMP_CONTAINER_VIEW (editor->view),
|
||||
NULL);
|
||||
g_object_unref (editor->container);
|
||||
editor->container = NULL;
|
||||
}
|
||||
|
||||
if (editor->base_item)
|
||||
{
|
||||
g_object_unref (editor->base_item);
|
||||
editor->base_item = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_undo_editor_undo_clicked (GtkWidget *widget,
|
||||
GimpImageEditor *editor)
|
||||
|
|
@ -291,17 +320,21 @@ gimp_undo_editor_undo_event (GimpImage *gimage,
|
|||
top_undo_item = gimp_undo_stack_peek (gimage->undo_stack);
|
||||
top_redo_item = gimp_undo_stack_peek (gimage->redo_stack);
|
||||
|
||||
g_signal_handlers_block_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case GIMP_UNDO_EVENT_UNDO_PUSHED:
|
||||
g_signal_handlers_block_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
gimp_container_insert (editor->container, GIMP_OBJECT (undo), -1);
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
GIMP_VIEWABLE (undo));
|
||||
gimp_undo_create_preview (undo, FALSE);
|
||||
|
||||
g_signal_handlers_unblock_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_EVENT_UNDO_EXPIRED:
|
||||
|
|
@ -311,6 +344,10 @@ gimp_undo_editor_undo_event (GimpImage *gimage,
|
|||
|
||||
case GIMP_UNDO_EVENT_UNDO:
|
||||
case GIMP_UNDO_EVENT_REDO:
|
||||
g_signal_handlers_block_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
if (top_undo_item)
|
||||
{
|
||||
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (editor->view),
|
||||
|
|
@ -323,17 +360,25 @@ gimp_undo_editor_undo_event (GimpImage *gimage,
|
|||
GIMP_VIEWABLE (editor->base_item));
|
||||
gimp_undo_create_preview (editor->base_item, TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_EVENT_UNDO_FREE:
|
||||
gimp_image_editor_set_image (GIMP_IMAGE_EDITOR (editor), NULL);
|
||||
gimp_undo_editor_clear (editor);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_EVENT_UNDO_FREEZE:
|
||||
gimp_undo_editor_clear (editor);
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_EVENT_UNDO_THAW:
|
||||
gimp_undo_editor_fill (editor);
|
||||
break;
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (editor->view,
|
||||
gimp_undo_editor_select_item,
|
||||
editor);
|
||||
|
||||
gtk_widget_set_sensitive (editor->undo_button, top_undo_item != NULL);
|
||||
gtk_widget_set_sensitive (editor->redo_button, top_redo_item != NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@
|
|||
(old-fg (car (gimp-palette-get-foreground)))
|
||||
)
|
||||
|
||||
(gimp-image-undo-disable image)
|
||||
(gimp-undo-push-group-start image)
|
||||
|
||||
(gimp-layer-add-alpha drawable)
|
||||
|
||||
(if (= (car (gimp-selection-is-empty image)) TRUE)
|
||||
|
|
@ -116,9 +117,11 @@
|
|||
(if (= keep-selection FALSE)
|
||||
(gimp-selection-none image))
|
||||
|
||||
(gimp-image-undo-enable image)
|
||||
(gimp-image-remove-channel image active-selection)
|
||||
(gimp-image-set-active-layer image drawable)
|
||||
|
||||
(gimp-undo-push-group-end image)
|
||||
|
||||
(gimp-displays-flush)))
|
||||
|
||||
(script-fu-register "script-fu-circuit"
|
||||
|
|
|
|||
Loading…
Reference in a new issue