void edit_undo_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; return_if_no_image (image, data); if (gimp_image_undo (image)) gimp_image_flush (image); }
void edit_undo_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpDisplay *display; return_if_no_image (image, data); return_if_no_display (display, data); if (tool_manager_undo_active (image->gimp, display) || gimp_image_undo (image)) { gimp_image_flush (image); } }
gboolean gimp_edit_fade (GimpImage *image, GimpContext *context) { GimpDrawableUndo *undo; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (GIMP_IS_CONTEXT (context), FALSE); undo = GIMP_DRAWABLE_UNDO (gimp_image_undo_get_fadeable (image)); if (undo && undo->applied_buffer) { GimpDrawable *drawable; GeglBuffer *buffer; drawable = GIMP_DRAWABLE (GIMP_ITEM_UNDO (undo)->item); g_object_ref (undo); buffer = g_object_ref (undo->applied_buffer); gimp_image_undo (image); gimp_drawable_apply_buffer (drawable, buffer, GEGL_RECTANGLE (0, 0, gegl_buffer_get_width (undo->buffer), gegl_buffer_get_height (undo->buffer)), TRUE, gimp_object_get_name (undo), gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), GIMP_LAYER_COLOR_SPACE_AUTO, GIMP_LAYER_COLOR_SPACE_AUTO, GIMP_LAYER_COMPOSITE_AUTO, NULL, undo->x, undo->y); g_object_unref (buffer); g_object_unref (undo); return TRUE; } return FALSE; }
static void gimp_rectangle_select_tool_cancel (GimpRectangleTool *rectangle) { GimpTool *tool; GimpRectangleSelectTool *rect_sel_tool; GimpRectangleSelectToolPrivate *priv; tool = GIMP_TOOL (rectangle); rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (rectangle); priv = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool); if (tool->display) { GimpImage *image = gimp_display_get_image (tool->display); GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image); GimpUndo *undo = gimp_undo_stack_peek (undo_stack); /* if we have an existing rectangle in the current display, then * we have already "executed", and need to undo at this point, * unless the user has done something in the meantime */ if (undo && priv->undo == undo) { /* prevent this change from halting the tool */ gimp_tool_control_push_preserve (tool->control, TRUE); gimp_image_undo (image); gimp_image_flush (image); gimp_tool_control_pop_preserve (tool->control); } } gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, TRUE); priv->undo = NULL; priv->redo = NULL; }
static gboolean gimp_rectangle_select_tool_rectangle_change_complete (GimpRectangleTool *rectangle) { GimpTool *tool; GimpRectangleSelectTool *rect_sel_tool; GimpRectangleSelectToolPrivate *priv; tool = GIMP_TOOL (rectangle); rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (tool); priv = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool); /* prevent change in selection from halting the tool */ gimp_tool_control_push_preserve (tool->control, TRUE); if (tool->display && ! gimp_tool_control_is_active (tool->control)) { GimpImage *image = gimp_display_get_image (tool->display); GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image); GimpUndo *undo = gimp_undo_stack_peek (undo_stack); gint x1, y1, x2, y2; /* if we got here via button release, we have already undone the * previous operation. But if we got here by some other means, * we need to undo it now. */ if (undo && priv->undo == undo) { gimp_image_undo (image); priv->undo = NULL; } g_object_get (rectangle, "x1", &x1, "y1", &y1, "x2", &x2, "y2", &y2, NULL); if (gimp_rectangle_select_tool_select (rectangle, x1, y1, x2 - x1, y2 - y1)) { /* save the undo that we got when executing, but only if * we actually selected something */ priv->undo = gimp_undo_stack_peek (undo_stack); priv->redo = NULL; } if (! priv->use_saved_op) { GimpSelectionOptions *options; options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool); /* remember the operation now in case we modify the rectangle */ priv->operation = options->operation; priv->use_saved_op = TRUE; } gimp_image_flush (image); } gimp_tool_control_pop_preserve (tool->control); gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, FALSE); return TRUE; }
static void gimp_rectangle_select_tool_button_press (GimpTool *tool, const GimpCoords *coords, guint32 time, GdkModifierType state, GimpButtonPressType press_type, GimpDisplay *display) { GimpRectangleTool *rectangle; GimpRectangleSelectTool *rect_sel_tool; GimpDisplayShell *shell; GimpRectangleSelectToolPrivate *priv; GimpRectangleFunction function; rectangle = GIMP_RECTANGLE_TOOL (tool); rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (tool); shell = gimp_display_get_shell (display); priv = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool); if (tool->display && display != tool->display) { gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool)); } if (gimp_selection_tool_start_edit (GIMP_SELECTION_TOOL (tool), display, coords)) { /* In some cases we want to finish the rectangle select tool * and hand over responsability to the selection tool */ gimp_rectangle_tool_execute (rectangle); gimp_rectangle_tool_control (tool, GIMP_TOOL_ACTION_HALT, display); gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, TRUE); return; } gimp_tool_control_activate (tool->control); priv->saved_show_selection = gimp_display_shell_get_show_selection (shell); /* if the shift or ctrl keys are down, we don't want to adjust, we * want to create a new rectangle, regardless of pointer loc */ if (state & (gimp_get_extend_selection_mask () | gimp_get_modify_selection_mask ())) { gimp_rectangle_tool_set_function (rectangle, GIMP_RECTANGLE_TOOL_CREATING); } gimp_rectangle_tool_button_press (tool, coords, time, state, display); priv->press_x = coords->x; priv->press_y = coords->y; /* if we have an existing rectangle in the current display, then * we have already "executed", and need to undo at this point, * unless the user has done something in the meantime */ function = gimp_rectangle_tool_get_function (rectangle); if (function == GIMP_RECTANGLE_TOOL_CREATING) { priv->use_saved_op = FALSE; } else { GimpImage *image = gimp_display_get_image (tool->display); GimpUndoStack *undo_stack = gimp_image_get_undo_stack (image); GimpUndoStack *redo_stack = gimp_image_get_redo_stack (image); GimpUndo *undo; GimpChannelOps operation; undo = gimp_undo_stack_peek (undo_stack); if (undo && priv->undo == undo) { /* prevent this change from halting the tool */ gimp_tool_control_push_preserve (tool->control, TRUE); gimp_image_undo (image); gimp_tool_control_pop_preserve (tool->control); /* we will need to redo if the user cancels or executes */ priv->redo = gimp_undo_stack_peek (redo_stack); } /* if the operation is "Replace", turn off the marching ants, because they are confusing */ operation = gimp_rectangle_select_tool_get_operation (rect_sel_tool); if (operation == GIMP_CHANNEL_OP_REPLACE) gimp_display_shell_set_show_selection (shell, FALSE); } priv->undo = NULL; }
static void color_profile_dialog_response (GtkWidget *widget, gint response_id, ProfileDialog *dialog) { gboolean success = TRUE; GError *error = NULL; if (response_id == GTK_RESPONSE_OK) { GimpColorProfile *dest_profile = NULL; GFile *file; file = gimp_color_profile_combo_box_get_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (dialog->combo)); if (file) { dest_profile = gimp_color_profile_new_from_file (file, &error); if (! dest_profile) success = FALSE; g_object_unref (file); } else { dest_profile = g_object_ref (dialog->builtin_profile); } if (success) { switch (dialog->dialog_type) { case COLOR_PROFILE_DIALOG_ASSIGN_PROFILE: { gimp_image_undo_group_start (dialog->image, GIMP_UNDO_GROUP_PARASITE_ATTACH, _("Assign color profile")); success = gimp_image_set_color_profile (dialog->image, dest_profile, &error); if (success) { gimp_image_set_is_color_managed (dialog->image, TRUE, TRUE); /* omg... */ gimp_image_parasite_detach (dialog->image, "icc-profile-name"); } gimp_image_undo_group_end (dialog->image); if (! success) gimp_image_undo (dialog->image); } break; case COLOR_PROFILE_DIALOG_CONVERT_TO_PROFILE: { GimpProgress *progress; const gchar *label; label = gimp_color_profile_get_label (dest_profile); progress = gimp_progress_start (dialog->progress, FALSE, _("Converting to '%s'"), label); success = gimp_image_convert_color_profile (dialog->image, dest_profile, dialog->intent, dialog->bpc, progress, &error); if (progress) gimp_progress_end (progress); if (success) { saved_intent = dialog->intent; saved_bpc = dialog->bpc; } } break; case COLOR_PROFILE_DIALOG_CONVERT_TO_RGB: { GimpProgress *progress; const gchar *label; label = gimp_color_profile_get_label (dest_profile); progress = gimp_progress_start (dialog->progress, FALSE, _("Converting to RGB (%s)"), label); success = gimp_image_convert_type (dialog->image, GIMP_RGB, dest_profile, progress, &error); if (progress) gimp_progress_end (progress); } break; case COLOR_PROFILE_DIALOG_CONVERT_TO_GRAY: { GimpProgress *progress; const gchar *label; label = gimp_color_profile_get_label (dest_profile); progress = gimp_progress_start (dialog->progress, FALSE, _("Converting to grayscale (%s)"), label); success = gimp_image_convert_type (dialog->image, GIMP_GRAY, dest_profile, progress, &error); if (progress) gimp_progress_end (progress); } break; } if (success) gimp_image_flush (dialog->image); g_object_unref (dest_profile); } } if (success) { gtk_widget_destroy (dialog->dialog); } else { gimp_message (dialog->image->gimp, G_OBJECT (dialog->dialog), GIMP_MESSAGE_ERROR, "%s", error->message); g_clear_error (&error); } }