[gimp/gimp-2-8] Bug 735906 - Transform tools give unexpected results when transforming...



commit d744c37557a3d4298cb74160c76d037723b9e1ac
Author: Michael Natterer <mitch gimp org>
Date:   Thu Jun 25 12:25:41 2015 +0200

    Bug 735906 - Transform tools give unexpected results when transforming...
    
    ...certain sets of linked layers
    
    Fix this bug for flip, rotate and general transforms (not for move yet):
    
    gimp_item_linked_flip,rotate,transform(): always transform the passed
    item too (do not filter it out of the list of items), so these functions
    do the entire job of transforming a linked group now. Transforming the
    active item separately didn't work (and is not implementable) if both
    a layer and its parent layer group were linked.
    
    flip tool, transform tool, layer->transform callbacks: don't call
    gimp_item_foo() *and* (if the item is linked) gimp_item_linked_foo().
    Instead call gimp_item_linked_foo() if the item is linked, and
    gimp_item_foo() otherwise.
    
    This commit also kills the mis-feature of transforming the selected
    pixels of the active layer, and then the linked items completely. We
    now either only transform the selected area *or* the linked group.
    
    (cherry picked from commit 25a696c7f822864ebb35bcbfdb913a98032b0469)

 app/actions/drawable-commands.c |   26 +++++--------
 app/core/gimpitem-linked.c      |   77 +++++++++++++++++++++++----------------
 app/tools/gimpfliptool.c        |   15 +++++---
 app/tools/gimptransformtool.c   |   46 +++++++++++++-----------
 po/POTFILES.in                  |    1 +
 5 files changed, 92 insertions(+), 73 deletions(-)
---
diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c
index 4847cc4..3c6eb7b 100644
--- a/app/actions/drawable-commands.c
+++ b/app/actions/drawable-commands.c
@@ -264,17 +264,14 @@ drawable_flip_cmd_callback (GtkAction *action,
     }
 
   if (gimp_item_get_linked (item))
-    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
-                                 GIMP_ITEM_GET_CLASS (item)->flip_desc);
-
-  gimp_item_flip (item, context,
-                  (GimpOrientationType) value, axis, FALSE);
-
-  if (gimp_item_get_linked (item))
     {
       gimp_item_linked_flip (item, context,
                              (GimpOrientationType) value, axis, FALSE);
-      gimp_image_undo_group_end (image);
+    }
+  else
+    {
+      gimp_item_flip (item, context,
+                      (GimpOrientationType) value, axis, FALSE);
     }
 
   gimp_image_flush (image);
@@ -302,21 +299,18 @@ drawable_rotate_cmd_callback (GtkAction *action,
   center_x = ((gdouble) off_x + (gdouble) gimp_item_get_width  (item) / 2.0);
   center_y = ((gdouble) off_y + (gdouble) gimp_item_get_height (item) / 2.0);
 
-  if (gimp_item_get_linked (item))
-    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
-                                 GIMP_ITEM_GET_CLASS (item)->rotate_desc);
-
   if (GIMP_IS_CHANNEL (item))
     clip_result = TRUE;
 
-  gimp_item_rotate (item, context, (GimpRotationType) value,
-                    center_x, center_y, clip_result);
-
   if (gimp_item_get_linked (item))
     {
       gimp_item_linked_rotate (item, context, (GimpRotationType) value,
                                center_x, center_y, FALSE);
-      gimp_image_undo_group_end (image);
+    }
+  else
+    {
+      gimp_item_rotate (item, context, (GimpRotationType) value,
+                        center_x, center_y, clip_result);
     }
 
   gimp_image_flush (image);
diff --git a/app/core/gimpitem-linked.c b/app/core/gimpitem-linked.c
index d2a618c..f5fcb60 100644
--- a/app/core/gimpitem-linked.c
+++ b/app/core/gimpitem-linked.c
@@ -24,11 +24,14 @@
 #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  */
 
@@ -63,23 +66,25 @@ gimp_item_linked_flip (GimpItem            *item,
                        gdouble              axis,
                        gboolean             clip_result)
 {
-  GList *list;
+  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));
 
-  list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
-                                        GIMP_ITEM_TYPE_ALL,
-                                        GIMP_ITEM_SET_LINKED);
+  image = gimp_item_get_image (item);
 
-  list = gimp_image_item_list_filter (item, list);
+  items = gimp_image_item_list_get_list (image, NULL,
+                                         GIMP_ITEM_TYPE_ALL,
+                                         GIMP_ITEM_SET_LINKED);
+  items = gimp_image_item_list_filter (NULL, items);
 
-  gimp_image_item_list_flip (gimp_item_get_image (item), list, context,
+  gimp_image_item_list_flip (image, items, context,
                              flip_type, axis, clip_result);
 
-  g_list_free (list);
+  g_list_free (items);
 }
 
 void
@@ -90,35 +95,42 @@ gimp_item_linked_rotate (GimpItem         *item,
                          gdouble           center_y,
                          gboolean          clip_result)
 {
-  GList *list;
+  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));
 
-  list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
-                                        GIMP_ITEM_TYPE_LAYERS |
-                                        GIMP_ITEM_TYPE_VECTORS,
-                                        GIMP_ITEM_SET_LINKED);
-
-  list = gimp_image_item_list_filter (item, list);
-
-  gimp_image_item_list_rotate (gimp_item_get_image (item), list, context,
-                               rotate_type, center_x, center_y, clip_result);
+  image = gimp_item_get_image (item);
 
-  g_list_free (list);
+  items = gimp_image_item_list_get_list (image, NULL,
+                                         GIMP_ITEM_TYPE_LAYERS |
+                                         GIMP_ITEM_TYPE_VECTORS,
+                                         GIMP_ITEM_SET_LINKED);
+  items = gimp_image_item_list_filter (NULL, items);
 
-  list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
-                                        GIMP_ITEM_TYPE_CHANNELS,
-                                        GIMP_ITEM_SET_LINKED);
+  channels = gimp_image_item_list_get_list (image, NULL,
+                                            GIMP_ITEM_TYPE_CHANNELS,
+                                            GIMP_ITEM_SET_LINKED);
+  channels = gimp_image_item_list_filter (NULL, channels);
 
-  list = gimp_image_item_list_filter (item, list);
+  if (items && channels)
+    gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
+                                 C_("undo-type", "Rotate Items"));
 
-  gimp_image_item_list_rotate (gimp_item_get_image (item), list, context,
+  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);
 
-  g_list_free (list);
+  if (items && channels)
+    gimp_image_undo_group_end (image);
+
+  g_list_free (items);
+  g_list_free (channels);
 }
 
 void
@@ -131,7 +143,8 @@ gimp_item_linked_transform (GimpItem               *item,
                             GimpTransformResize     clip_result,
                             GimpProgress           *progress)
 {
-  GList *list;
+  GimpImage *image;
+  GList     *items;
 
   g_return_if_fail (GIMP_IS_ITEM (item));
   g_return_if_fail (GIMP_IS_CONTEXT (context));
@@ -139,16 +152,18 @@ gimp_item_linked_transform (GimpItem               *item,
   g_return_if_fail (gimp_item_is_attached (item));
   g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
 
-  list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
-                                        GIMP_ITEM_TYPE_ALL,
-                                        GIMP_ITEM_SET_LINKED);
+  image = gimp_item_get_image (item);
 
-  list = gimp_image_item_list_filter (item, list);
+  items = gimp_image_item_list_get_list (image, NULL,
+                                         GIMP_ITEM_TYPE_ALL,
+                                         GIMP_ITEM_SET_LINKED);
+
+  items = gimp_image_item_list_filter (NULL, items);
 
-  gimp_image_item_list_transform (gimp_item_get_image (item), list, context,
+  gimp_image_item_list_transform (image, items, context,
                                   matrix, direction,
                                   interpolation_type, recursion_level,
                                   clip_result, progress);
 
-  g_list_free (list);
+  g_list_free (items);
 }
diff --git a/app/tools/gimpfliptool.c b/app/tools/gimpfliptool.c
index edb102d..d810990 100644
--- a/app/tools/gimpfliptool.c
+++ b/app/tools/gimpfliptool.c
@@ -227,10 +227,6 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool,
       break;
     }
 
-  if (gimp_item_get_linked (active_item))
-    gimp_item_linked_flip (active_item, context, options->flip_type, axis,
-                           FALSE);
-
   if (orig_tiles)
     {
       /*  this happens when transforming a selection cut out of a
@@ -251,7 +247,16 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool,
     {
       /*  this happens for entire drawables, paths and layer groups  */
 
-      gimp_item_flip (active_item, context, options->flip_type, axis, FALSE);
+      if (gimp_item_get_linked (active_item))
+        {
+          gimp_item_linked_flip (active_item, context,
+                                 options->flip_type, axis, FALSE);
+        }
+      else
+        {
+          gimp_item_flip (active_item, context,
+                          options->flip_type, axis, FALSE);
+        }
     }
 
   return ret;
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index d4e5fb2..1656964 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -998,15 +998,6 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
   progress = gimp_progress_start (GIMP_PROGRESS (tool),
                                   tr_tool->progress_text, FALSE);
 
-  if (gimp_item_get_linked (active_item))
-    gimp_item_linked_transform (active_item, context,
-                                &tr_tool->transform,
-                                options->direction,
-                                options->interpolation,
-                                options->recursion_level,
-                                clip,
-                                progress);
-
   if (orig_tiles)
     {
       /*  this happens when transforming a selection cut out of a
@@ -1038,18 +1029,31 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
     {
       /*  this happens for entire drawables, paths and layer groups  */
 
-      /*  always clip layer masks so they keep their size
-       */
-      if (GIMP_IS_CHANNEL (active_item))
-        clip = GIMP_TRANSFORM_RESIZE_CLIP;
-
-      gimp_item_transform (active_item, context,
-                           &tr_tool->transform,
-                           options->direction,
-                           options->interpolation,
-                           options->recursion_level,
-                           clip,
-                           progress);
+      if (gimp_item_get_linked (active_item))
+        {
+          gimp_item_linked_transform (active_item, context,
+                                      &tr_tool->transform,
+                                      options->direction,
+                                      options->interpolation,
+                                      options->recursion_level,
+                                      clip,
+                                      progress);
+        }
+      else
+        {
+          /*  always clip layer masks so they keep their size
+           */
+          if (GIMP_IS_CHANNEL (active_item))
+            clip = GIMP_TRANSFORM_RESIZE_CLIP;
+
+          gimp_item_transform (active_item, context,
+                               &tr_tool->transform,
+                               options->direction,
+                               options->interpolation,
+                               options->recursion_level,
+                               clip,
+                               progress);
+        }
     }
 
   if (progress)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e21eb4c..5f95a6b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -157,6 +157,7 @@ app/core/gimpimage.c
 app/core/gimpimagefile.c
 app/core/gimpitem.c
 app/core/gimpitem-exclusive.c
+app/core/gimpitem-list.c
 app/core/gimplayer-floating-sel.c
 app/core/gimplayer.c
 app/core/gimplayermask.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]