2006-12-09 21:33:38 +00:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-24 22:05:25 +00:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-17 22:28:01 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
1997-11-24 22:05:25 +00:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-17 22:28:01 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
1997-11-24 22:05:25 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2018-07-11 23:27:07 +02:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
1997-11-24 22:05:25 +00:00
|
|
|
*/
|
2000-12-16 21:37:03 +00:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2012-03-16 00:02:27 +01:00
|
|
|
#include <cairo.h>
|
2008-10-09 20:24:04 +00:00
|
|
|
#include <gegl.h>
|
2012-05-03 03:36:22 +02:00
|
|
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
2001-01-24 22:36:18 +00:00
|
|
|
|
2006-08-29 14:46:32 +00:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2012-03-16 00:02:27 +01:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
2006-08-29 14:46:32 +00:00
|
|
|
|
2001-07-04 19:31:35 +00:00
|
|
|
#include "core-types.h"
|
2000-12-16 21:37:03 +00:00
|
|
|
|
2001-07-04 19:31:35 +00:00
|
|
|
#include "gimp.h"
|
2003-09-15 17:26:28 +00:00
|
|
|
#include "gimp-edit.h"
|
2001-07-03 18:38:56 +00:00
|
|
|
#include "gimpbuffer.h"
|
|
|
|
#include "gimpcontext.h"
|
2022-11-10 22:41:27 +01:00
|
|
|
#include "gimpdrawable-edit.h"
|
2019-01-02 00:14:35 +01:00
|
|
|
#include "gimpgrouplayer.h"
|
2001-07-03 18:38:56 +00:00
|
|
|
#include "gimpimage.h"
|
2017-05-01 19:10:52 +02:00
|
|
|
#include "gimpimage-duplicate.h"
|
2016-09-19 23:53:40 +02:00
|
|
|
#include "gimpimage-new.h"
|
2003-02-13 11:23:50 +00:00
|
|
|
#include "gimpimage-undo.h"
|
2016-05-20 16:46:26 +02:00
|
|
|
#include "gimplayer-floating-selection.h"
|
2015-06-17 13:21:01 +02:00
|
|
|
#include "gimplayer-new.h"
|
2022-10-29 18:53:44 +00:00
|
|
|
#include "gimplayermask.h"
|
2001-07-03 18:38:56 +00:00
|
|
|
#include "gimplist.h"
|
2006-03-02 19:30:59 +00:00
|
|
|
#include "gimppickable.h"
|
2003-10-06 12:17:11 +00:00
|
|
|
#include "gimpselection.h"
|
2001-07-03 18:38:56 +00:00
|
|
|
|
2003-03-25 16:38:19 +00:00
|
|
|
#include "gimp-intl.h"
|
1998-11-23 14:47:09 +00:00
|
|
|
|
1998-01-22 07:02:57 +00:00
|
|
|
|
2003-10-08 17:20:06 +00:00
|
|
|
/* local function protypes */
|
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
static GimpBuffer * gimp_edit_extract (GimpImage *image,
|
|
|
|
GList *pickables,
|
|
|
|
GimpContext *context,
|
|
|
|
gboolean cut_pixels,
|
|
|
|
GError **error);
|
|
|
|
static GimpDrawable * gimp_edit_paste_get_top_item (GList *drawables);
|
2003-10-08 17:20:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
2016-09-19 23:53:40 +02:00
|
|
|
GimpObject *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_cut (GimpImage *image,
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *drawables,
|
2007-12-14 13:58:10 +00:00
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
1997-11-24 22:05:25 +00:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *iter;
|
|
|
|
gboolean cut_layers = FALSE;
|
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2004-04-14 23:37:34 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
1997-11-24 22:05:25 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
if (gimp_channel_is_empty (gimp_image_get_mask (image)))
|
|
|
|
{
|
|
|
|
cut_layers = TRUE;
|
|
|
|
|
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
if (! GIMP_IS_LAYER (iter->data))
|
|
|
|
{
|
|
|
|
cut_layers = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cut_layers)
|
2016-09-19 23:53:40 +02:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *remove = NULL;
|
2016-09-19 23:53:40 +02:00
|
|
|
GimpImage *clip_image;
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
gchar *undo_label;
|
2017-11-12 18:41:05 +01:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
/* Let's work on a copy because we will edit the list to remove
|
|
|
|
* layers whose ancestor is also cut.
|
|
|
|
*/
|
|
|
|
drawables = g_list_copy (drawables);
|
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
GList *iter2;
|
2005-09-05 18:21:51 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
for (iter2 = drawables; iter2; iter2 = iter2->next)
|
|
|
|
{
|
|
|
|
if (iter2 == iter)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (gimp_viewable_is_ancestor (iter2->data, iter->data))
|
|
|
|
{
|
|
|
|
/* When cutting a layer group, all its children come
|
|
|
|
* with anyway.
|
|
|
|
*/
|
|
|
|
remove = g_list_prepend (remove, iter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (iter = remove; iter; iter = iter->next)
|
|
|
|
drawables = g_list_delete_link (drawables, iter->data);
|
|
|
|
|
|
|
|
g_list_free (remove);
|
|
|
|
|
|
|
|
/* Now copy all layers into the clipboard image. */
|
app: rework and fix the logic for copy-pasting multiple drawables.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
2022-11-12 18:28:58 +01:00
|
|
|
clip_image = gimp_image_new_from_drawables (image->gimp, drawables, FALSE, TRUE);
|
2016-09-19 23:53:40 +02:00
|
|
|
gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
|
|
|
|
gimp_set_clipboard_image (image->gimp, clip_image);
|
|
|
|
g_object_unref (clip_image);
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
undo_label = g_strdup_printf (ngettext ("Cut Layer", "Cut %d Layers",
|
|
|
|
g_list_length (drawables)),
|
|
|
|
g_list_length (drawables));
|
2016-09-19 23:53:40 +02:00
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT,
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
undo_label);
|
|
|
|
g_free (undo_label);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
/* Remove layers from source image. */
|
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
gimp_image_remove_layer (image, GIMP_LAYER (iter->data),
|
|
|
|
TRUE, NULL);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
|
|
|
gimp_image_undo_group_end (image);
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
g_list_free (drawables);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
|
|
|
return GIMP_OBJECT (gimp_get_clipboard_image (image->gimp));
|
|
|
|
}
|
|
|
|
else
|
2005-09-05 18:21:51 +00:00
|
|
|
{
|
2016-09-19 23:53:40 +02:00
|
|
|
GimpBuffer *buffer;
|
2005-09-05 18:21:51 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
buffer = gimp_edit_extract (image, drawables, context, TRUE, error);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
|
|
|
gimp_set_clipboard_buffer (image->gimp, buffer);
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return GIMP_OBJECT (gimp_get_clipboard_buffer (image->gimp));
|
|
|
|
}
|
2005-09-05 18:21:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
1997-11-24 22:05:25 +00:00
|
|
|
}
|
|
|
|
|
2016-09-19 23:53:40 +02:00
|
|
|
GimpObject *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_copy (GimpImage *image,
|
2020-05-06 15:46:51 +02:00
|
|
|
GList *drawables,
|
2007-12-14 13:58:10 +00:00
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
1997-11-24 22:05:25 +00:00
|
|
|
{
|
2020-05-06 15:46:51 +02:00
|
|
|
GList *iter;
|
|
|
|
gboolean drawables_are_layers = TRUE;
|
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2020-05-06 15:46:51 +02:00
|
|
|
g_return_val_if_fail (drawables != NULL, NULL);
|
2004-04-14 23:37:34 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
1997-11-24 22:05:25 +00:00
|
|
|
|
2020-05-06 15:46:51 +02:00
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
2016-09-19 23:53:40 +02:00
|
|
|
{
|
2020-05-06 15:46:51 +02:00
|
|
|
g_return_val_if_fail (GIMP_IS_DRAWABLE (iter->data), NULL);
|
|
|
|
g_return_val_if_fail (gimp_item_is_attached (iter->data), NULL);
|
|
|
|
|
|
|
|
if (! GIMP_IS_LAYER (iter->data))
|
|
|
|
drawables_are_layers = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only accept multiple drawables for layers. */
|
|
|
|
g_return_val_if_fail (g_list_length (drawables) == 1 || drawables_are_layers, NULL);
|
|
|
|
|
2022-11-10 22:41:27 +01:00
|
|
|
if (drawables_are_layers)
|
2020-05-06 15:46:51 +02:00
|
|
|
{
|
|
|
|
/* Special-casing the 1 layer with no selection case.
|
|
|
|
* It allows us to save the whole layer with all pixels as stored,
|
|
|
|
* not the rendered version of it.
|
|
|
|
*/
|
2022-11-10 22:41:27 +01:00
|
|
|
GimpImage *clip_image;
|
|
|
|
GimpChannel *clip_selection;
|
2005-09-05 18:21:51 +00:00
|
|
|
|
app: rework and fix the logic for copy-pasting multiple drawables.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
2022-11-12 18:28:58 +01:00
|
|
|
clip_image = gimp_image_new_from_drawables (image->gimp, drawables, TRUE, TRUE);
|
2016-09-19 23:53:40 +02:00
|
|
|
gimp_container_remove (image->gimp->images, GIMP_OBJECT (clip_image));
|
|
|
|
gimp_set_clipboard_image (image->gimp, clip_image);
|
|
|
|
g_object_unref (clip_image);
|
|
|
|
|
2022-11-10 22:41:27 +01:00
|
|
|
clip_selection = gimp_image_get_mask (clip_image);
|
|
|
|
if (! gimp_channel_is_empty (clip_selection))
|
|
|
|
{
|
|
|
|
GList *all_items;
|
|
|
|
GeglRectangle selection_bounds;
|
2020-05-06 15:46:51 +02:00
|
|
|
|
2022-11-10 22:41:27 +01:00
|
|
|
gimp_item_bounds (GIMP_ITEM (clip_selection),
|
|
|
|
&selection_bounds.x, &selection_bounds.y,
|
|
|
|
&selection_bounds.width, &selection_bounds.height);
|
2020-05-06 15:46:51 +02:00
|
|
|
|
2022-11-10 22:41:27 +01:00
|
|
|
/* Invert the selection. */
|
|
|
|
gimp_channel_invert (clip_selection, FALSE);
|
|
|
|
all_items = gimp_image_get_layer_list (clip_image);
|
|
|
|
|
|
|
|
for (iter = all_items; iter; iter = g_list_next (iter))
|
|
|
|
{
|
app: copying from selection creates layers the size of the selection.
After further discussions with Aryeom, we had to make decisions about a few
problems. The main problem was: what happens when we copy a selection of a layer
whose bounds don't intersect with the selection?
The silent treatment of discarding the layer was not acceptable, because e.g. it
could happen on huge set of selected layers (like say you copy 100 layers with a
selection: you expect 100 created layers and if you realize you don't have them
all — e.g. you have 99! — after hours of work, trying to find the missing one
can be a huge time loss).
The status bar notification (or even error) did not feel right either because
this can typically be missed easily. Also it doesn't give a lot of feedback
(e.g. you might want hint to find the non-intersecting layers, in case it was
not supposed to happen).
An error box was even considered, possibly proposing to ignore the problematic
layers, or even giving easy ways to find them.
Finally what if we let the selection happen regardless the non-intersecting
layers? What should the dimension and offset of said layers be?
In the end, we went with the more consistent behavior of always creating new
layers of the exact same size as the selection. It can be considered as a rule
which would make the behavior predictable. For the non-intersecting layers, we'd
just have new layers with the dimension/offset of the selection bounding box,
and no contents. For other layers, they'd be also this same dimension, possibly
increasing the dimension of the source layers (though any new pixel is fully
transparent obviously). Aryeom wondered if some people might absolutely need for
their workflow that the new layers stick to the origin bounding box. But we felt
it was enough of a stretch that we'd try this way for now.
Note: of course if some day we get infinite canvas/layers, this whole discussion
could be less of a problem anyway! This was Aryeom's conclusion! Ahahah!
2022-11-10 23:49:04 +01:00
|
|
|
gint item_x;
|
|
|
|
gint item_y;
|
2022-11-10 22:41:27 +01:00
|
|
|
|
|
|
|
gimp_item_get_offset (GIMP_ITEM (iter->data), &item_x, &item_y);
|
|
|
|
|
|
|
|
/* Even if the original layer may not have an alpha channel, the
|
|
|
|
* selected data must always have one. First because a selection
|
|
|
|
* is in some way an alpha channel when we copy (we may copy part
|
|
|
|
* of a pixel, i.e. with transparency). Second because the
|
|
|
|
* selection is not necessary rectangular, unlike layers. So when
|
|
|
|
* we will clear, if we hadn't added an alpha channel, we'd end up
|
|
|
|
* with background color all over the place.
|
|
|
|
*/
|
|
|
|
gimp_layer_add_alpha (GIMP_LAYER (iter->data));
|
|
|
|
gimp_drawable_edit_clear (GIMP_DRAWABLE (iter->data), context);
|
|
|
|
|
app: copying from selection creates layers the size of the selection.
After further discussions with Aryeom, we had to make decisions about a few
problems. The main problem was: what happens when we copy a selection of a layer
whose bounds don't intersect with the selection?
The silent treatment of discarding the layer was not acceptable, because e.g. it
could happen on huge set of selected layers (like say you copy 100 layers with a
selection: you expect 100 created layers and if you realize you don't have them
all — e.g. you have 99! — after hours of work, trying to find the missing one
can be a huge time loss).
The status bar notification (or even error) did not feel right either because
this can typically be missed easily. Also it doesn't give a lot of feedback
(e.g. you might want hint to find the non-intersecting layers, in case it was
not supposed to happen).
An error box was even considered, possibly proposing to ignore the problematic
layers, or even giving easy ways to find them.
Finally what if we let the selection happen regardless the non-intersecting
layers? What should the dimension and offset of said layers be?
In the end, we went with the more consistent behavior of always creating new
layers of the exact same size as the selection. It can be considered as a rule
which would make the behavior predictable. For the non-intersecting layers, we'd
just have new layers with the dimension/offset of the selection bounding box,
and no contents. For other layers, they'd be also this same dimension, possibly
increasing the dimension of the source layers (though any new pixel is fully
transparent obviously). Aryeom wondered if some people might absolutely need for
their workflow that the new layers stick to the origin bounding box. But we felt
it was enough of a stretch that we'd try this way for now.
Note: of course if some day we get infinite canvas/layers, this whole discussion
could be less of a problem anyway! This was Aryeom's conclusion! Ahahah!
2022-11-10 23:49:04 +01:00
|
|
|
/* Finally shrink the copied layer to selection bounds. */
|
2022-11-10 22:41:27 +01:00
|
|
|
gimp_item_resize (iter->data, context, GIMP_FILL_TRANSPARENT,
|
app: copying from selection creates layers the size of the selection.
After further discussions with Aryeom, we had to make decisions about a few
problems. The main problem was: what happens when we copy a selection of a layer
whose bounds don't intersect with the selection?
The silent treatment of discarding the layer was not acceptable, because e.g. it
could happen on huge set of selected layers (like say you copy 100 layers with a
selection: you expect 100 created layers and if you realize you don't have them
all — e.g. you have 99! — after hours of work, trying to find the missing one
can be a huge time loss).
The status bar notification (or even error) did not feel right either because
this can typically be missed easily. Also it doesn't give a lot of feedback
(e.g. you might want hint to find the non-intersecting layers, in case it was
not supposed to happen).
An error box was even considered, possibly proposing to ignore the problematic
layers, or even giving easy ways to find them.
Finally what if we let the selection happen regardless the non-intersecting
layers? What should the dimension and offset of said layers be?
In the end, we went with the more consistent behavior of always creating new
layers of the exact same size as the selection. It can be considered as a rule
which would make the behavior predictable. For the non-intersecting layers, we'd
just have new layers with the dimension/offset of the selection bounding box,
and no contents. For other layers, they'd be also this same dimension, possibly
increasing the dimension of the source layers (though any new pixel is fully
transparent obviously). Aryeom wondered if some people might absolutely need for
their workflow that the new layers stick to the origin bounding box. But we felt
it was enough of a stretch that we'd try this way for now.
Note: of course if some day we get infinite canvas/layers, this whole discussion
could be less of a problem anyway! This was Aryeom's conclusion! Ahahah!
2022-11-10 23:49:04 +01:00
|
|
|
selection_bounds.width, selection_bounds.height,
|
|
|
|
item_x - selection_bounds.x, item_y - selection_bounds.y);
|
2022-11-10 22:41:27 +01:00
|
|
|
}
|
|
|
|
g_list_free (all_items);
|
|
|
|
}
|
|
|
|
/* Remove selection from the clipboard image. */
|
|
|
|
gimp_channel_clear (clip_selection, NULL, FALSE);
|
2020-05-06 15:46:51 +02:00
|
|
|
|
2022-11-10 22:41:27 +01:00
|
|
|
return GIMP_OBJECT (gimp_get_clipboard_image (image->gimp));
|
2020-05-06 15:46:51 +02:00
|
|
|
}
|
2016-09-19 23:53:40 +02:00
|
|
|
else
|
2005-09-05 18:21:51 +00:00
|
|
|
{
|
2016-09-19 23:53:40 +02:00
|
|
|
GimpBuffer *buffer;
|
2005-09-05 18:21:51 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
buffer = gimp_edit_extract (image, drawables, context, FALSE, error);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
|
|
|
gimp_set_clipboard_buffer (image->gimp, buffer);
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return GIMP_OBJECT (gimp_get_clipboard_buffer (image->gimp));
|
|
|
|
}
|
2005-09-05 18:21:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
1997-11-24 22:05:25 +00:00
|
|
|
}
|
|
|
|
|
2016-05-19 23:51:44 +02:00
|
|
|
GimpBuffer *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_copy_visible (GimpImage *image,
|
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
2004-12-12 14:01:08 +00:00
|
|
|
{
|
2013-09-13 23:29:06 +02:00
|
|
|
GimpBuffer *buffer;
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *pickables;
|
2004-12-12 14:01:08 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2004-12-12 14:01:08 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
2004-12-12 14:01:08 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
pickables = g_list_prepend (NULL, image);
|
|
|
|
buffer = gimp_edit_extract (image, pickables, context, FALSE, error);
|
|
|
|
g_list_free (pickables);
|
2004-12-12 14:01:08 +00:00
|
|
|
|
2005-09-05 18:21:51 +00:00
|
|
|
if (buffer)
|
|
|
|
{
|
2016-09-17 17:39:54 +02:00
|
|
|
gimp_set_clipboard_buffer (image->gimp, buffer);
|
2005-09-05 18:21:51 +00:00
|
|
|
g_object_unref (buffer);
|
2004-12-12 14:01:08 +00:00
|
|
|
|
2016-09-17 17:39:54 +02:00
|
|
|
return gimp_get_clipboard_buffer (image->gimp);
|
2005-09-05 18:21:51 +00:00
|
|
|
}
|
2004-12-12 14:01:08 +00:00
|
|
|
|
2005-09-05 18:21:51 +00:00
|
|
|
return NULL;
|
2004-12-12 14:01:08 +00:00
|
|
|
}
|
|
|
|
|
2018-03-24 12:43:30 -04:00
|
|
|
static gboolean
|
|
|
|
gimp_edit_paste_is_in_place (GimpPasteType paste_type)
|
|
|
|
{
|
|
|
|
switch (paste_type)
|
|
|
|
{
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER:
|
2022-10-29 18:53:44 +00:00
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
2018-03-24 12:43:30 -04:00
|
|
|
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:
|
2022-10-29 18:53:44 +00:00
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
2018-03-24 12:43:30 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_return_val_if_reached (FALSE);
|
|
|
|
}
|
|
|
|
|
2019-05-25 17:05:49 +02:00
|
|
|
static gboolean
|
2022-10-29 18:53:44 +00:00
|
|
|
gimp_edit_paste_is_floating (GimpPasteType paste_type,
|
|
|
|
GimpDrawable *drawable)
|
2019-05-25 17:05:49 +02:00
|
|
|
{
|
|
|
|
switch (paste_type)
|
|
|
|
{
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
|
|
|
|
return FALSE;
|
2022-10-29 18:53:44 +00:00
|
|
|
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
|
|
|
if (GIMP_IS_LAYER_MASK (drawable))
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2019-05-25 17:05:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
g_return_val_if_reached (FALSE);
|
|
|
|
}
|
|
|
|
|
app: rework and fix the logic for copy-pasting multiple drawables.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
2022-11-12 18:28:58 +01:00
|
|
|
static GList *
|
|
|
|
gimp_edit_paste_get_tagged_layers (GimpImage *image,
|
|
|
|
GList *layers,
|
|
|
|
GList *returned_layers,
|
|
|
|
const Babl *floating_format,
|
|
|
|
GimpImageBaseType base_type,
|
|
|
|
GimpPrecision precision,
|
|
|
|
GimpPasteType paste_type)
|
|
|
|
{
|
|
|
|
GList *iter;
|
|
|
|
|
|
|
|
for (iter = layers; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
GimpLayer *layer;
|
|
|
|
GType layer_type;
|
|
|
|
gboolean copied = TRUE;
|
|
|
|
|
|
|
|
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:
|
|
|
|
/* when pasting as floating make sure gimp_item_convert()
|
|
|
|
* will turn group layers into normal layers, otherwise use
|
|
|
|
* the same layer type so e.g. text information gets
|
|
|
|
* preserved. See issue #2667.
|
|
|
|
*/
|
|
|
|
if (GIMP_IS_GROUP_LAYER (iter->data))
|
|
|
|
layer_type = GIMP_TYPE_LAYER;
|
|
|
|
else
|
|
|
|
layer_type = G_TYPE_FROM_INSTANCE (iter->data);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
|
|
|
|
layer_type = G_TYPE_FROM_INSTANCE (iter->data);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_return_val_if_reached (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GIMP_IS_GROUP_LAYER (iter->data))
|
|
|
|
copied = (gboolean) GPOINTER_TO_INT (g_object_get_data (G_OBJECT (iter->data),
|
|
|
|
"gimp-image-copied-layer"));
|
|
|
|
if (copied)
|
|
|
|
{
|
|
|
|
layer = GIMP_LAYER (gimp_item_convert (GIMP_ITEM (iter->data),
|
|
|
|
image, layer_type));
|
|
|
|
returned_layers = g_list_prepend (returned_layers, layer);
|
|
|
|
|
|
|
|
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:
|
|
|
|
/* when pasting as floating selection, get rid of the layer mask,
|
|
|
|
* and make sure the layer has the right format
|
|
|
|
*/
|
|
|
|
if (gimp_layer_get_mask (iter->data))
|
|
|
|
gimp_layer_apply_mask (iter->data, GIMP_MASK_DISCARD, FALSE);
|
|
|
|
|
|
|
|
if (gimp_drawable_get_format (GIMP_DRAWABLE (iter->data)) !=
|
|
|
|
floating_format)
|
|
|
|
{
|
|
|
|
gimp_drawable_convert_type (GIMP_DRAWABLE (iter->data), image,
|
|
|
|
base_type, precision,
|
|
|
|
TRUE, NULL, NULL,
|
|
|
|
GEGL_DITHER_NONE, GEGL_DITHER_NONE,
|
|
|
|
FALSE, NULL);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GimpContainer *container;
|
|
|
|
|
|
|
|
container = gimp_viewable_get_children (iter->data);
|
|
|
|
returned_layers = gimp_edit_paste_get_tagged_layers (image,
|
|
|
|
GIMP_LIST (container)->queue->head,
|
|
|
|
returned_layers,
|
|
|
|
floating_format,
|
|
|
|
base_type, precision, paste_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return returned_layers;
|
|
|
|
}
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
static GList *
|
|
|
|
gimp_edit_paste_get_layers (GimpImage *image,
|
2022-11-09 17:01:44 +01:00
|
|
|
GList *drawables,
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GimpObject *paste,
|
|
|
|
GimpPasteType *paste_type)
|
2017-11-12 18:41:05 +01:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *layers = NULL;
|
2017-11-12 18:41:05 +01:00
|
|
|
const Babl *floating_format;
|
|
|
|
|
|
|
|
/* change paste type to NEW_LAYER for cases where we can't attach a
|
|
|
|
* floating selection
|
|
|
|
*/
|
2022-11-09 17:01:44 +01:00
|
|
|
if (g_list_length (drawables) != 1 ||
|
|
|
|
gimp_viewable_get_children (drawables->data) ||
|
|
|
|
gimp_item_is_content_locked (drawables->data, NULL))
|
2017-11-12 18:41:05 +01:00
|
|
|
{
|
2018-03-24 12:43:30 -04:00
|
|
|
if (gimp_edit_paste_is_in_place (*paste_type))
|
|
|
|
*paste_type = GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE;
|
|
|
|
else
|
|
|
|
*paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* floating pastes always have the pasted-to drawable's format with
|
|
|
|
* alpha; if drawable == NULL, user is pasting into an empty image
|
|
|
|
*/
|
2022-11-09 17:01:44 +01:00
|
|
|
if (drawables && gimp_edit_paste_is_floating (*paste_type, drawables->data))
|
|
|
|
floating_format = gimp_drawable_get_format_with_alpha (drawables->data);
|
2017-11-12 18:41:05 +01:00
|
|
|
else
|
|
|
|
floating_format = gimp_image_get_layer_format (image, TRUE);
|
|
|
|
|
|
|
|
if (GIMP_IS_IMAGE (paste))
|
|
|
|
{
|
app: rework and fix the logic for copy-pasting multiple drawables.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
2022-11-12 18:28:58 +01:00
|
|
|
layers = gimp_image_get_layer_iter (GIMP_IMAGE (paste));
|
2017-11-12 18:41:05 +01:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
if (g_list_length (layers) > 1)
|
2017-11-12 18:41:05 +01:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
if (gimp_edit_paste_is_in_place (*paste_type))
|
|
|
|
*paste_type = GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE;
|
2019-01-02 00:14:35 +01:00
|
|
|
else
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
*paste_type = GIMP_PASTE_TYPE_NEW_LAYER;
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
|
app: rework and fix the logic for copy-pasting multiple drawables.
There were a lot of incertainty of what should happen when we copy layers being
descendant of each other (i.e. when you select a group layer and some of its
children), then when you paste such data. So we sat down with Aryeom and tried
to come up with some consistent behavior which is somewhat expectable, but also
which would allow the most use-case.
Otherwise it was making very weird result when pasting the data, duplicating
some layers and whatnot, which was obviously a buggy behavior and never the
expected result.
We decided that if you select one leaf item, then even if you also selected a
parent item, it would be as though the parent was not selected. This is very
often what you expect anyway when you select a whole bunch of layers and would
work well if, say, you shift-click over many layers in sub-groups. Then you
wouldn't have to manually ctrl-click to unselect every group.
Then what if you were instead expecting to copy many groups? Then you could
shift-click the group arrow, closing all same-level groups. Once they are all
closed, you can shift-click the groups to only select group layers, not their
contents.
This way, both use cases are still quite doable easily with this default choice.
2022-11-12 18:28:58 +01:00
|
|
|
layers = gimp_edit_paste_get_tagged_layers (image, layers, NULL, floating_format,
|
|
|
|
gimp_drawable_get_base_type (drawables->data),
|
|
|
|
gimp_drawable_get_precision (drawables->data),
|
|
|
|
*paste_type);
|
|
|
|
layers = g_list_reverse (layers);
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
else if (GIMP_IS_BUFFER (paste))
|
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GimpLayer *layer;
|
|
|
|
|
2017-11-12 18:41:05 +01:00
|
|
|
layer = gimp_layer_new_from_buffer (GIMP_BUFFER (paste), image,
|
|
|
|
floating_format,
|
|
|
|
_("Pasted Layer"),
|
|
|
|
GIMP_OPACITY_OPAQUE,
|
|
|
|
gimp_image_get_default_new_layer_mode (image));
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
|
|
|
|
layers = g_list_prepend (layers, layer);
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
return layers;
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gimp_edit_paste_get_viewport_offset (GimpImage *image,
|
|
|
|
GList *drawables,
|
|
|
|
GList *pasted_layers,
|
|
|
|
gint viewport_x,
|
|
|
|
gint viewport_y,
|
|
|
|
gint viewport_width,
|
|
|
|
gint viewport_height,
|
|
|
|
gint *pasted_bbox_x,
|
|
|
|
gint *pasted_bbox_y,
|
|
|
|
gint *offset_x,
|
|
|
|
gint *offset_y)
|
1997-11-24 22:05:25 +00:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *iter;
|
2016-09-19 17:30:41 +02:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
/* Source: pasted layers */
|
|
|
|
gint source_width;
|
|
|
|
gint source_height;
|
|
|
|
|
|
|
|
gint x1 = G_MAXINT;
|
|
|
|
gint y1 = G_MAXINT;
|
|
|
|
gint x2 = G_MININT;
|
|
|
|
gint y2 = G_MININT;
|
2016-09-19 17:30:41 +02:00
|
|
|
gboolean clamp_to_image = TRUE;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_IMAGE (image));
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
g_return_if_fail (pasted_layers != NULL);
|
2016-09-19 17:30:41 +02:00
|
|
|
g_return_if_fail (offset_x != NULL);
|
|
|
|
g_return_if_fail (offset_y != NULL);
|
1997-11-24 22:05:25 +00:00
|
|
|
|
2012-07-30 16:20:11 +02:00
|
|
|
image_width = gimp_image_get_width (image);
|
|
|
|
image_height = gimp_image_get_height (image);
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
for (iter = pasted_layers; iter; iter = iter->next)
|
|
|
|
{
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gint layer_off_x;
|
|
|
|
gint layer_off_y;
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
gint layer_width;
|
|
|
|
gint layer_height;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_VIEWABLE (iter->data));
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
|
|
|
|
gimp_item_get_offset (GIMP_ITEM (iter->data), &layer_off_x, &layer_off_y);
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
gimp_viewable_get_size (iter->data, &layer_width, &layer_height);
|
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
x1 = MIN (layer_off_x, x1);
|
|
|
|
y1 = MIN (layer_off_y, y1);
|
|
|
|
x2 = MAX (layer_off_x + layer_width, x2);
|
|
|
|
y2 = MAX (layer_off_y + layer_height, y2);
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
}
|
2012-07-30 16:20:11 +02:00
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
/* Source offset and dimensions: this is the bounding box for all layers which
|
|
|
|
* we want to paste together, keeping their relative position to each others.
|
|
|
|
*/
|
|
|
|
*pasted_bbox_x = x1;
|
|
|
|
*pasted_bbox_y = y1;
|
|
|
|
source_width = x2 - x1;
|
|
|
|
source_height = y2 - y1;
|
|
|
|
|
2012-07-30 16:20:11 +02:00
|
|
|
if (viewport_width == image_width &&
|
|
|
|
viewport_height == image_height)
|
|
|
|
{
|
|
|
|
/* if the whole image is visible, act as if there was no viewport */
|
|
|
|
|
|
|
|
viewport_x = 0;
|
|
|
|
viewport_y = 0;
|
|
|
|
viewport_width = 0;
|
|
|
|
viewport_height = 0;
|
|
|
|
}
|
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
if (drawables)
|
2001-06-26 12:09:43 +00:00
|
|
|
{
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
/* if pasting while 1 or more drawables are selected */
|
|
|
|
gboolean empty_target = TRUE;
|
|
|
|
gint target_x;
|
|
|
|
gint target_y;
|
|
|
|
gint target_width;
|
|
|
|
gint target_height;
|
|
|
|
gint paste_x, paste_y;
|
|
|
|
gint paste_width;
|
|
|
|
gint paste_height;
|
|
|
|
gboolean have_mask;
|
2022-11-09 17:01:44 +01:00
|
|
|
|
2016-09-21 00:53:42 +02:00
|
|
|
have_mask = ! gimp_channel_is_empty (gimp_image_get_mask (image));
|
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
GimpContainer *children;
|
2016-09-21 09:22:30 +02:00
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
children = gimp_viewable_get_children (iter->data);
|
|
|
|
if (! children || gimp_container_get_n_children (children) > 0)
|
|
|
|
{
|
|
|
|
empty_target = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-09-21 09:22:30 +02:00
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
if (empty_target)
|
2016-09-21 09:22:30 +02:00
|
|
|
{
|
|
|
|
/* treat empty layer groups as image-sized, use the selection
|
|
|
|
* as target
|
|
|
|
*/
|
|
|
|
gimp_item_bounds (GIMP_ITEM (gimp_image_get_mask (image)),
|
|
|
|
&target_x, &target_y,
|
|
|
|
&target_width, &target_height);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gint x1 = G_MAXINT;
|
|
|
|
gint y1 = G_MAXINT;
|
|
|
|
gint x2 = G_MININT;
|
|
|
|
gint y2 = G_MININT;
|
|
|
|
|
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
gint layer_off_x;
|
|
|
|
gint layer_off_y;
|
|
|
|
gint mask_off_x;
|
|
|
|
gint mask_off_y;
|
|
|
|
gint mask_width;
|
|
|
|
gint mask_height;
|
|
|
|
|
|
|
|
gimp_item_get_offset (GIMP_ITEM (iter->data), &layer_off_x, &layer_off_y);
|
|
|
|
/* This is the bounds relatively to the drawable. */
|
|
|
|
gimp_item_mask_intersect (GIMP_ITEM (iter->data),
|
|
|
|
&mask_off_x, &mask_off_y,
|
|
|
|
&mask_width, &mask_height);
|
|
|
|
|
|
|
|
/* The bounds relatively to the image. */
|
|
|
|
x1 = MIN (layer_off_x + mask_off_x, x1);
|
|
|
|
y1 = MIN (layer_off_y + mask_off_y, y1);
|
|
|
|
x2 = MAX (layer_off_x + mask_off_x + mask_width, x2);
|
|
|
|
y2 = MAX (layer_off_y + mask_off_y + mask_height, y2);
|
|
|
|
}
|
|
|
|
|
|
|
|
target_x = x1;
|
|
|
|
target_y = y1;
|
|
|
|
target_width = x2 - x1;
|
|
|
|
target_height = y2 - y1;
|
2016-09-21 09:22:30 +02:00
|
|
|
}
|
2004-01-15 14:36:43 +00:00
|
|
|
|
2016-09-21 00:53:42 +02:00
|
|
|
if (! have_mask && /* if we have no mask */
|
|
|
|
viewport_width > 0 && /* and we have a viewport */
|
2004-01-15 14:36:43 +00:00
|
|
|
viewport_height > 0 &&
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
(source_width < target_width || /* and the paste is smaller than the target */
|
|
|
|
source_height < target_height) &&
|
2012-07-30 16:20:11 +02:00
|
|
|
|
|
|
|
/* and the viewport intersects with the target */
|
2004-01-15 14:36:43 +00:00
|
|
|
gimp_rectangle_intersect (viewport_x, viewport_y,
|
|
|
|
viewport_width, viewport_height,
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
target_x, target_x,
|
2016-09-21 00:53:42 +02:00
|
|
|
target_width, target_height,
|
2004-01-15 14:36:43 +00:00
|
|
|
&paste_x, &paste_y,
|
|
|
|
&paste_width, &paste_height))
|
|
|
|
{
|
2012-07-30 16:20:11 +02:00
|
|
|
/* center on the viewport */
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
*offset_x = viewport_x + (viewport_width - source_width) / 2;
|
|
|
|
*offset_y = viewport_y + (viewport_height- source_height) / 2;
|
2004-01-15 14:36:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-07-30 16:20:11 +02:00
|
|
|
/* otherwise center on the target */
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
*offset_x = target_x + (target_width - source_width) / 2;
|
|
|
|
*offset_y = target_y + (target_height - source_height) / 2;
|
2012-07-30 16:20:11 +02:00
|
|
|
|
|
|
|
/* and keep it that way */
|
|
|
|
clamp_to_image = FALSE;
|
2004-01-15 14:36:43 +00:00
|
|
|
}
|
|
|
|
}
|
2012-07-30 16:20:11 +02:00
|
|
|
else if (viewport_width > 0 && /* if we have a viewport */
|
|
|
|
viewport_height > 0 &&
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
(source_width < image_width || /* and the paste is */
|
|
|
|
source_height < image_height)) /* smaller than the image */
|
2004-01-15 14:36:43 +00:00
|
|
|
{
|
2012-07-30 16:20:11 +02:00
|
|
|
/* center on the viewport */
|
2004-01-15 14:36:43 +00:00
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
*offset_x = viewport_x + (viewport_width - source_width) / 2;
|
|
|
|
*offset_y = viewport_y + (viewport_height - source_height) / 2;
|
2001-06-26 12:09:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-07-30 16:20:11 +02:00
|
|
|
/* otherwise center on the image */
|
1997-11-24 22:05:25 +00:00
|
|
|
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
*offset_x = (image_width - source_width) / 2;
|
|
|
|
*offset_y = (image_height - source_height) / 2;
|
2004-09-17 09:14:02 +00:00
|
|
|
|
2012-07-30 16:20:11 +02:00
|
|
|
/* and keep it that way */
|
|
|
|
clamp_to_image = FALSE;
|
|
|
|
}
|
2004-09-17 09:14:02 +00:00
|
|
|
|
2012-07-30 16:20:11 +02:00
|
|
|
if (clamp_to_image)
|
|
|
|
{
|
|
|
|
/* Ensure that the pasted layer is always within the image, if it
|
|
|
|
* fits and aligned at top left if it doesn't. (See bug #142944).
|
|
|
|
*/
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
*offset_x = MIN (*offset_x, image_width - source_width);
|
|
|
|
*offset_y = MIN (*offset_y, image_height - source_height);
|
2016-09-19 17:30:41 +02:00
|
|
|
*offset_x = MAX (*offset_x, 0);
|
|
|
|
*offset_y = MAX (*offset_y, 0);
|
2012-07-30 16:20:11 +02:00
|
|
|
}
|
2016-09-19 17:30:41 +02:00
|
|
|
}
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
static GList *
|
2017-11-12 18:41:05 +01:00
|
|
|
gimp_edit_paste_paste (GimpImage *image,
|
2022-11-09 17:01:44 +01:00
|
|
|
GList *drawables,
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *layers,
|
2017-11-12 18:41:05 +01:00
|
|
|
GimpPasteType paste_type,
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
gboolean use_offset,
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gint layers_bbox_x,
|
|
|
|
gint layers_bbox_y,
|
2017-11-12 18:41:05 +01:00
|
|
|
gint offset_x,
|
|
|
|
gint offset_y)
|
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *iter;
|
2001-03-30 11:16:05 +00:00
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
g_return_val_if_fail (paste_type > GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE ||
|
|
|
|
g_list_length (drawables) == 1, NULL);
|
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
|
2010-06-08 14:24:11 +03:00
|
|
|
C_("undo-type", "Paste"));
|
2004-10-19 22:52:04 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
for (iter = layers; iter; iter = iter->next)
|
2016-09-19 23:53:40 +02:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
/* Layers for in-place paste are already translated. */
|
|
|
|
if (use_offset)
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gimp_item_translate (GIMP_ITEM (iter->data),
|
|
|
|
offset_x - layers_bbox_x,
|
|
|
|
offset_y - layers_bbox_y, FALSE);
|
1997-11-24 22:05:25 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
switch (paste_type)
|
|
|
|
{
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_IN_PLACE:
|
|
|
|
/* if there is a selection mask clear it - this might not
|
|
|
|
* always be desired, but in general, it seems like the correct
|
|
|
|
* behavior
|
|
|
|
*/
|
|
|
|
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
|
|
|
|
gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);
|
2016-09-19 23:53:40 +02:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
/* fall thru */
|
2016-09-19 23:53:40 +02:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
case GIMP_PASTE_TYPE_FLOATING_INTO:
|
|
|
|
case GIMP_PASTE_TYPE_FLOATING_INTO_IN_PLACE:
|
2022-11-09 17:01:44 +01:00
|
|
|
floating_sel_attach (iter->data, drawables->data);
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
break;
|
2016-09-21 11:15:34 +02:00
|
|
|
|
2022-10-29 18:53:44 +00:00
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_OR_FLOATING_IN_PLACE:
|
2022-11-09 17:01:44 +01:00
|
|
|
if (g_list_length (drawables) == 1 && GIMP_IS_LAYER_MASK (drawables->data))
|
2022-10-29 18:53:44 +00:00
|
|
|
{
|
|
|
|
if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
|
|
|
|
gimp_channel_clear (gimp_image_get_mask (image), NULL, TRUE);
|
2022-11-09 17:01:44 +01:00
|
|
|
floating_sel_attach (iter->data, drawables->data);
|
2022-10-29 18:53:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fall thru if not a layer mask */
|
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER:
|
|
|
|
case GIMP_PASTE_TYPE_NEW_LAYER_IN_PLACE:
|
|
|
|
{
|
|
|
|
GimpLayer *parent = NULL;
|
|
|
|
gint position = 0;
|
|
|
|
|
|
|
|
/* always add on top of a passed layer, where we would attach
|
|
|
|
* a floating selection
|
|
|
|
*/
|
2022-11-09 17:01:44 +01:00
|
|
|
if (g_list_length (drawables) > 0 && GIMP_IS_LAYER (drawables->data))
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
{
|
2022-11-09 17:01:44 +01:00
|
|
|
GimpDrawable *top_drawable;
|
|
|
|
|
|
|
|
top_drawable = gimp_edit_paste_get_top_item (drawables);
|
|
|
|
parent = gimp_layer_get_parent (GIMP_LAYER (top_drawable));
|
|
|
|
position = gimp_item_get_index (GIMP_ITEM (top_drawable));
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gimp_image_add_layer (image, iter->data, parent, position, TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-09-19 23:53:40 +02:00
|
|
|
}
|
2000-02-10 21:54:12 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_image_undo_group_end (image);
|
2001-06-26 12:09:43 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
return layers;
|
1997-11-24 22:05:25 +00:00
|
|
|
}
|
2000-01-16 09:34:45 +00:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *
|
2017-11-12 18:41:05 +01:00
|
|
|
gimp_edit_paste (GimpImage *image,
|
2022-11-09 17:01:44 +01:00
|
|
|
GList *drawables,
|
2017-11-12 18:41:05 +01:00
|
|
|
GimpObject *paste,
|
|
|
|
GimpPasteType paste_type,
|
|
|
|
gint viewport_x,
|
|
|
|
gint viewport_y,
|
|
|
|
gint viewport_width,
|
|
|
|
gint viewport_height)
|
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
GList *layers;
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
gboolean use_offset = FALSE;
|
|
|
|
gint layers_bbox_x = 0;
|
|
|
|
gint layers_bbox_y = 0;
|
|
|
|
gint offset_y = 0;
|
|
|
|
gint offset_x = 0;
|
2017-11-12 18:41:05 +01:00
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
|
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
for (GList *iter = drawables; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_DRAWABLE (iter->data), NULL);
|
|
|
|
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (iter->data)), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
layers = gimp_edit_paste_get_layers (image, drawables, paste, &paste_type);
|
2017-11-12 18:41:05 +01:00
|
|
|
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
if (! layers)
|
2017-11-12 18:41:05 +01:00
|
|
|
return NULL;
|
|
|
|
|
2018-03-24 12:43:30 -04:00
|
|
|
if (gimp_edit_paste_is_in_place (paste_type))
|
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
if (GIMP_IS_BUFFER (paste))
|
|
|
|
{
|
|
|
|
GimpBuffer *buffer = GIMP_BUFFER (paste);
|
|
|
|
|
|
|
|
use_offset = TRUE;
|
|
|
|
offset_x = buffer->offset_x;
|
|
|
|
offset_y = buffer->offset_y;
|
|
|
|
}
|
2018-03-24 12:43:30 -04:00
|
|
|
}
|
|
|
|
else
|
2017-11-12 18:41:05 +01:00
|
|
|
{
|
app, libgimp, pdb, plug-ins: allow pasting multiple full layers.
When a selection exists, we are copying then pasting the selection
contents. In particular, with multi-layer selection, it means pasting a
merged result of the selected layers (like a sample merged but limited
to selected layers).
Yet when no selection exists, with a single layer selected, a cut in
particular would remove the layer fully, then a paste would copy it
elsewhere (in the same image or even on a different image). This was
still working, but not with multiple layers. This is now fixed and we
can now copy/cut then paste several layers (without merge), which is
sometimes a very practical way to move layers (sometimes simpler than
drag'n drop, especially between images).
As a consequence, the PDB function gimp_edit_paste() now also returns an
array of layers (not a single layer).
2021-04-24 22:45:09 +02:00
|
|
|
use_offset = TRUE;
|
2022-11-09 17:01:44 +01:00
|
|
|
gimp_edit_paste_get_viewport_offset (image, drawables, layers,
|
2017-11-12 18:41:05 +01:00
|
|
|
viewport_x,
|
|
|
|
viewport_y,
|
|
|
|
viewport_width,
|
|
|
|
viewport_height,
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
&layers_bbox_x,
|
|
|
|
&layers_bbox_y,
|
2017-11-12 18:41:05 +01:00
|
|
|
&offset_x,
|
|
|
|
&offset_y);
|
|
|
|
}
|
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
return gimp_edit_paste_paste (image, drawables, layers, paste_type,
|
app: fix position of pasted data.
Position of pasted image data was getting very bad lately, especially with the
multi-item selection logic which confused the hell out of the legacy algorithm.
So I reviewed it a bit, in light of the multi-item abilities, as well as the
recent no-floating-selection paste changes.
One of the particularly wrong paste position was when pasting one or several
pieces (through selection) of existing layers. The positionning was really bad
and sometimes even off-canvas (which was explicitly forbidden by the algorithm,
except it was broken now).
Now the behavior is much more reliable and consistent, by centering on viewport
or on target drawables. If there are several such targets, their bounding box is
used as target position (and the bounding box of all source drawables is also
used now). An interesting consequence of this is that copy-pasting quickly
without removing a selection paste "in-place" since the target this time will
use the selection bounding box.
Aryeom and I are doing some work on specifying copy-paste (based on existing
logic, we tried not to disrupt too much years of logic, but also keeping
consistency and new logic for recent changes, such as multi-items). It will all
be written down into the GIMP developer website, section "Specifications".
2022-11-10 22:06:48 +01:00
|
|
|
use_offset, layers_bbox_x, layers_bbox_y,
|
|
|
|
offset_x, offset_y);
|
2017-11-12 18:41:05 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 19:10:52 +02:00
|
|
|
GimpImage *
|
|
|
|
gimp_edit_paste_as_new_image (Gimp *gimp,
|
|
|
|
GimpObject *paste)
|
|
|
|
{
|
|
|
|
GimpImage *image = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (paste) || GIMP_IS_BUFFER (paste), NULL);
|
|
|
|
|
|
|
|
if (GIMP_IS_IMAGE (paste))
|
|
|
|
{
|
|
|
|
image = gimp_image_duplicate (GIMP_IMAGE (paste));
|
|
|
|
}
|
|
|
|
else if (GIMP_IS_BUFFER (paste))
|
|
|
|
{
|
|
|
|
image = gimp_image_new_from_buffer (gimp, GIMP_BUFFER (paste));
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
2005-09-02 22:50:06 +00:00
|
|
|
const gchar *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_named_cut (GimpImage *image,
|
|
|
|
const gchar *name,
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *drawables,
|
2007-12-14 13:58:10 +00:00
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
2005-09-02 22:50:06 +00:00
|
|
|
{
|
2005-09-05 18:21:51 +00:00
|
|
|
GimpBuffer *buffer;
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
buffer = gimp_edit_extract (image, drawables, context, TRUE, error);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
2005-09-05 18:21:51 +00:00
|
|
|
gimp_object_set_name (GIMP_OBJECT (buffer), name);
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
|
2005-09-05 18:21:51 +00:00
|
|
|
g_object_unref (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2009-08-31 22:47:18 +02:00
|
|
|
return gimp_object_get_name (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_named_copy (GimpImage *image,
|
|
|
|
const gchar *name,
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *drawables,
|
2007-12-14 13:58:10 +00:00
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
2005-09-02 22:50:06 +00:00
|
|
|
{
|
2005-09-05 18:21:51 +00:00
|
|
|
GimpBuffer *buffer;
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
buffer = gimp_edit_extract (image, drawables, context, FALSE, error);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
2005-09-05 18:21:51 +00:00
|
|
|
gimp_object_set_name (GIMP_OBJECT (buffer), name);
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
|
2005-09-05 18:21:51 +00:00
|
|
|
g_object_unref (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2009-08-31 22:47:18 +02:00
|
|
|
return gimp_object_get_name (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const gchar *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_named_copy_visible (GimpImage *image,
|
|
|
|
const gchar *name,
|
|
|
|
GimpContext *context,
|
|
|
|
GError **error)
|
2005-09-02 22:50:06 +00:00
|
|
|
{
|
2013-09-13 23:29:06 +02:00
|
|
|
GimpBuffer *buffer;
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *pickables;
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
2007-12-14 13:58:10 +00:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
pickables = g_list_prepend (NULL, image);
|
|
|
|
buffer = gimp_edit_extract (image, pickables, context, FALSE, error);
|
|
|
|
g_list_free (pickables);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
2005-09-05 18:21:51 +00:00
|
|
|
gimp_object_set_name (GIMP_OBJECT (buffer), name);
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_container_add (image->gimp->named_buffers, GIMP_OBJECT (buffer));
|
2005-09-05 18:21:51 +00:00
|
|
|
g_object_unref (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
|
2009-08-31 22:47:18 +02:00
|
|
|
return gimp_object_get_name (buffer);
|
2005-09-02 22:50:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-10-08 17:20:06 +00:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
/**
|
|
|
|
* gimp_edit_extract:
|
|
|
|
* @image:
|
|
|
|
* @pickables:
|
|
|
|
* @context:
|
|
|
|
* @cut_pixels:
|
|
|
|
* @error:
|
|
|
|
*
|
|
|
|
* Extracts the selected part of @image from the list of @pickables.
|
|
|
|
* If @cut_pixels is %TRUE, and there is only one pickable input, and if
|
|
|
|
* this pickable is a #GimpDrawable, then the selected pixels will be
|
|
|
|
* effectively erased from the input pickable.
|
|
|
|
* Otherwise @cut_pixels has no additional effect.
|
|
|
|
* Note that all @pickables must belong to the same @image.
|
|
|
|
*
|
|
|
|
* Returns: a #GimpBuffer of the selected part of @image as if only the
|
|
|
|
* selected @pickables were present (composited according to their
|
|
|
|
* properties, unless there is only one pickable, in which case direct
|
|
|
|
* pixel information is used without composition).
|
|
|
|
*/
|
2005-09-05 18:21:51 +00:00
|
|
|
static GimpBuffer *
|
2007-12-14 13:58:10 +00:00
|
|
|
gimp_edit_extract (GimpImage *image,
|
2020-05-26 16:15:15 +02:00
|
|
|
GList *pickables,
|
2007-12-14 13:58:10 +00:00
|
|
|
GimpContext *context,
|
|
|
|
gboolean cut_pixels,
|
|
|
|
GError **error)
|
2003-12-09 16:20:31 +00:00
|
|
|
{
|
2012-03-21 14:38:19 +01:00
|
|
|
GeglBuffer *buffer;
|
|
|
|
gint offset_x;
|
|
|
|
gint offset_y;
|
2003-12-09 16:20:31 +00:00
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
g_return_val_if_fail (g_list_length (pickables) > 0, NULL);
|
|
|
|
|
|
|
|
if (g_list_length (pickables) > 1 ||
|
|
|
|
! GIMP_IS_DRAWABLE (pickables->data))
|
|
|
|
cut_pixels = FALSE;
|
|
|
|
|
2003-12-09 16:20:31 +00:00
|
|
|
if (cut_pixels)
|
2015-06-16 23:16:54 +02:00
|
|
|
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_CUT,
|
|
|
|
C_("undo-type", "Cut"));
|
2003-12-09 16:20:31 +00:00
|
|
|
|
2006-03-28 17:08:36 +00:00
|
|
|
/* Cut/copy the mask portion from the image */
|
2012-03-21 14:43:38 +01:00
|
|
|
buffer = gimp_selection_extract (GIMP_SELECTION (gimp_image_get_mask (image)),
|
2020-05-26 16:15:15 +02:00
|
|
|
pickables, context,
|
2012-03-21 14:43:38 +01:00
|
|
|
cut_pixels, FALSE, FALSE,
|
|
|
|
&offset_x, &offset_y, error);
|
2003-12-09 16:20:31 +00:00
|
|
|
|
|
|
|
if (cut_pixels)
|
2006-03-28 17:08:36 +00:00
|
|
|
gimp_image_undo_group_end (image);
|
2003-12-09 16:20:31 +00:00
|
|
|
|
2012-03-21 14:38:19 +01:00
|
|
|
if (buffer)
|
2010-03-19 09:52:29 +01:00
|
|
|
{
|
2017-05-01 18:36:33 +02:00
|
|
|
GimpBuffer *gimp_buffer;
|
|
|
|
gdouble res_x;
|
|
|
|
gdouble res_y;
|
|
|
|
|
|
|
|
gimp_buffer = gimp_buffer_new (buffer, _("Global Buffer"),
|
|
|
|
offset_x, offset_y, FALSE);
|
2012-03-21 14:38:19 +01:00
|
|
|
g_object_unref (buffer);
|
2012-03-14 23:09:36 +01:00
|
|
|
|
2017-05-01 18:36:33 +02:00
|
|
|
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));
|
|
|
|
|
2020-05-26 16:15:15 +02:00
|
|
|
if (GIMP_IS_COLOR_MANAGED (pickables->data))
|
2015-06-16 23:16:54 +02:00
|
|
|
{
|
2015-08-16 13:14:56 +02:00
|
|
|
GimpColorProfile *profile =
|
2020-05-26 16:15:15 +02:00
|
|
|
gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (pickables->data));
|
2015-06-16 23:16:54 +02:00
|
|
|
|
2015-09-03 01:36:02 +02:00
|
|
|
if (profile)
|
|
|
|
gimp_buffer_set_color_profile (gimp_buffer, profile);
|
2015-06-16 23:16:54 +02:00
|
|
|
}
|
|
|
|
|
2012-03-21 14:38:19 +01:00
|
|
|
return gimp_buffer;
|
2010-03-19 09:52:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2022-11-09 17:01:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the visually top item. */
|
|
|
|
static GimpDrawable *
|
|
|
|
gimp_edit_paste_get_top_item (GList *drawables)
|
|
|
|
{
|
|
|
|
GList *iter;
|
|
|
|
GimpDrawable *top = NULL;
|
|
|
|
GList *top_path = NULL;
|
|
|
|
|
|
|
|
for (iter = drawables; iter; iter = iter->next)
|
|
|
|
{
|
2022-11-10 23:29:23 +01:00
|
|
|
GList *path = gimp_item_get_path (iter->data);
|
|
|
|
|
2022-11-09 17:01:44 +01:00
|
|
|
if (top == NULL)
|
|
|
|
{
|
2022-11-10 23:29:23 +01:00
|
|
|
top = iter->data;
|
|
|
|
top_path = path;
|
|
|
|
path = NULL;
|
2022-11-09 17:01:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GList *p_iter;
|
|
|
|
GList *tp_iter;
|
|
|
|
|
|
|
|
for (p_iter = path, tp_iter = top_path; p_iter || tp_iter; p_iter = p_iter->next, tp_iter = tp_iter->next)
|
|
|
|
{
|
|
|
|
if (tp_iter == NULL)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (p_iter == NULL ||
|
|
|
|
GPOINTER_TO_UINT (p_iter->data) < GPOINTER_TO_UINT (tp_iter->data))
|
|
|
|
{
|
|
|
|
g_list_free (top_path);
|
|
|
|
top_path = path;
|
|
|
|
path = NULL;
|
|
|
|
top = iter->data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (GPOINTER_TO_UINT (p_iter->data) > GPOINTER_TO_UINT (tp_iter->data))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-10 23:29:23 +01:00
|
|
|
g_list_free (path);
|
2022-11-09 17:01:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (top_path);
|
|
|
|
return top;
|
|
|
|
}
|