diff --git a/ChangeLog b/ChangeLog index fa9b6e0c04..26517141bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2003-08-27 Michael Natterer + + Enabled type-preserving DND of all kinds of items between + different images. Fixes bug #119983. + + * app/core/gimpitem.[ch]: added new virtual function + GimpItem::convert() which duplicates an item for another image. + + * app/core/gimplayer.[ch]: removed gimp_layer_new_from_drawable() + and made it a GimpItem::convert() implementation. + + * app/vectors/gimpvectors.[ch]: removed gimp_vectors_convert() and + made it a GimpItem::convert() implementation. + + * app/widgets/gimpitemtreeview.[ch]: removed GimpConvertItemFunc + typedef and function pointer in GimpItemTreeViewClass since + we can simply call gimp_item_convert() now. + + * app/widgets/gimplayertreeview.c + * app/widgets/gimpvectorstreeview.c + * app/display/gimpdisplayshell-dnd.c + * tools/pdbgen/pdb/layer.pdb: changed accordingly. + + * app/pdb/layer_cmds.c: regenerated. + 2003-08-27 Sven Neumann * app/widgets/gimpitemfactory.c (gimp_item_factory_translate_func): diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c index 64d35eadb2..fad22f3a84 100644 --- a/app/core/gimpitem.c +++ b/app/core/gimpitem.c @@ -67,6 +67,10 @@ static gsize gimp_item_get_memsize (GimpObject *object, static GimpItem * gimp_item_real_duplicate (GimpItem *item, GType new_type, gboolean add_alpha); +static GimpItem * gimp_item_real_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha); static void gimp_item_real_rename (GimpItem *item, const gchar *new_name, const gchar *undo_desc); @@ -159,6 +163,7 @@ gimp_item_class_init (GimpItemClass *klass) klass->removed = NULL; klass->linked_changed = NULL; klass->duplicate = gimp_item_real_duplicate; + klass->convert = gimp_item_real_convert; klass->rename = gimp_item_real_rename; klass->translate = gimp_item_real_translate; klass->scale = gimp_item_real_scale; @@ -298,6 +303,27 @@ gimp_item_real_duplicate (GimpItem *item, return new_item; } +static GimpItem * +gimp_item_real_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha) +{ + GimpItem *new_item; + + new_item = gimp_item_duplicate (item, new_type, add_alpha); + + if (dest_image != item->gimage) + { + gimp_item_set_image (new_item, dest_image); + + /* force a unique name */ + gimp_object_name_changed (GIMP_OBJECT (new_item)); + } + + return new_item; +} + static void gimp_item_real_rename (GimpItem *item, const gchar *new_name, @@ -397,6 +423,21 @@ gimp_item_duplicate (GimpItem *item, return GIMP_ITEM_GET_CLASS (item)->duplicate (item, new_type, add_alpha); } +GimpItem * +gimp_item_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha) +{ + g_return_val_if_fail (GIMP_IS_ITEM (item), NULL); + g_return_val_if_fail (GIMP_IS_IMAGE (item->gimage), NULL); + g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL); + g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_ITEM), NULL); + + return GIMP_ITEM_GET_CLASS (item)->convert (item, dest_image, + new_type, add_alpha); +} + void gimp_item_rename (GimpItem *item, const gchar *new_name) diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h index f23cb33e96..72d827bb8a 100644 --- a/app/core/gimpitem.h +++ b/app/core/gimpitem.h @@ -62,6 +62,10 @@ struct _GimpItemClass GimpItem * (* duplicate) (GimpItem *item, GType new_type, gboolean add_alpha); + GimpItem * (* convert) (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha); void (* rename) (GimpItem *item, const gchar *new_name, const gchar *undo_desc); @@ -116,6 +120,10 @@ void gimp_item_configure (GimpItem *item, GimpItem * gimp_item_duplicate (GimpItem *item, GType new_type, gboolean add_alpha); +GimpItem * gimp_item_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha); void gimp_item_rename (GimpItem *item, const gchar *new_name); diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c index c32bca3c5c..5d83932f3d 100644 --- a/app/core/gimplayer.c +++ b/app/core/gimplayer.c @@ -46,7 +46,6 @@ #include "gimplayer-floating-sel.h" #include "gimplayermask.h" #include "gimpmarshal.h" -#include "gimpparasitelist.h" #include "gimp-intl.h" @@ -74,6 +73,10 @@ static void gimp_layer_invalidate_preview (GimpViewable *viewable); static GimpItem * gimp_layer_duplicate (GimpItem *item, GType new_type, gboolean add_alpha); +static GimpItem * gimp_layer_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha); static void gimp_layer_rename (GimpItem *item, const gchar *new_name, const gchar *undo_desc); @@ -208,6 +211,7 @@ gimp_layer_class_init (GimpLayerClass *klass) viewable_class->invalidate_preview = gimp_layer_invalidate_preview; item_class->duplicate = gimp_layer_duplicate; + item_class->convert = gimp_layer_convert; item_class->rename = gimp_layer_rename; item_class->translate = gimp_layer_translate; item_class->scale = gimp_layer_scale; @@ -346,6 +350,102 @@ gimp_layer_duplicate (GimpItem *item, return new_item; } +static GimpItem * +gimp_layer_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha) +{ + GimpLayer *layer; + GimpDrawable *drawable; + GimpItem *new_item; + GimpLayer *new_layer; + GimpDrawable *new_drawable; + GimpImageBaseType src_base_type; + GimpImageBaseType new_base_type; + + g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL); + + new_item = GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image, + new_type, add_alpha); + + if (! GIMP_IS_LAYER (new_item)) + return new_item; + + layer = GIMP_LAYER (item); + drawable = GIMP_DRAWABLE (item); + new_layer = GIMP_LAYER (new_item); + new_drawable = GIMP_DRAWABLE (new_item); + + src_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable)); + new_base_type = gimp_image_base_type (dest_image); + + if (src_base_type != new_base_type) + { + TileManager *new_tiles; + GimpImageType new_type; + + new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type); + + if (gimp_drawable_has_alpha (new_drawable)) + new_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_type); + + new_tiles = tile_manager_new (gimp_item_width (new_item), + gimp_item_height (new_item), + GIMP_IMAGE_TYPE_BYTES (new_type)); + + switch (new_base_type) + { + case GIMP_RGB: + gimp_drawable_convert_rgb (new_drawable, + new_tiles, + src_base_type); + break; + + case GIMP_GRAY: + gimp_drawable_convert_grayscale (new_drawable, + new_tiles, + src_base_type); + break; + + case GIMP_INDEXED: + { + PixelRegion layerPR; + PixelRegion newPR; + + pixel_region_init (&layerPR, new_drawable->tiles, + 0, 0, + gimp_item_width (new_item), + gimp_item_height (new_item), + FALSE); + pixel_region_init (&newPR, new_tiles, + 0, 0, + gimp_item_width (new_item), + gimp_item_height (new_item), + TRUE); + + gimp_layer_transform_color (dest_image, + &newPR, &layerPR, + NULL, + src_base_type); + } + break; + } + + tile_manager_unref (new_drawable->tiles); + + new_drawable->tiles = new_tiles; + new_drawable->type = new_type; + new_drawable->bytes = GIMP_IMAGE_TYPE_BYTES (new_type); + new_drawable->has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (new_type); + } + + if (new_layer->mask && dest_image != item->gimage) + gimp_item_set_image (GIMP_ITEM (new_layer->mask), dest_image); + + return new_item; +} + static void gimp_layer_rename (GimpItem *item, const gchar *new_name, @@ -399,7 +499,7 @@ gimp_layer_translate (GimpItem *item, /* update the new region */ gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, item->width, item->height); - if (layer->mask) + if (layer->mask) { GIMP_ITEM (layer->mask)->offset_x = item->offset_x; GIMP_ITEM (layer->mask)->offset_y = item->offset_y; @@ -657,11 +757,11 @@ gimp_layer_new (GimpImage *gimage, * @name: The new layer's name. * @opacity: The new layer's opacity. * @mode: The new layer's mode. - * + * * Copies %tiles to a layer taking into consideration the * possibility of transforming the contents to meet the requirements * of the target image type - * + * * Return value: The new layer. **/ GimpLayer * @@ -721,104 +821,13 @@ gimp_layer_new_from_tiles (TileManager *tiles, gimp_layer_transform_color (dest_gimage, &layerPR, &bufPR, GIMP_DRAWABLE (new_layer), - ((tile_manager_bpp (tiles) == 4) ? + ((tile_manager_bpp (tiles) == 4) ? GIMP_RGB : GIMP_GRAY)); } return new_layer; } -GimpLayer * -gimp_layer_new_from_drawable (GimpDrawable *drawable, - GimpImage *dest_image) -{ - GimpImageBaseType src_base_type; - GimpImageBaseType new_base_type; - GimpItem *new_item; - GimpDrawable *new_drawable; - GimpLayer *new_layer; - - g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); - g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL); - - src_base_type = GIMP_IMAGE_TYPE_BASE_TYPE (gimp_drawable_type (drawable)); - new_base_type = gimp_image_base_type (dest_image); - - new_item = gimp_item_duplicate (GIMP_ITEM (drawable), - GIMP_TYPE_LAYER, - TRUE); - - new_drawable = GIMP_DRAWABLE (new_item); - new_layer = GIMP_LAYER (new_item); - - if (src_base_type != new_base_type) - { - TileManager *new_tiles; - GimpImageType new_type; - - new_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_base_type); - - if (gimp_drawable_has_alpha (new_drawable)) - new_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_type); - - new_tiles = tile_manager_new (gimp_item_width (new_item), - gimp_item_height (new_item), - GIMP_IMAGE_TYPE_BYTES (new_type)); - - switch (new_base_type) - { - case GIMP_RGB: - gimp_drawable_convert_rgb (new_drawable, - new_tiles, - src_base_type); - break; - - case GIMP_GRAY: - gimp_drawable_convert_grayscale (new_drawable, - new_tiles, - src_base_type); - break; - - case GIMP_INDEXED: - { - PixelRegion layerPR; - PixelRegion newPR; - - pixel_region_init (&layerPR, new_drawable->tiles, - 0, 0, - gimp_item_width (new_item), - gimp_item_height (new_item), - FALSE); - pixel_region_init (&newPR, new_tiles, - 0, 0, - gimp_item_width (new_item), - gimp_item_height (new_item), - TRUE); - - gimp_layer_transform_color (dest_image, - &newPR, &layerPR, - NULL, - src_base_type); - } - break; - } - - tile_manager_unref (new_drawable->tiles); - - new_drawable->tiles = new_tiles; - new_drawable->type = new_type; - new_drawable->bytes = GIMP_IMAGE_TYPE_BYTES (new_type); - new_drawable->has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (new_type); - } - - gimp_item_set_image (new_item, dest_image); - - if (new_layer->mask) - gimp_item_set_image (GIMP_ITEM (new_layer->mask), dest_image); - - return new_layer; -} - GimpLayerMask * gimp_layer_add_mask (GimpLayer *layer, GimpLayerMask *mask, @@ -869,7 +878,7 @@ gimp_layer_add_mask (GimpLayer *layer, gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, - GIMP_ITEM (layer)->width, + GIMP_ITEM (layer)->width, GIMP_ITEM (layer)->height); if (push_undo) @@ -927,10 +936,10 @@ gimp_layer_create_mask (const GimpLayer *layer, break; } - pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles, - 0, 0, + pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles, + 0, 0, GIMP_ITEM (mask)->width, - GIMP_ITEM (mask)->height, + GIMP_ITEM (mask)->height, TRUE); switch (add_mask_type) @@ -942,9 +951,9 @@ gimp_layer_create_mask (const GimpLayer *layer, case GIMP_ADD_ALPHA_MASK: if (gimp_drawable_has_alpha (drawable)) { - pixel_region_init (&srcPR, drawable->tiles, - 0, 0, - item->width, item->height, + pixel_region_init (&srcPR, drawable->tiles, + 0, 0, + item->width, item->height, FALSE); extract_alpha_region (&srcPR, NULL, &destPR); @@ -982,7 +991,7 @@ gimp_layer_create_mask (const GimpLayer *layer, TRUE); copy_region (&srcPR, &destPR); - + GIMP_CHANNEL (mask)->bounds_known = FALSE; } } @@ -1012,16 +1021,16 @@ gimp_layer_create_mask (const GimpLayer *layer, pixel_region_init (&srcPR, copy_tiles, 0, 0, - item->width, - item->height, + item->width, + item->height, FALSE); } else { pixel_region_init (&srcPR, drawable->tiles, 0, 0, - item->width, - item->height, + item->width, + item->height, FALSE); } @@ -1100,15 +1109,15 @@ gimp_layer_apply_mask (GimpLayer *layer, NULL, FALSE); /* Combine the current layer's alpha channel and the mask */ - pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles, - 0, 0, - item->width, - item->height, + pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles, + 0, 0, + item->width, + item->height, TRUE); - pixel_region_init (&maskPR, GIMP_DRAWABLE (layer->mask)->tiles, - 0, 0, - item->width, - item->height, + pixel_region_init (&maskPR, GIMP_DRAWABLE (layer->mask)->tiles, + 0, 0, + item->width, + item->height, FALSE); apply_mask_to_region (&srcPR, &maskPR, OPAQUE_OPACITY); @@ -1141,53 +1150,54 @@ gimp_layer_add_alpha (GimpLayer *layer) { PixelRegion srcPR, destPR; TileManager *new_tiles; - GimpImageType type; + GimpImageType new_type; GimpImage *gimage; g_return_if_fail (GIMP_IS_LAYER (layer)); + gimage = gimp_item_get_image (GIMP_ITEM (layer)); + + g_return_if_fail (GIMP_IS_IMAGE (gimage)); + if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) return; - type = gimp_drawable_type_with_alpha (GIMP_DRAWABLE (layer)); + new_type = gimp_drawable_type_with_alpha (GIMP_DRAWABLE (layer)); + + /* Allocate the new tiles */ + new_tiles = tile_manager_new (GIMP_ITEM (layer)->width, + GIMP_ITEM (layer)->height, + GIMP_IMAGE_TYPE_BYTES (new_type)); /* Configure the pixel regions */ - pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles, - 0, 0, - GIMP_ITEM (layer)->width, - GIMP_ITEM (layer)->height, - FALSE); - - /* Allocate the new layer, configure dest region */ - new_tiles = tile_manager_new (GIMP_ITEM (layer)->width, - GIMP_ITEM (layer)->height, - gimp_drawable_bytes_with_alpha (GIMP_DRAWABLE (layer))); - pixel_region_init (&destPR, new_tiles, + pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles, 0, 0, - GIMP_ITEM (layer)->width, - GIMP_ITEM (layer)->height, + GIMP_ITEM (layer)->width, + GIMP_ITEM (layer)->height, + FALSE); + pixel_region_init (&destPR, new_tiles, + 0, 0, + GIMP_ITEM (layer)->width, + GIMP_ITEM (layer)->height, TRUE); /* Add an alpha channel */ add_alpha_region (&srcPR, &destPR); /* Push the layer on the undo stack */ - gimp_image_undo_push_layer_mod (gimp_item_get_image (GIMP_ITEM (layer)), - _("Add Alpha Channel"), layer); + gimp_image_undo_push_layer_mod (gimage, _("Add Alpha Channel"), layer); /* Configure the new layer */ tile_manager_unref (GIMP_DRAWABLE (layer)->tiles); GIMP_DRAWABLE (layer)->tiles = new_tiles; - GIMP_DRAWABLE (layer)->type = type; - GIMP_DRAWABLE (layer)->bytes = GIMP_DRAWABLE (layer)->bytes + 1; - GIMP_DRAWABLE (layer)->has_alpha = GIMP_IMAGE_TYPE_HAS_ALPHA (type); + GIMP_DRAWABLE (layer)->type = new_type; + GIMP_DRAWABLE (layer)->bytes = GIMP_IMAGE_TYPE_BYTES (new_type); + GIMP_DRAWABLE (layer)->has_alpha = TRUE; GIMP_DRAWABLE (layer)->preview_valid = FALSE; gimp_drawable_alpha_changed (GIMP_DRAWABLE (layer)); - gimage = gimp_item_get_image (GIMP_ITEM (layer)); - if (gimp_container_num_children (gimage->layers) == 1) gimp_image_alpha_changed (gimage); } @@ -1344,7 +1354,7 @@ gimp_layer_pick_correlate (GimpLayer *layer, /* Otherwise, determine if the alpha value at * the given point is non-zero */ - tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, + tile = tile_manager_get_tile (GIMP_DRAWABLE(layer)->tiles, x, y, TRUE, FALSE); val = * ((guchar *) tile_data_pointer (tile, @@ -1410,7 +1420,7 @@ gimp_layer_set_opacity (GimpLayer *layer, if (gimage) gimp_image_undo_push_layer_opacity (gimage, NULL, layer); } - + layer->opacity = opacity; g_signal_emit (layer, layer_signals[OPACITY_CHANGED], 0); @@ -1446,7 +1456,7 @@ gimp_layer_set_mode (GimpLayer *layer, if (gimage) gimp_image_undo_push_layer_mode (gimage, NULL, layer); } - + layer->mode = mode; g_signal_emit (layer, layer_signals[MODE_CHANGED], 0); @@ -1482,7 +1492,7 @@ gimp_layer_set_preserve_trans (GimpLayer *layer, if (gimage) gimp_image_undo_push_layer_preserve_trans (gimage, NULL, layer); } - + layer->preserve_trans = preserve ? TRUE : FALSE; g_signal_emit (layer, layer_signals[PRESERVE_TRANS_CHANGED], 0); diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h index ec91031dea..0720f3b9c7 100644 --- a/app/core/gimplayer.h +++ b/app/core/gimplayer.h @@ -85,11 +85,9 @@ GimpLayer * gimp_layer_new_from_tiles (TileManager *tiles, const gchar *name, gdouble opacity, GimpLayerModeEffects mode); -GimpLayer * gimp_layer_new_from_drawable (GimpDrawable *drawable, - GimpImage *dest_image); GimpLayerMask * gimp_layer_create_mask (const GimpLayer *layer, - GimpAddMaskType mask_type); + GimpAddMaskType mask_type); GimpLayerMask * gimp_layer_add_mask (GimpLayer *layer, GimpLayerMask *mask, gboolean push_undo); @@ -99,11 +97,11 @@ void gimp_layer_apply_mask (GimpLayer *layer, void gimp_layer_add_alpha (GimpLayer *layer); void gimp_layer_resize_to_image (GimpLayer *layer); -BoundSeg * gimp_layer_boundary (GimpLayer *layer, +BoundSeg * gimp_layer_boundary (GimpLayer *layer, gint *num_segs); void gimp_layer_invalidate_boundary (GimpLayer *layer); -gboolean gimp_layer_pick_correlate (GimpLayer *layer, - gint x, +gboolean gimp_layer_pick_correlate (GimpLayer *layer, + gint x, gint y); GimpLayerMask * gimp_layer_get_mask (const GimpLayer *layer); @@ -115,7 +113,7 @@ void gimp_layer_set_opacity (GimpLayer *layer, gboolean push_undo); gdouble gimp_layer_get_opacity (const GimpLayer *layer); -void gimp_layer_set_mode (GimpLayer *layer, +void gimp_layer_set_mode (GimpLayer *layer, GimpLayerModeEffects mode, gboolean push_undo); GimpLayerModeEffects gimp_layer_get_mode (const GimpLayer *layer); @@ -126,5 +124,4 @@ void gimp_layer_set_preserve_trans (GimpLayer *layer, gboolean gimp_layer_get_preserve_trans (const GimpLayer *layer); - #endif /* __GIMP_LAYER_H__ */ diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c index 942e3116e2..49d9395684 100644 --- a/app/display/gimpdisplayshell-dnd.c +++ b/app/display/gimpdisplayshell-dnd.c @@ -49,35 +49,49 @@ gimp_display_shell_drop_drawable (GtkWidget *widget, GimpViewable *viewable, gpointer data) { - GimpDrawable *drawable; GimpDisplay *gdisp; - GimpLayer *new_layer; - gint off_x, off_y; + GType new_type; + GimpItem *new_item; gdisp = GIMP_DISPLAY_SHELL (data)->gdisp; if (gdisp->gimage->gimp->busy) return; - drawable = GIMP_DRAWABLE (viewable); + if (GIMP_IS_LAYER (viewable)) + new_type = G_TYPE_FROM_INSTANCE (viewable); + else + new_type = GIMP_TYPE_LAYER; - gimp_image_undo_group_start (gdisp->gimage, GIMP_UNDO_GROUP_EDIT_PASTE, - _("Drop New Layer")); + new_item = gimp_item_convert (GIMP_ITEM (viewable), gdisp->gimage, + new_type, TRUE); - new_layer = gimp_layer_new_from_drawable (drawable, gdisp->gimage); + if (new_item) + { + GimpLayer *new_layer; + gint off_x, off_y; - off_x = (gdisp->gimage->width - gimp_item_width (GIMP_ITEM (drawable))) / 2; - off_y = (gdisp->gimage->height - gimp_item_height (GIMP_ITEM (drawable))) / 2; + new_layer = GIMP_LAYER (new_item); - gimp_item_translate (GIMP_ITEM (new_layer), off_x, off_y, FALSE); + gimp_image_undo_group_start (gdisp->gimage, GIMP_UNDO_GROUP_EDIT_PASTE, + _("Drop New Layer")); - gimp_image_add_layer (gdisp->gimage, new_layer, -1); + gimp_item_offsets (new_item, &off_x, &off_y); - gimp_image_undo_group_end (gdisp->gimage); + off_x = (gdisp->gimage->width - gimp_item_width (new_item)) / 2 - off_x; + off_y = (gdisp->gimage->height - gimp_item_height (new_item)) / 2 - off_y; - gimp_image_flush (gdisp->gimage); + gimp_item_translate (new_item, off_x, off_y, FALSE); - gimp_context_set_display (gimp_get_user_context (gdisp->gimage->gimp), gdisp); + gimp_image_add_layer (gdisp->gimage, new_layer, -1); + + gimp_image_undo_group_end (gdisp->gimage); + + gimp_image_flush (gdisp->gimage); + + gimp_context_set_display (gimp_get_user_context (gdisp->gimage->gimp), + gdisp); + } } void @@ -85,29 +99,35 @@ gimp_display_shell_drop_vectors (GtkWidget *widget, GimpViewable *viewable, gpointer data) { - GimpVectors *vectors; GimpDisplay *gdisp; - GimpVectors *new_vectors; + GimpItem *new_item; gdisp = GIMP_DISPLAY_SHELL (data)->gdisp; if (gdisp->gimage->gimp->busy) return; - vectors = GIMP_VECTORS (viewable); + new_item = gimp_item_convert (GIMP_ITEM (viewable), gdisp->gimage, + G_TYPE_FROM_INSTANCE (viewable), TRUE); - gimp_image_undo_group_start (gdisp->gimage, GIMP_UNDO_GROUP_EDIT_PASTE, - _("Drop New Path")); + if (new_item) + { + GimpVectors *new_vectors; - new_vectors = gimp_vectors_convert (vectors, gdisp->gimage); + new_vectors = GIMP_VECTORS (new_item); - gimp_image_add_vectors (gdisp->gimage, new_vectors, -1); + gimp_image_undo_group_start (gdisp->gimage, GIMP_UNDO_GROUP_EDIT_PASTE, + _("Drop New Path")); - gimp_image_undo_group_end (gdisp->gimage); + gimp_image_add_vectors (gdisp->gimage, new_vectors, -1); - gimp_image_flush (gdisp->gimage); + gimp_image_undo_group_end (gdisp->gimage); - gimp_context_set_display (gimp_get_user_context (gdisp->gimage->gimp), gdisp); + gimp_image_flush (gdisp->gimage); + + gimp_context_set_display (gimp_get_user_context (gdisp->gimage->gimp), + gdisp); + } } static void @@ -134,13 +154,9 @@ gimp_display_shell_bucket_fill (GimpImage *gimage, "gimp-bucket-fill-tool"); if (tool_info && tool_info->tool_options) - { - context = GIMP_CONTEXT (tool_info->tool_options); - } + context = GIMP_CONTEXT (tool_info->tool_options); else - { - context = gimp_get_user_context (gimage->gimp); - } + context = gimp_get_user_context (gimage->gimp); gimp_drawable_bucket_fill_full (drawable, fill_mode, diff --git a/app/pdb/layer_cmds.c b/app/pdb/layer_cmds.c index 6c9757c511..96f602582d 100644 --- a/app/pdb/layer_cmds.c +++ b/app/pdb/layer_cmds.c @@ -243,7 +243,7 @@ layer_copy_invoker (Gimp *gimp, Argument *return_args; GimpLayer *layer; gboolean add_alpha; - GimpLayer *copy = NULL; + GimpLayer *layer_copy = NULL; layer = (GimpLayer *) gimp_item_get_by_ID (gimp, args[0].value.pdb_int); if (! GIMP_IS_LAYER (layer)) @@ -252,12 +252,12 @@ layer_copy_invoker (Gimp *gimp, add_alpha = args[1].value.pdb_int ? TRUE : FALSE; if (success) - success = (copy = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer), G_TYPE_FROM_INSTANCE (layer), add_alpha))) != NULL; + success = (layer_copy = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer), G_TYPE_FROM_INSTANCE (layer), add_alpha))) != NULL; return_args = procedural_db_return_args (&layer_copy_proc, success); if (success) - return_args[1].value.pdb_int = gimp_item_get_ID (GIMP_ITEM (copy)); + return_args[1].value.pdb_int = gimp_item_get_ID (GIMP_ITEM (layer_copy)); return return_args; } @@ -944,25 +944,42 @@ layer_new_from_drawable_invoker (Gimp *gimp, gboolean success = TRUE; Argument *return_args; GimpDrawable *drawable; - GimpImage *gimage; - GimpLayer *copy = NULL; + GimpImage *dest_image; + GimpLayer *layer_copy = NULL; drawable = (GimpDrawable *) gimp_item_get_by_ID (gimp, args[0].value.pdb_int); if (! GIMP_IS_DRAWABLE (drawable)) success = FALSE; - gimage = gimp_image_get_by_ID (gimp, args[1].value.pdb_int); - if (! GIMP_IS_IMAGE (gimage)) + dest_image = gimp_image_get_by_ID (gimp, args[1].value.pdb_int); + if (! GIMP_IS_IMAGE (dest_image)) success = FALSE; if (success) - success = (copy = gimp_layer_new_from_drawable (drawable, - gimage)) != NULL; + { + GType new_type; + GimpItem *new_item; + + if (GIMP_IS_LAYER (drawable)) + new_type = G_TYPE_FROM_INSTANCE (drawable); + else + new_type = GIMP_TYPE_LAYER; + + if (dest_image == gimp_item_get_image (GIMP_ITEM (drawable))) + new_item = gimp_item_duplicate (GIMP_ITEM (drawable), new_type, TRUE); + else + new_item = gimp_item_convert (GIMP_ITEM (drawable), dest_image, new_type, TRUE); + + if (new_item) + layer_copy = GIMP_LAYER (new_item); + else + success = FALSE; + } return_args = procedural_db_return_args (&layer_new_from_drawable_proc, success); if (success) - return_args[1].value.pdb_int = gimp_item_get_ID (GIMP_ITEM (copy)); + return_args[1].value.pdb_int = gimp_item_get_ID (GIMP_ITEM (layer_copy)); return return_args; } diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c index 0ed3d91f3f..4fc8a27d96 100644 --- a/app/vectors/gimpvectors.c +++ b/app/vectors/gimpvectors.c @@ -57,6 +57,10 @@ static gsize gimp_vectors_get_memsize (GimpObject *object, static GimpItem * gimp_vectors_duplicate (GimpItem *item, GType new_type, gboolean add_alpha); +static GimpItem * gimp_vectors_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha); static void gimp_vectors_translate (GimpItem *item, gint offset_x, gint offset_y, @@ -192,6 +196,7 @@ gimp_vectors_class_init (GimpVectorsClass *klass) viewable_class->get_new_preview = gimp_vectors_get_new_preview; item_class->duplicate = gimp_vectors_duplicate; + item_class->convert = gimp_vectors_convert; item_class->translate = gimp_vectors_translate; item_class->scale = gimp_vectors_scale; item_class->resize = gimp_vectors_resize; @@ -285,6 +290,31 @@ gimp_vectors_duplicate (GimpItem *item, return new_item; } +static GimpItem * +gimp_vectors_convert (GimpItem *item, + GimpImage *dest_image, + GType new_type, + gboolean add_alpha) +{ + GimpItem *new_item; + + g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_VECTORS), NULL); + + new_item = GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image, + new_type, add_alpha); + + if (! GIMP_IS_VECTORS (new_item)) + return new_item; + + if (dest_image != item->gimage) + { + new_item->width = dest_image->width; + new_item->height = dest_image->height; + } + + return new_item; +} + static void gimp_vectors_translate (GimpItem *item, gint offset_x, @@ -516,30 +546,6 @@ gimp_vectors_new (GimpImage *gimage, return vectors; } -GimpVectors * -gimp_vectors_convert (GimpVectors *vectors, - GimpImage *dest_image) -{ - GimpItem *new_item; - GimpVectors *new_vectors; - - g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL); - g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL); - - new_item = gimp_item_duplicate (GIMP_ITEM (vectors), - GIMP_TYPE_VECTORS, - FALSE); - - new_vectors = GIMP_VECTORS (new_item); - - new_item->width = dest_image->width; - new_item->height = dest_image->height; - - gimp_item_set_image (new_item, dest_image); - - return new_vectors; -} - void gimp_vectors_freeze (GimpVectors *vectors) { diff --git a/app/vectors/gimpvectors.h b/app/vectors/gimpvectors.h index 7c8513aac7..6719de4ba1 100644 --- a/app/vectors/gimpvectors.h +++ b/app/vectors/gimpvectors.h @@ -87,8 +87,6 @@ GType gimp_vectors_get_type (void) G_GNUC_CONST; GimpVectors * gimp_vectors_new (GimpImage *gimage, const gchar *name); -GimpVectors * gimp_vectors_convert (GimpVectors *vectors, - GimpImage *dest_image); void gimp_vectors_freeze (GimpVectors *vectors); void gimp_vectors_thaw (GimpVectors *vectors); diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 4f7a7f0162..ad0660eb68 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -217,7 +217,6 @@ gimp_item_tree_view_class_init (GimpItemTreeViewClass *klass) klass->reorder_item = NULL; klass->add_item = NULL; klass->remove_item = NULL; - klass->convert_item = NULL; klass->new_desc = NULL; klass->new_help_id = NULL; @@ -706,15 +705,10 @@ gimp_item_tree_view_drop_possible (GimpContainerTreeView *tree_view, if (gimp_item_get_image (GIMP_ITEM (src_viewable)) != gimp_item_get_image (GIMP_ITEM (dest_viewable))) { - if (GIMP_ITEM_TREE_VIEW_GET_CLASS (item_view)->convert_item) - { - if (drag_action) - *drag_action = GDK_ACTION_COPY; + if (drag_action) + *drag_action = GDK_ACTION_COPY; - return TRUE; - } - - return FALSE; + return TRUE; } return GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_possible (tree_view, @@ -758,8 +752,10 @@ gimp_item_tree_view_drop (GimpContainerTreeView *tree_view, if (drop_pos == GTK_TREE_VIEW_DROP_AFTER) dest_index++; - new_item = item_view_class->convert_item (GIMP_ITEM (src_viewable), - item_view->gimage); + new_item = gimp_item_convert (GIMP_ITEM (src_viewable), + item_view->gimage, + G_TYPE_FROM_INSTANCE (src_viewable), + TRUE); item_view_class->add_item (item_view->gimage, new_item, diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h index e4949d094e..449c7aa6a0 100644 --- a/app/widgets/gimpitemtreeview.h +++ b/app/widgets/gimpitemtreeview.h @@ -40,8 +40,6 @@ typedef void (* GimpAddItemFunc) (GimpImage *gimage, gint index); typedef void (* GimpRemoveItemFunc) (GimpImage *gimage, GimpItem *item); -typedef GimpItem * (* GimpConvertItemFunc) (GimpItem *item, - GimpImage *dest_gimage); typedef void (* GimpNewItemFunc) (GimpImage *gimage, GimpItem *template, @@ -102,7 +100,6 @@ struct _GimpItemTreeViewClass GimpReorderItemFunc reorder_item; GimpAddItemFunc add_item; GimpRemoveItemFunc remove_item; - GimpConvertItemFunc convert_item; /* various descriptive strings for tooltips and undo steps */ const gchar *new_desc; diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c index 78cb2d97d7..a2bce2d172 100644 --- a/app/widgets/gimplayertreeview.c +++ b/app/widgets/gimplayertreeview.c @@ -193,7 +193,6 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass) item_view_class->reorder_item = (GimpReorderItemFunc) gimp_image_position_layer; item_view_class->add_item = (GimpAddItemFunc) gimp_image_add_layer; item_view_class->remove_item = gimp_layer_tree_view_remove_item; - item_view_class->convert_item = (GimpConvertItemFunc) gimp_layer_new_from_drawable; item_view_class->new_desc = _("New Layer"); item_view_class->new_help_id = GIMP_HELP_LAYER_NEW; diff --git a/app/widgets/gimpvectorstreeview.c b/app/widgets/gimpvectorstreeview.c index 52098ebc78..b8400504c0 100644 --- a/app/widgets/gimpvectorstreeview.c +++ b/app/widgets/gimpvectorstreeview.c @@ -119,7 +119,6 @@ gimp_vectors_tree_view_class_init (GimpVectorsTreeViewClass *klass) item_view_class->reorder_item = (GimpReorderItemFunc) gimp_image_position_vectors; item_view_class->add_item = (GimpAddItemFunc) gimp_image_add_vectors; item_view_class->remove_item = (GimpRemoveItemFunc) gimp_image_remove_vectors; - item_view_class->convert_item = (GimpConvertItemFunc) gimp_vectors_convert; item_view_class->new_desc = _("New Path"); item_view_class->new_help_id = GIMP_HELP_PATH_NEW; diff --git a/tools/pdbgen/pdb/layer.pdb b/tools/pdbgen/pdb/layer.pdb index 4fa0b57da5..5799e89691 100644 --- a/tools/pdbgen/pdb/layer.pdb +++ b/tools/pdbgen/pdb/layer.pdb @@ -286,11 +286,11 @@ HELP @outargs = ( { name => 'layer_copy', type => 'layer', init => 1, wrap => 1, - desc => 'The newly copied layer', alias => 'copy' } + desc => 'The newly copied layer' } ); %invoke = ( - code => 'success = (copy = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer), G_TYPE_FROM_INSTANCE (layer), add_alpha))) != NULL;' + code => 'success = (layer_copy = GIMP_LAYER (gimp_item_duplicate (GIMP_ITEM (layer), G_TYPE_FROM_INSTANCE (layer), add_alpha))) != NULL;' ); } @@ -506,23 +506,39 @@ HELP @inargs = ( { name => 'drawable', type => 'drawable', - desc => 'The source drawable from where the new layer is copied', - alias => 'drawable' }, + desc => 'The source drawable from where the new layer is copied' }, { name => 'dest_image', type => 'image', - desc => 'The destination image to which to add the layer', - alias => 'gimage' } + desc => 'The destination image to which to add the layer' } ); @outargs = ( { name => 'layer_copy', type => 'layer', init => 1, - desc => 'The newly copied layer', alias => 'copy' } + desc => 'The newly copied layer' } ); %invoke = ( - code => 'success = (copy = gimp_layer_new_from_drawable (drawable, - gimage)) != NULL;' - ); + code => <<'CODE' +{ + GType new_type; + GimpItem *new_item; + if (GIMP_IS_LAYER (drawable)) + new_type = G_TYPE_FROM_INSTANCE (drawable); + else + new_type = GIMP_TYPE_LAYER; + + if (dest_image == gimp_item_get_image (GIMP_ITEM (drawable))) + new_item = gimp_item_duplicate (GIMP_ITEM (drawable), new_type, TRUE); + else + new_item = gimp_item_convert (GIMP_ITEM (drawable), dest_image, new_type, TRUE); + + if (new_item) + layer_copy = GIMP_LAYER (new_item); + else + success = FALSE; +} +CODE + ); } &layer_accessors('name', 'string', 'name', 0, 0, [ undef, <<'CODE' ],