Files
gimp/app/core/gimpitem-linked.c
Jehan 66db143502 Bug 796014 - Cannot open some older .xcf files made with 2.8.22 in 2.10.
To avoid an infinite loop, gimp_item_linked_is_locked() was temporarily
unlinking items before calling gimp_item_is_position_locked(). This
worked only based on gimp_item_real_is_position_locked() code which
called gimp_item_linked_is_locked() only when it was linked. It did not
take into account the fact that it was an abstract method which could
have other implementations. In particular the group layer implementation
would call in turn gimp_item_is_position_locked() on each child layer.

Basically temporarily unsetting the link was anyway a very ugly hack.
The point is simply that we are only interested by the value of the
`lock_position` flag for this item, without further "intelligence". For
this, use gimp_item_get_lock_position() instead.
2018-05-11 18:04:31 +02:00

205 lines
6.6 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "core-types.h"
#include "gimpcontext.h"
#include "gimpimage.h"
#include "gimpimage-item-list.h"
#include "gimpimage-undo.h"
#include "gimpitem.h"
#include "gimpitem-linked.h"
#include "gimplist.h"
#include "gimpprogress.h"
#include "gimp-intl.h"
/* public functions */
gboolean
gimp_item_linked_is_locked (GimpItem *item)
{
GList *list;
GList *l;
gboolean locked = FALSE;
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
g_return_val_if_fail (gimp_item_get_linked (item) == TRUE, FALSE);
g_return_val_if_fail (gimp_item_is_attached (item), FALSE);
list = gimp_image_item_list_get_list (gimp_item_get_image (item),
GIMP_ITEM_TYPE_ALL,
GIMP_ITEM_SET_LINKED);
list = gimp_image_item_list_filter (list);
for (l = list; l && ! locked; l = g_list_next (l))
{
/* We must not use gimp_item_is_position_locked(), especially
* since a child implementation may call the current function and
* end up in infinite loop.
* We are only interested in the value of `lock_position` flag.
*/
if (gimp_item_get_lock_position (l->data))
locked = TRUE;
}
g_list_free (list);
return locked;
}
void
gimp_item_linked_translate (GimpItem *item,
gint offset_x,
gint offset_y,
gboolean push_undo)
{
GimpImage *image;
GList *items;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
g_return_if_fail (gimp_item_is_attached (item));
image = gimp_item_get_image (item);
items = gimp_image_item_list_get_list (image,
GIMP_ITEM_TYPE_ALL,
GIMP_ITEM_SET_LINKED);
items = gimp_image_item_list_filter (items);
gimp_image_item_list_translate (gimp_item_get_image (item), items,
offset_x, offset_y, push_undo);
g_list_free (items);
}
void
gimp_item_linked_flip (GimpItem *item,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result)
{
GimpImage *image;
GList *items;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (GIMP_IS_CONTEXT (context));
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
g_return_if_fail (gimp_item_is_attached (item));
image = gimp_item_get_image (item);
items = gimp_image_item_list_get_list (image,
GIMP_ITEM_TYPE_ALL,
GIMP_ITEM_SET_LINKED);
items = gimp_image_item_list_filter (items);
gimp_image_item_list_flip (image, items, context,
flip_type, axis, clip_result);
g_list_free (items);
}
void
gimp_item_linked_rotate (GimpItem *item,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result)
{
GimpImage *image;
GList *items;
GList *channels;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (GIMP_IS_CONTEXT (context));
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
g_return_if_fail (gimp_item_is_attached (item));
image = gimp_item_get_image (item);
items = gimp_image_item_list_get_list (image,
GIMP_ITEM_TYPE_LAYERS |
GIMP_ITEM_TYPE_VECTORS,
GIMP_ITEM_SET_LINKED);
items = gimp_image_item_list_filter (items);
channels = gimp_image_item_list_get_list (image,
GIMP_ITEM_TYPE_CHANNELS,
GIMP_ITEM_SET_LINKED);
channels = gimp_image_item_list_filter (channels);
if (items && channels)
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
C_("undo-type", "Rotate Items"));
gimp_image_item_list_rotate (image, items, context,
rotate_type, center_x, center_y, clip_result);
gimp_image_item_list_rotate (image, channels, context,
rotate_type, center_x, center_y, TRUE);
if (items && channels)
gimp_image_undo_group_end (image);
g_list_free (items);
g_list_free (channels);
}
void
gimp_item_linked_transform (GimpItem *item,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
GimpProgress *progress)
{
GimpImage *image;
GList *items;
g_return_if_fail (GIMP_IS_ITEM (item));
g_return_if_fail (GIMP_IS_CONTEXT (context));
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
g_return_if_fail (gimp_item_is_attached (item));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
image = gimp_item_get_image (item);
items = gimp_image_item_list_get_list (image,
GIMP_ITEM_TYPE_ALL,
GIMP_ITEM_SET_LINKED);
items = gimp_image_item_list_filter (items);
gimp_image_item_list_transform (image, items, context,
matrix, direction,
interpolation_type,
clip_result, progress);
g_list_free (items);
}