static void gimp_drawable_tree_view_new_dropped (GimpItemTreeView *view, gint x, gint y, const GimpRGB *color, GimpPattern *pattern) { GimpItem *item; gimp_image_undo_group_start (gimp_item_tree_view_get_image (view), GIMP_UNDO_GROUP_EDIT_PASTE, _("New Layer")); item = GIMP_ITEM_TREE_VIEW_GET_CLASS (view)->new_item (gimp_item_tree_view_get_image (view)); if (item) { gimp_edit_fill_full (gimp_item_get_image (item), GIMP_DRAWABLE (item), color, pattern, GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE, pattern ? C_("undo-type", "Drop pattern to layer") : C_("undo-type", "Drop color to layer")); } gimp_image_undo_group_end (gimp_item_tree_view_get_image (view)); gimp_image_flush (gimp_item_tree_view_get_image (view)); }
void gimp_item_rotate (GimpItem *item, GimpContext *context, GimpRotationType rotate_type, gdouble center_x, gdouble center_y, gboolean clip_result) { GimpItemClass *item_class; GimpImage *image; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (gimp_item_is_attached (item)); g_return_if_fail (GIMP_IS_CONTEXT (context)); item_class = GIMP_ITEM_GET_CLASS (item); image = gimp_item_get_image (item); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, item_class->rotate_desc); item_class->rotate (item, context, rotate_type, center_x, center_y, clip_result); gimp_image_undo_group_end (image); }
static void gimp_text_layer_set_buffer (GimpDrawable *drawable, gboolean push_undo, const gchar *undo_desc, GeglBuffer *buffer, gint offset_x, gint offset_y) { GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable); GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); if (push_undo && ! layer->modified) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD, undo_desc); GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable, push_undo, undo_desc, buffer, offset_x, offset_y); if (push_undo && ! layer->modified) { gimp_image_undo_push_text_layer_modified (image, NULL, layer); g_object_set (drawable, "modified", TRUE, NULL); gimp_image_undo_group_end (image); } }
/** * gimp_item_translate: * @item: The #GimpItem to move. * @offset_x: Increment to the X offset of the item. * @offset_y: Increment to the Y offset of the item. * @push_undo: If #TRUE, create an entry in the image's undo stack * for this action. * * Adds the specified increments to the X and Y offsets for the item. */ void gimp_item_translate (GimpItem *item, gint offset_x, gint offset_y, gboolean push_undo) { GimpItemClass *item_class; GimpImage *image; g_return_if_fail (GIMP_IS_ITEM (item)); item_class = GIMP_ITEM_GET_CLASS (item); image = gimp_item_get_image (item); if (! gimp_item_is_attached (item)) push_undo = FALSE; if (push_undo) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, item_class->translate_desc); item_class->translate (item, offset_x, offset_y, push_undo); if (push_undo) gimp_image_undo_group_end (image); }
void floating_sel_remove (GimpLayer *layer) { GimpImage *image; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (gimp_layer_is_floating_sel (layer)); image = gimp_item_get_image (GIMP_ITEM (layer->fs.drawable)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_REMOVE, _("Remove Floating Selection")); /* store the affected area from the drawable in the backing store */ floating_sel_relax (layer, TRUE); /* Invalidate the preview of the obscured drawable. We do this here * because it will not be done until the floating selection is removed, * at which point the obscured drawable's preview will not be declared * invalid. */ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer)); /* remove the layer from the image */ gimp_image_remove_layer (image, layer); gimp_image_undo_group_end (image); }
void gimp_item_transform (GimpItem *item, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation, gint recursion_level, GimpTransformResize clip_result, GimpProgress *progress) { GimpItemClass *item_class; GimpImage *image; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (gimp_item_is_attached (item)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (matrix != NULL); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); item_class = GIMP_ITEM_GET_CLASS (item); image = gimp_item_get_image (item); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, item_class->transform_desc); item_class->transform (item, context, matrix, direction, interpolation, recursion_level, clip_result, progress); gimp_image_undo_group_end (image); }
void gimp_image_item_list_transform (GimpImage *image, GList *list, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation_type, GimpTransformResize clip_result, GimpProgress *progress) { g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (list) { GList *l; if (list->next) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Transform Items")); for (l = list; l; l = g_list_next (l)) gimp_item_transform (GIMP_ITEM (l->data), context, matrix, direction, interpolation_type, clip_result, progress); if (list->next) gimp_image_undo_group_end (image); } }
void gimp_image_item_list_translate (GimpImage *image, GList *list, gint offset_x, gint offset_y, gboolean push_undo) { g_return_if_fail (GIMP_IS_IMAGE (image)); if (list) { GList *l; if (push_undo && list->next) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_DISPLACE, C_("undo-type", "Translate Items")); for (l = list; l; l = g_list_next (l)) gimp_item_translate (GIMP_ITEM (l->data), offset_x, offset_y, push_undo); if (push_undo && list->next) gimp_image_undo_group_end (image); } }
GimpLayer * gimp_image_merge_group_layer (GimpImage *image, GimpGroupLayer *group) { GimpLayer *parent; GimpLayer *layer; gint index; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_GROUP_LAYER (group), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (group)), NULL); g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (group)) == image, NULL); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, C_("undo-type", "Merge Layer Group")); parent = gimp_layer_get_parent (GIMP_LAYER (group)); index = gimp_item_get_index (GIMP_ITEM (group)); layer = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (group), GIMP_TYPE_LAYER)); gimp_object_set_name (GIMP_OBJECT (layer), gimp_object_get_name (group)); gimp_image_remove_layer (image, GIMP_LAYER (group), TRUE, NULL); gimp_image_add_layer (image, layer, parent, index, TRUE); gimp_image_undo_group_end (image); return layer; }
void gimp_item_scale (GimpItem *item, gint new_width, gint new_height, gint new_offset_x, gint new_offset_y, GimpInterpolationType interpolation, GimpProgress *progress) { GimpItemClass *item_class; GimpImage *image; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (new_width < 1 || new_height < 1) return; item_class = GIMP_ITEM_GET_CLASS (item); image = gimp_item_get_image (item); if (gimp_item_is_attached (item)) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_SCALE, item_class->scale_desc); item_class->scale (item, new_width, new_height, new_offset_x, new_offset_y, interpolation, progress); if (gimp_item_is_attached (item)) gimp_image_undo_group_end (image); }
void gimp_item_resize (GimpItem *item, GimpContext *context, gint new_width, gint new_height, gint offset_x, gint offset_y) { GimpItemClass *item_class; GimpImage *image; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (GIMP_IS_CONTEXT (context)); if (new_width < 1 || new_height < 1) return; item_class = GIMP_ITEM_GET_CLASS (item); image = gimp_item_get_image (item); if (gimp_item_is_attached (item)) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_RESIZE, item_class->resize_desc); item_class->resize (item, context, new_width, new_height, offset_x, offset_y); if (gimp_item_is_attached (item)) gimp_image_undo_group_end (image); }
static void gimp_text_layer_push_undo (GimpDrawable *drawable, const gchar *undo_desc, GeglBuffer *buffer, gint x, gint y, gint width, gint height) { GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable); GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); if (! layer->modified) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc); GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc, buffer, x, y, width, height); if (! layer->modified) { gimp_image_undo_push_text_layer_modified (image, NULL, layer); g_object_set (drawable, "modified", TRUE, NULL); gimp_image_undo_group_end (image); } }
void callback_edit_mask_button (GtkWidget * button, gpointer data) { NewLayerData *nl_data = NEW_LAYER_DATA (data); PreviewData *p_data = nl_data->preview_data; gint32 layer_ID = *(nl_data->layer_ID); IMAGE_CHECK_ACTION(p_data->image_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_FATAL), ); LAYER_CHECK_ACTION(layer_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_REFRESH), ); if (*(nl_data->status) != TRUE) { g_message ("You just found a bug!"); return; } gimp_image_undo_group_start (p_data->image_ID); gimp_image_set_active_layer(p_data->image_ID, layer_ID); gimp_image_undo_group_end (p_data->image_ID); nl_data->preview_data->ui_vals->layer_on_edit_ID = layer_ID; nl_data->preview_data->ui_vals->layer_on_edit_type = nl_data->layer_type; nl_data->preview_data->ui_vals->layer_on_edit_is_new = FALSE; gtk_dialog_response (GTK_DIALOG(dlg), RESPONSE_WORK_ON_AUX_LAYER); }
static GValueArray * image_undo_group_start_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GValueArray *args, GError **error) { gboolean success = TRUE; GimpImage *image; image = gimp_value_get_image (&args->values[0], gimp); if (success) { GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in; const gchar *undo_desc = NULL; if (plug_in) { success = gimp_plug_in_cleanup_undo_group_start (plug_in, image); if (success) undo_desc = gimp_plug_in_get_undo_desc (plug_in); } if (success) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_MISC, undo_desc); } return gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); }
static void callback_alarm_triggered (GtkWidget * size_entry, gpointer data) { gint new_width, new_height; gboolean render_success; InterfaceIData *p_data = INTERFACE_I_DATA (data); CarverData *c_data = p_data->carver_data; //gtk_widget_set_sensitive (p_data->size_frame, FALSE); new_width = ROUND (alt_size_entry_get_refval (ALT_SIZE_ENTRY (size_entry), 0)); new_height = ROUND (alt_size_entry_get_refval (ALT_SIZE_ENTRY (size_entry), 1)); state->new_width = new_width; state->new_height = new_height; gimp_image_undo_group_start (c_data->image_ID); render_success = render_interactive (state, p_data->carver_data); gimp_image_undo_group_end (c_data->image_ID); /* p_data->drawable_vals->layer_ID = c_data->layer_ID; */ if (!render_success) { dialog_I_response = RESPONSE_FATAL; gtk_main_quit(); } gimp_displays_flush(); set_info_label_text (p_data); //set_info_label_text (p_data->info_label, c_data->ref_w, c_data->ref_h, c_data->orientation, c_data->depth, c_data->enl_step); //gtk_widget_set_sensitive (p_data->dump_button, (c_data->depth != 0)); //gtk_widget_set_sensitive (p_data->size_frame, TRUE); }
static void image_scale_callback (GtkWidget *dialog, GimpViewable *viewable, gint width, gint height, GimpUnit unit, GimpInterpolationType interpolation, gdouble xresolution, gdouble yresolution, GimpUnit resolution_unit, gpointer user_data) { GimpImage *image = GIMP_IMAGE (viewable); gdouble xres; gdouble yres; image_scale_unit = unit; image_scale_interp = interpolation; gimp_image_get_resolution (image, &xres, &yres); if (width > 0 && height > 0) { if (width == gimp_image_get_width (image) && height == gimp_image_get_height (image) && xresolution == xres && yresolution == yres && resolution_unit == gimp_image_get_unit (image)) return; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE, _("Scale Image")); gimp_image_set_resolution (image, xresolution, yresolution); gimp_image_set_unit (image, resolution_unit); if (width != gimp_image_get_width (image) || height != gimp_image_get_height (image)) { GimpProgress *progress; progress = gimp_progress_start (GIMP_PROGRESS (user_data), _("Scaling"), FALSE); gimp_image_scale (image, width, height, interpolation, progress); if (progress) gimp_progress_end (progress); } gimp_image_undo_group_end (image); gimp_image_flush (image); } else { g_warning ("Scale Error: " "Both width and height must be greater than zero."); } }
static void image_print_size_callback (GtkWidget *dialog, GimpImage *image, gdouble xresolution, gdouble yresolution, GimpUnit resolution_unit, gpointer data) { gdouble xres; gdouble yres; gtk_widget_destroy (dialog); gimp_image_get_resolution (image, &xres, &yres); if (xresolution == xres && yresolution == yres && resolution_unit == gimp_image_get_unit (image)) return; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_SCALE, _("Change Print Size")); gimp_image_set_resolution (image, xresolution, yresolution); gimp_image_set_unit (image, resolution_unit); gimp_image_undo_group_end (image); gimp_image_flush (image); }
void gimp_image_item_list_rotate (GimpImage *image, GList *list, GimpContext *context, GimpRotationType rotate_type, gdouble center_x, gdouble center_y, gboolean clip_result) { g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); if (list) { GList *l; if (list->next) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Rotate Items")); for (l = list; l; l = g_list_next (l)) gimp_item_rotate (GIMP_ITEM (l->data), context, rotate_type, center_x, center_y, clip_result); if (list->next) gimp_image_undo_group_end (image); } }
static void gimp_display_shell_drop_component (GtkWidget *widget, gint x, gint y, GimpImage *image, GimpChannelType component, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *dest_image = gimp_display_get_image (shell->display); GimpChannel *channel; GimpItem *new_item; const gchar *desc; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! dest_image) { dest_image = gimp_image_new_from_component (image->gimp, image, component); gimp_create_display (dest_image->gimp, dest_image, GIMP_UNIT_PIXEL, 1.0, G_OBJECT (gtk_widget_get_screen (widget)), gimp_widget_get_monitor (widget)); g_object_unref (dest_image); return; } channel = gimp_channel_new_from_component (image, component, NULL, NULL); new_item = gimp_item_convert (GIMP_ITEM (channel), dest_image, GIMP_TYPE_LAYER); g_object_unref (channel); if (new_item) { GimpLayer *new_layer = GIMP_LAYER (new_item); gimp_enum_get_value (GIMP_TYPE_CHANNEL_TYPE, component, NULL, NULL, &desc, NULL); gimp_object_take_name (GIMP_OBJECT (new_layer), g_strdup_printf (_("%s Channel Copy"), desc)); gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE, _("Drop New Layer")); gimp_display_shell_dnd_position_item (shell, image, new_item); gimp_image_add_layer (dest_image, new_layer, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE); gimp_image_undo_group_end (dest_image); gimp_display_shell_dnd_flush (shell, dest_image); } }
void gimp_image_item_list_transform (GimpImage *image, GList *list, GimpContext *context, const GimpMatrix3 *matrix, GimpTransformDirection direction, GimpInterpolationType interpolation_type, GimpTransformResize clip_result, GimpProgress *progress) { g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (list) { GimpObjectQueue *queue = NULL; GList *l; if (progress) { queue = gimp_object_queue_new (progress); progress = GIMP_PROGRESS (queue); gimp_object_queue_push_list (queue, list); } if (list->next) { gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM, C_("undo-type", "Transform Items")); for (l = list; l; l = g_list_next (l)) gimp_item_start_transform (GIMP_ITEM (l->data), TRUE); } for (l = list; l; l = g_list_next (l)) { if (queue) gimp_object_queue_pop (queue); gimp_item_transform (GIMP_ITEM (l->data), context, matrix, direction, interpolation_type, clip_result, progress); } if (list->next) { for (l = list; l; l = g_list_next (l)) gimp_item_end_transform (GIMP_ITEM (l->data), TRUE); gimp_image_undo_group_end (image); } g_clear_object (&queue); } }
static void gimp_display_shell_drop_pixbuf (GtkWidget *widget, gint x, gint y, GdkPixbuf *pixbuf, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *image = gimp_display_get_image (shell->display); GimpLayer *new_layer; gboolean has_alpha = FALSE; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! image) { image = gimp_image_new_from_pixbuf (shell->display->gimp, pixbuf, _("Dropped Buffer")); gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0, G_OBJECT (gtk_widget_get_screen (widget)), gimp_widget_get_monitor (widget)); g_object_unref (image); return; } if (gdk_pixbuf_get_n_channels (pixbuf) == 2 || gdk_pixbuf_get_n_channels (pixbuf) == 4) { has_alpha = TRUE; } new_layer = gimp_layer_new_from_pixbuf (pixbuf, image, gimp_image_get_layer_format (image, has_alpha), _("Dropped Buffer"), GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); if (new_layer) { GimpItem *new_item = GIMP_ITEM (new_layer); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, _("Drop New Layer")); gimp_display_shell_dnd_position_item (shell, image, new_item); gimp_image_add_layer (image, new_layer, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE); gimp_image_undo_group_end (image); gimp_display_shell_dnd_flush (shell, image); } }
void gimp_item_parasite_attach (GimpItem *item, const GimpParasite *parasite) { GimpParasite copy; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (parasite != NULL); /* make a temporary copy of the GimpParasite struct because * gimp_parasite_shift_parent() changes it */ copy = *parasite; if (gimp_item_is_attached (item)) { /* only set the dirty bit manually if we can be saved and the new * parasite differs from the current one and we aren't undoable */ if (gimp_parasite_is_undoable (©)) { /* do a group in case we have attach_parent set */ gimp_image_undo_group_start (item->image, GIMP_UNDO_GROUP_PARASITE_ATTACH, _("Attach Parasite")); gimp_image_undo_push_item_parasite (item->image, NULL, item, ©); } else if (gimp_parasite_is_persistent (©) && ! gimp_parasite_compare (©, gimp_item_parasite_find (item, gimp_parasite_name (©)))) { gimp_image_undo_push_cantundo (item->image, _("Attach Parasite to Item")); } } gimp_parasite_list_add (item->parasites, ©); if (gimp_parasite_has_flag (©, GIMP_PARASITE_ATTACH_PARENT)) { gimp_parasite_shift_parent (©); gimp_image_parasite_attach (item->image, ©); } else if (gimp_parasite_has_flag (©, GIMP_PARASITE_ATTACH_GRANDPARENT)) { gimp_parasite_shift_parent (©); gimp_parasite_shift_parent (©); gimp_parasite_attach (item->image->gimp, ©); } if (gimp_item_is_attached (item) && gimp_parasite_is_undoable (©)) { gimp_image_undo_group_end (item->image); } }
GimpLayer * gimp_image_flatten (GimpImage *image, GimpContext *context, GError **error) { GList *list; GSList *merge_list = NULL; GimpLayer *layer; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); for (list = gimp_image_get_layer_iter (image); list; list = g_list_next (list)) { layer = list->data; if (gimp_layer_is_floating_sel (layer)) continue; if (gimp_item_get_visible (GIMP_ITEM (layer))) merge_list = g_slist_append (merge_list, layer); } if (merge_list) { gimp_set_busy (image->gimp); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, C_("undo-type", "Flatten Image")); /* if there's a floating selection, anchor it */ if (gimp_image_get_floating_selection (image)) floating_sel_anchor (gimp_image_get_floating_selection (image)); layer = gimp_image_merge_layers (image, gimp_image_get_layers (image), merge_list, context, GIMP_FLATTEN_IMAGE); g_slist_free (merge_list); gimp_image_alpha_changed (image); gimp_image_undo_group_end (image); gimp_unset_busy (image->gimp); return layer; } g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot flatten an image without any visible layer.")); return NULL; }
static void gimp_display_shell_drop_drawable (GtkWidget *widget, gint x, gint y, GimpViewable *viewable, gpointer data) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data); GimpImage *image = gimp_display_get_image (shell->display); GType new_type; GimpItem *new_item; GIMP_LOG (DND, NULL); if (shell->display->gimp->busy) return; if (! image) { image = gimp_image_new_from_drawable (shell->display->gimp, GIMP_DRAWABLE (viewable)); gimp_create_display (shell->display->gimp, image, GIMP_UNIT_PIXEL, 1.0, G_OBJECT (gtk_widget_get_screen (widget)), gimp_widget_get_monitor (widget)); g_object_unref (image); return; } if (GIMP_IS_LAYER (viewable)) new_type = G_TYPE_FROM_INSTANCE (viewable); else new_type = GIMP_TYPE_LAYER; new_item = gimp_item_convert (GIMP_ITEM (viewable), image, new_type); if (new_item) { GimpLayer *new_layer = GIMP_LAYER (new_item); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, _("Drop New Layer")); gimp_display_shell_dnd_position_item (shell, image, new_item); gimp_item_set_visible (new_item, TRUE, FALSE); gimp_item_set_linked (new_item, FALSE, FALSE); gimp_image_add_layer (image, new_layer, GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE); gimp_image_undo_group_end (image); gimp_display_shell_dnd_flush (shell, image); } }
GimpDrawable * gimp_drawable_transform_paste (GimpDrawable *drawable, GeglBuffer *buffer, GimpColorProfile *buffer_profile, gint offset_x, gint offset_y, gboolean new_layer) { GimpImage *image; GimpLayer *layer = NULL; const gchar *undo_desc = NULL; g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL); g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (buffer_profile), NULL); image = gimp_item_get_image (GIMP_ITEM (drawable)); if (GIMP_IS_LAYER (drawable)) undo_desc = C_("undo-type", "Transform Layer"); else if (GIMP_IS_CHANNEL (drawable)) undo_desc = C_("undo-type", "Transform Channel"); else return NULL; gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE, undo_desc); if (new_layer) { layer = gimp_layer_new_from_gegl_buffer (buffer, image, gimp_drawable_get_format_with_alpha (drawable), _("Transformation"), GIMP_OPACITY_OPAQUE, gimp_image_get_default_new_layer_mode (image), buffer_profile); gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y); floating_sel_attach (layer, drawable); drawable = GIMP_DRAWABLE (layer); } else { gimp_drawable_set_buffer_full (drawable, TRUE, NULL, buffer, offset_x, offset_y, TRUE); } gimp_image_undo_group_end (image); return drawable; }
void floating_sel_anchor (GimpLayer *layer) { GimpImage *image; GimpDrawable *drawable; GimpFilter *filter = NULL; gint off_x, off_y; gint dr_off_x, dr_off_y; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (gimp_layer_is_floating_sel (layer)); /* Don't let gimp_image_remove_layer free the layer while we still need it */ g_object_ref (layer); image = gimp_item_get_image (GIMP_ITEM (layer)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_ANCHOR, C_("undo-type", "Anchor Floating Selection")); drawable = gimp_layer_get_floating_sel_drawable (layer); gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y); gimp_item_get_offset (GIMP_ITEM (drawable), &dr_off_x, &dr_off_y); if (gimp_item_get_visible (GIMP_ITEM (layer)) && gimp_rectangle_intersect (off_x, off_y, gimp_item_get_width (GIMP_ITEM (layer)), gimp_item_get_height (GIMP_ITEM (layer)), dr_off_x, dr_off_y, gimp_item_get_width (GIMP_ITEM (drawable)), gimp_item_get_height (GIMP_ITEM (drawable)), NULL, NULL, NULL, NULL)) { filter = gimp_drawable_get_floating_sel_filter (drawable); g_object_ref (filter); } /* first remove the filter, then merge it, or we will get warnings * about already connected nodes */ gimp_image_remove_layer (image, layer, TRUE, NULL); if (filter) { gimp_drawable_merge_filter (drawable, filter, NULL, NULL); g_object_unref (filter); } gimp_image_undo_group_end (image); /* invalidate the boundaries */ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (gimp_image_get_mask (image))); g_object_unref (layer); }
void floating_sel_to_layer (GimpLayer *layer) { GimpItem *item; GimpImage *image; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (gimp_layer_is_floating_sel (layer)); item = GIMP_ITEM (layer); if (! (image = gimp_item_get_image (item))) return; /* Check if the floating layer belongs to a channel... */ if (GIMP_IS_CHANNEL (layer->fs.drawable)) { gimp_message (image->gimp, NULL, GIMP_MESSAGE_WARNING, _("Cannot create a new layer from the floating selection " "because it belongs to a layer mask or channel.")); return; } gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER, _("Floating Selection to Layer")); /* restore the contents of the drawable */ floating_sel_restore (layer, item->offset_x, item->offset_y, item->width, item->height); gimp_image_undo_push_fs_to_layer (image, NULL, layer); /* clear the selection */ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer)); /* Set pointers */ layer->fs.drawable = NULL; image->floating_sel = NULL; gimp_item_set_visible (GIMP_ITEM (layer), TRUE, TRUE); gimp_layer_set_lock_alpha (layer, FALSE, TRUE); gimp_image_undo_group_end (image); gimp_object_name_changed (GIMP_OBJECT (layer)); gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, GIMP_ITEM (layer)->width, GIMP_ITEM (layer)->height); gimp_image_floating_selection_changed (image); }
void gimp_paint_core_finish (GimpPaintCore *core, GimpDrawable *drawable, gboolean push_undo) { GimpImage *image; g_return_if_fail (GIMP_IS_PAINT_CORE (core)); g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); if (core->stroke_buffer) { g_array_free (core->stroke_buffer, TRUE); core->stroke_buffer = NULL; } image = gimp_item_get_image (GIMP_ITEM (drawable)); /* Determine if any part of the image has been altered-- * if nothing has, then just return... */ if ((core->x2 == core->x1) || (core->y2 == core->y1)) { gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable)); return; } if (push_undo) { gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_PAINT, core->undo_desc); GIMP_PAINT_CORE_GET_CLASS (core)->push_undo (core, image, NULL); gimp_drawable_push_undo (drawable, NULL, core->x1, core->y1, core->x2 - core->x1, core->y2 - core->y1, core->undo_tiles, TRUE); gimp_image_undo_group_end (image); } tile_manager_unref (core->undo_tiles); core->undo_tiles = NULL; if (core->saved_proj_tiles) { tile_manager_unref (core->saved_proj_tiles); core->saved_proj_tiles = NULL; } gimp_viewable_preview_thaw (GIMP_VIEWABLE (drawable)); }
void gimp_text_layer_set (GimpTextLayer *layer, const gchar *undo_desc, const gchar *first_property_name, ...) { GimpImage *image; GimpText *text; va_list var_args; g_return_if_fail (gimp_item_is_text_layer (GIMP_ITEM (layer))); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer))); text = gimp_text_layer_get_text (layer); if (! text) return; image = gimp_item_get_image (GIMP_ITEM (layer)); gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT, undo_desc); g_object_freeze_notify (G_OBJECT (layer)); if (layer->modified) { gimp_image_undo_push_text_layer_modified (image, NULL, layer); /* pass copy_tiles = TRUE so we not only ref the tiles; after * being a text layer again, undo doesn't care about the * layer's pixels any longer because they are generated, so * changing the text would happily overwrite the layer's * pixels, changing the pixels on the undo stack too without * any chance to ever undo again. */ gimp_image_undo_push_drawable_mod (image, NULL, GIMP_DRAWABLE (layer), TRUE); } gimp_image_undo_push_text_layer (image, undo_desc, layer, NULL); va_start (var_args, first_property_name); g_object_set_valist (G_OBJECT (text), first_property_name, var_args); va_end (var_args); g_object_set (layer, "modified", FALSE, NULL); g_object_thaw_notify (G_OBJECT (layer)); gimp_image_undo_group_end (image); }
static GimpBuffer * gimp_edit_extract (GimpImage *image, GimpPickable *pickable, GimpContext *context, gboolean cut_pixels, GError **error) { GeglBuffer *buffer; gint offset_x; gint offset_y; if (cut_pixels) gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT, C_("undo-type", "Cut")); /* Cut/copy the mask portion from the image */ buffer = gimp_selection_extract (GIMP_SELECTION (gimp_image_get_mask (image)), pickable, context, cut_pixels, FALSE, &offset_x, &offset_y, error); if (cut_pixels) gimp_image_undo_group_end (image); if (buffer) { GimpBuffer *gimp_buffer; gdouble res_x; gdouble res_y; gimp_buffer = gimp_buffer_new (buffer, _("Global Buffer"), offset_x, offset_y, FALSE); g_object_unref (buffer); gimp_image_get_resolution (image, &res_x, &res_y); gimp_buffer_set_resolution (gimp_buffer, res_x, res_y); gimp_buffer_set_unit (gimp_buffer, gimp_image_get_unit (image)); if (GIMP_IS_COLOR_MANAGED (pickable)) { GimpColorProfile *profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (pickable)); if (profile) gimp_buffer_set_color_profile (gimp_buffer, profile); } return gimp_buffer; } return NULL; }