core: Allow copy/pasting NDE filters

Previously, filters were lost when copying
individual layers. This patch copies them
to the clipboard image on cut or copy,
then copies them back to the pasted
image.
It also fixes an issue where filters would
be merged down if a selection was
copied instead of the entire layer.
This commit is contained in:
Alx Sa 2024-03-12 13:29:36 +00:00
parent 252f991cfb
commit dfb26f37e7
3 changed files with 103 additions and 0 deletions

View file

@ -33,10 +33,13 @@
#include "core/gimpcontainer.h"
#include "core/gimpdrawable.h"
#include "core/gimpdrawable-edit.h"
#include "core/gimpdrawable-filters.h"
#include "core/gimpdrawablefilter.h"
#include "core/gimpfilloptions.h"
#include "core/gimplayer.h"
#include "core/gimplayer-new.h"
#include "core/gimplayermask.h"
#include "core/gimplist.h"
#include "core/gimpimage.h"
#include "core/gimpimage-undo.h"
@ -718,6 +721,53 @@ edit_paste (GimpDisplay *display,
merged, x, y, width, height)))
{
gimp_image_set_selected_layers (image, pasted_layers);
/* Copy over layer effects */
if (GIMP_IS_IMAGE (paste))
{
GList *old_layers_list;
GList *new_layers_list;
old_layers_list = gimp_image_get_layer_iter (GIMP_IMAGE (paste));
for (new_layers_list = pasted_layers; new_layers_list;
new_layers_list = g_list_next (new_layers_list))
{
GimpLayer *layer = old_layers_list->data;
GimpLayer *new_layer = new_layers_list->data;
if (gimp_drawable_has_filters (GIMP_DRAWABLE (layer)))
{
GList *filter_list;
GimpContainer *filters;
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
for (filter_list = GIMP_LIST (filters)->queue->tail;
filter_list;
filter_list = g_list_previous (filter_list))
{
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
{
GimpDrawableFilter *old_filter = filter_list->data;
GimpDrawableFilter *filter;
filter =
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
old_filter);
gimp_drawable_filter_apply (filter, NULL);
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
gimp_drawable_filter_layer_mask_freeze (filter);
g_object_unref (filter);
}
}
}
old_layers_list = g_list_next (old_layers_list);
}
}
g_list_free (pasted_layers);
gimp_image_flush (image);
}

View file

@ -27,8 +27,10 @@
#include "gegl/gimp-gegl-loops.h"
#include "gimpchannel.h"
#include "core/gimpcontainer.h"
#include "gimpdrawable.h"
#include "gimpdrawable-edit.h"
#include "core/gimpdrawable-filters.h"
#include "gimpdrawablefilter.h"
#include "gimpcontext.h"
#include "gimpfilloptions.h"
@ -201,6 +203,7 @@ gimp_drawable_edit_fill (GimpDrawable *drawable,
gdouble opacity;
GimpLayerMode mode;
GimpLayerCompositeMode composite_mode;
GimpContainer *filter_stack;
opacity = gimp_context_get_opacity (context);
mode = gimp_context_get_paint_mode (context);
@ -224,6 +227,12 @@ gimp_drawable_edit_fill (GimpDrawable *drawable,
composite_mode);
gimp_drawable_filter_apply (filter, NULL);
/* Move to bottom of filter stack */
filter_stack = gimp_drawable_get_filters (drawable);
if (filter_stack)
gimp_container_reorder (filter_stack, GIMP_OBJECT (filter),
gimp_container_get_n_children (filter_stack) - 1);
gimp_drawable_filter_commit (filter, FALSE, NULL, FALSE);
g_object_unref (filter);

View file

@ -37,6 +37,8 @@
#include "gimpchannel.h"
#include "gimpcontext.h"
#include "gimpdrawable-fill.h"
#include "gimpdrawable-filters.h"
#include "gimpdrawablefilter.h"
#include "gimpgrouplayer.h"
#include "gimpimage.h"
#include "gimpimage-color-profile.h"
@ -406,6 +408,8 @@ gimp_image_new_from_drawables (Gimp *gimp,
gdouble xres;
gdouble yres;
GimpColorProfile *profile = NULL;
GList *old_layers_list;
GList *new_layers_list;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (drawables != NULL, NULL);
@ -462,6 +466,46 @@ gimp_image_new_from_drawables (Gimp *gimp,
}
gimp_image_new_copy_drawables (image, drawables, new_image, tag_copies, NULL, NULL, NULL, NULL);
/* Copy any attached layer effects */
old_layers_list = gimp_image_get_layer_iter (image);
for (new_layers_list = gimp_image_get_layer_iter (new_image);
new_layers_list; new_layers_list = g_list_next (new_layers_list))
{
GimpLayer *layer = old_layers_list->data;
GimpLayer *new_layer = new_layers_list->data;
if (gimp_drawable_has_filters (GIMP_DRAWABLE (layer)))
{
GList *filter_list;
GimpContainer *filters;
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
for (filter_list = GIMP_LIST (filters)->queue->tail; filter_list;
filter_list = g_list_previous (filter_list))
{
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
{
GimpDrawableFilter *old_filter = filter_list->data;
GimpDrawableFilter *filter;
filter =
gimp_drawable_filter_duplicate (GIMP_DRAWABLE (new_layer),
old_filter);
gimp_drawable_filter_apply (filter, NULL);
gimp_drawable_filter_commit (filter, TRUE, NULL, FALSE);
gimp_drawable_filter_layer_mask_freeze (filter);
g_object_unref (filter);
}
}
}
old_layers_list = g_list_next (old_layers_list);
}
gimp_image_undo_enable (new_image);
return new_image;