mirror of https://github.com/GNOME/gimp.git
app, menus, pdb: new "Paste as Single Layer( in Place)?" actions.
When the clipboard contains raw image data or single layers, it's the same as the normal "Paste" (and "Paste In Place" respectively). These actions are useful if you want to copy a bunch of layers and paste them "merged" into a single layers (since now the copy-paste of multiple layers will create multiple layers). It is somehow similar to the "Copy Visible" action except that it works on selected layers only and work at paste time, making the action more versatile.
This commit is contained in:
parent
fc050914ab
commit
143496af22
|
@ -93,6 +93,7 @@ buffers_paste_cmd_callback (GimpAction *action,
|
|||
g_list_free (gimp_edit_paste (image,
|
||||
g_list_length (drawables) == 1 ? drawables->data : NULL,
|
||||
GIMP_OBJECT (buffer), paste_type,
|
||||
context, FALSE,
|
||||
x, y, width, height));
|
||||
|
||||
gimp_image_flush (image);
|
||||
|
|
|
@ -178,6 +178,19 @@ static const GimpEnumActionEntry edit_paste_actions[] =
|
|||
GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE, FALSE,
|
||||
GIMP_HELP_EDIT_PASTE_IN_PLACE },
|
||||
|
||||
{ "edit-paste-merged", GIMP_ICON_EDIT_PASTE,
|
||||
NC_("edit-action", "_Paste as Single Layer"), NULL,
|
||||
NC_("edit-action", "Paste the content of the clipboard as a single layer"),
|
||||
GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING, FALSE,
|
||||
GIMP_HELP_EDIT_PASTE },
|
||||
|
||||
{ "edit-paste-merged-in-place", GIMP_ICON_EDIT_PASTE,
|
||||
NC_("edit-action", "Paste as Single Layer In P_lace"), NULL,
|
||||
NC_("edit-action",
|
||||
"Paste the content of the clipboard at its original position as a single layer"),
|
||||
GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE, FALSE,
|
||||
GIMP_HELP_EDIT_PASTE_IN_PLACE },
|
||||
|
||||
{ "edit-paste-into", GIMP_ICON_EDIT_PASTE_INTO,
|
||||
NC_("edit-action", "Paste _Into Selection"), NULL,
|
||||
NC_("edit-action",
|
||||
|
|
|
@ -69,6 +69,7 @@ static gboolean check_drawable_alpha (GimpDrawable *drawable,
|
|||
gpointer data);
|
||||
static void edit_paste (GimpDisplay *display,
|
||||
GimpPasteType paste_type,
|
||||
gboolean merged,
|
||||
gboolean try_svg);
|
||||
static void cut_named_buffer_callback (GtkWidget *widget,
|
||||
const gchar *name,
|
||||
|
@ -346,6 +347,7 @@ edit_paste_cmd_callback (GimpAction *action,
|
|||
GimpPasteType paste_type = (GimpPasteType) g_variant_get_int32 (value);
|
||||
GimpPasteType converted_type;
|
||||
GList *drawables;
|
||||
gboolean merged = FALSE;
|
||||
|
||||
return_if_no_image (image, data);
|
||||
|
||||
|
@ -367,14 +369,17 @@ edit_paste_cmd_callback (GimpAction *action,
|
|||
case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
||||
case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
|
||||
edit_paste (display, paste_type, TRUE);
|
||||
edit_paste (display, paste_type, merged, TRUE);
|
||||
break;
|
||||
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
|
||||
edit_paste (display, paste_type, FALSE);
|
||||
edit_paste (display, paste_type, merged, FALSE);
|
||||
break;
|
||||
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE:
|
||||
merged = TRUE;
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
|
@ -383,19 +388,21 @@ edit_paste_cmd_callback (GimpAction *action,
|
|||
(g_list_length (drawables) == 1) &&
|
||||
GIMP_IS_LAYER_MASK (drawables->data))
|
||||
{
|
||||
converted_type = (paste_type == GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING) ?
|
||||
converted_type = (paste_type == GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING ||
|
||||
paste_type == GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING) ?
|
||||
GIMP_PASTE_TYPE_FLOATING :
|
||||
GIMP_PASTE_TYPE_FLOATING_IN_PLACE;
|
||||
|
||||
edit_paste (display, converted_type, TRUE);
|
||||
edit_paste (display, converted_type, merged, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
converted_type = (paste_type == GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING) ?
|
||||
converted_type = (paste_type == GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING ||
|
||||
paste_type == GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING) ?
|
||||
GIMP_PASTE_TYPE_NEW_LAYER :
|
||||
GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE;
|
||||
|
||||
edit_paste (display, converted_type, FALSE);
|
||||
edit_paste (display, converted_type, merged, FALSE);
|
||||
}
|
||||
g_list_free (drawables);
|
||||
|
||||
|
@ -627,13 +634,16 @@ check_drawable_alpha (GimpDrawable *drawable,
|
|||
static void
|
||||
edit_paste (GimpDisplay *display,
|
||||
GimpPasteType paste_type,
|
||||
gboolean merged,
|
||||
gboolean try_svg)
|
||||
{
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpObject *paste;
|
||||
|
||||
g_return_if_fail (paste_type != GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING &&
|
||||
paste_type != GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE);
|
||||
paste_type != GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE &&
|
||||
paste_type != GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING &&
|
||||
paste_type != GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE);
|
||||
|
||||
if (try_svg)
|
||||
{
|
||||
|
@ -702,8 +712,9 @@ edit_paste (GimpDisplay *display,
|
|||
! gimp_display_shell_get_infinite_canvas (shell),
|
||||
&x, &y, &width, &height);
|
||||
|
||||
if ((pasted_layers = gimp_edit_paste (image, drawables, paste,
|
||||
paste_type, x, y, width, height)))
|
||||
if ((pasted_layers = gimp_edit_paste (image, drawables, paste, paste_type,
|
||||
gimp_get_user_context (display->gimp),
|
||||
merged, x, y, width, height)))
|
||||
{
|
||||
gimp_image_set_selected_layers (image, pasted_layers);
|
||||
g_list_free (pasted_layers);
|
||||
|
|
|
@ -950,6 +950,8 @@ gimp_paste_type_get_type (void)
|
|||
{ GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE", "new-layer-in-place" },
|
||||
{ GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING, "GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING", "new-layer-or-floating" },
|
||||
{ GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE", "new-layer-or-floating-in-place" },
|
||||
{ GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING, "GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING", "new-merged-layer-or-floating" },
|
||||
{ GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE", "new-merged-layer-or-floating-in-place" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -963,6 +965,8 @@ gimp_paste_type_get_type (void)
|
|||
{ GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE", NULL },
|
||||
{ GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING, "GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING", NULL },
|
||||
{ GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE", NULL },
|
||||
{ GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING, "GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING", NULL },
|
||||
{ GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE, "GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE", NULL },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -437,7 +437,9 @@ typedef enum /*< pdb-skip >*/
|
|||
GIMP_PASTE_TYPE_NEW_LAYER,
|
||||
GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE,
|
||||
GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING,
|
||||
GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE
|
||||
GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE,
|
||||
GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING,
|
||||
GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE,
|
||||
} GimpPasteType;
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "gimpgrouplayer.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-duplicate.h"
|
||||
#include "gimpimage-merge.h"
|
||||
#include "gimpimage-new.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimplayer-floating-selection.h"
|
||||
|
@ -296,12 +297,14 @@ gimp_edit_paste_is_in_place (GimpPasteType paste_type)
|
|||
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING:
|
||||
return FALSE;
|
||||
|
||||
case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -326,6 +329,8 @@ gimp_edit_paste_is_floating (GimpPasteType paste_type,
|
|||
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE:
|
||||
if (GIMP_IS_LAYER_MASK (drawable))
|
||||
return TRUE;
|
||||
else
|
||||
|
@ -775,6 +780,10 @@ gimp_edit_paste_paste (GimpImage *image,
|
|||
gimp_image_add_layer (image, iter->data, parent, position, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING:
|
||||
case GIMP_PASTE_TYPE_NEW_MERGED_LAYER_OR_FLOATING_IN_PLACE:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -788,6 +797,8 @@ gimp_edit_paste (GimpImage *image,
|
|||
GList *drawables,
|
||||
GimpObject *paste,
|
||||
GimpPasteType paste_type,
|
||||
GimpContext *context,
|
||||
gboolean merged,
|
||||
gint viewport_x,
|
||||
gint viewport_y,
|
||||
gint viewport_width,
|
||||
|
@ -809,7 +820,51 @@ gimp_edit_paste (GimpImage *image,
|
|||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (iter->data)), NULL);
|
||||
}
|
||||
|
||||
if (merged && GIMP_IS_IMAGE (paste))
|
||||
{
|
||||
GimpImage *tmp_image;
|
||||
|
||||
tmp_image = gimp_image_duplicate (GIMP_IMAGE (paste));
|
||||
gimp_container_remove (image->gimp->images, GIMP_OBJECT (tmp_image));
|
||||
gimp_image_merge_visible_layers (tmp_image, context, GIMP_EXPAND_AS_NECESSARY,
|
||||
FALSE, FALSE, NULL);
|
||||
layers = g_list_copy (gimp_image_get_layer_iter (tmp_image));
|
||||
|
||||
/* The merge process should ensure that we get a single non-group and
|
||||
* no-mask layer.
|
||||
*/
|
||||
g_return_val_if_fail (g_list_length (layers) == 1, NULL);
|
||||
|
||||
layers->data = gimp_item_convert (GIMP_ITEM (layers->data), image,
|
||||
G_TYPE_FROM_INSTANCE (layers->data));
|
||||
|
||||
switch (paste_type)
|
||||
{
|
||||
case GIMP_PASTE_TYPE_FLOATING:
|
||||
case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
|
||||
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
||||
case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
|
||||
if (gimp_drawable_get_format (GIMP_DRAWABLE (layers->data)) !=
|
||||
gimp_drawable_get_format_with_alpha (GIMP_DRAWABLE (layers->data)))
|
||||
{
|
||||
gimp_drawable_convert_type (GIMP_DRAWABLE (layers->data), image,
|
||||
gimp_drawable_get_base_type (layers->data),
|
||||
gimp_drawable_get_precision (layers->data),
|
||||
TRUE, NULL, NULL,
|
||||
GEGL_DITHER_NONE, GEGL_DITHER_NONE,
|
||||
FALSE, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_object_unref (tmp_image);
|
||||
}
|
||||
else
|
||||
{
|
||||
layers = gimp_edit_paste_get_layers (image, drawables, paste, &paste_type);
|
||||
}
|
||||
|
||||
if (! layers)
|
||||
return NULL;
|
||||
|
|
|
@ -35,6 +35,8 @@ GList * gimp_edit_paste (GimpImage *image,
|
|||
GList *drawables,
|
||||
GimpObject *paste,
|
||||
GimpPasteType paste_type,
|
||||
GimpContext *context,
|
||||
gboolean merged,
|
||||
gint viewport_x,
|
||||
gint viewport_y,
|
||||
gint viewport_width,
|
||||
|
|
|
@ -459,6 +459,7 @@ gimp_display_shell_drop_buffer (GtkWidget *widget,
|
|||
{
|
||||
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
|
||||
GimpImage *image = gimp_display_get_image (shell->display);
|
||||
GimpContext *context;
|
||||
GList *drawables;
|
||||
GimpBuffer *buffer;
|
||||
GimpPasteType paste_type;
|
||||
|
@ -482,7 +483,7 @@ gimp_display_shell_drop_buffer (GtkWidget *widget,
|
|||
|
||||
paste_type = GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING;
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
|
||||
context = gimp_get_user_context (shell->display->gimp);
|
||||
buffer = GIMP_BUFFER (viewable);
|
||||
|
||||
gimp_display_shell_untransform_viewport (
|
||||
|
@ -493,7 +494,8 @@ gimp_display_shell_drop_buffer (GtkWidget *widget,
|
|||
/* FIXME: popup a menu for selecting "Paste Into" */
|
||||
|
||||
g_list_free (gimp_edit_paste (image, drawables, GIMP_OBJECT (buffer),
|
||||
paste_type, x, y, width, height));
|
||||
paste_type, context, FALSE,
|
||||
x, y, width, height));
|
||||
|
||||
g_list_free (drawables);
|
||||
gimp_display_shell_dnd_flush (shell, image);
|
||||
|
|
|
@ -278,6 +278,7 @@ edit_paste_invoker (GimpProcedure *procedure,
|
|||
paste_into ?
|
||||
GIMP_PASTE_TYPE_FLOATING_INTO :
|
||||
GIMP_PASTE_TYPE_FLOATING,
|
||||
context, FALSE,
|
||||
-1, -1, -1, -1);
|
||||
g_list_free (drawables);
|
||||
|
||||
|
@ -595,6 +596,7 @@ edit_named_paste_invoker (GimpProcedure *procedure,
|
|||
paste_into ?
|
||||
GIMP_PASTE_TYPE_FLOATING_INTO :
|
||||
GIMP_PASTE_TYPE_FLOATING,
|
||||
context, FALSE,
|
||||
-1, -1, -1, -1);
|
||||
g_list_free (drawables);
|
||||
|
||||
|
|
|
@ -197,6 +197,8 @@
|
|||
<menuitem action="edit-paste-in-place" />
|
||||
</placeholder>
|
||||
<menu action="edit-paste-as-menu" name="Paste as">
|
||||
<menuitem action="edit-paste-merged" />
|
||||
<menuitem action="edit-paste-merged-in-place" />
|
||||
<menuitem action="edit-paste-into" />
|
||||
<menuitem action="edit-paste-into-in-place" />
|
||||
<menuitem action="edit-paste-as-new-image-short" />
|
||||
|
|
|
@ -287,6 +287,7 @@ HELP
|
|||
paste_into ?
|
||||
GIMP_PASTE_TYPE_FLOATING_INTO :
|
||||
GIMP_PASTE_TYPE_FLOATING,
|
||||
context, FALSE,
|
||||
-1, -1, -1, -1);
|
||||
g_list_free (drawables);
|
||||
|
||||
|
@ -614,6 +615,7 @@ HELP
|
|||
paste_into ?
|
||||
GIMP_PASTE_TYPE_FLOATING_INTO :
|
||||
GIMP_PASTE_TYPE_FLOATING,
|
||||
context, FALSE,
|
||||
-1, -1, -1, -1);
|
||||
g_list_free (drawables);
|
||||
|
||||
|
|
Loading…
Reference in New Issue