[gimp] Make reordering items between groups work in the core and the UI



commit d059f239ac7577d5c919d3d3fbc89cc1becf93a5
Author: Michael Natterer <mitch gimp org>
Date:   Thu Aug 6 18:43:57 2009 +0200

    Make reordering items between groups work in the core and the UI
    
    * app/core/gimpimage.[ch]: rename all gimp_image_reposition_foo() to
      gimp_image_reorder_foo() and added "new_parent" parameters. Factor
      out calculating of the item's new container and index to a utility
      function.
    
    * app/core/core-enums.[ch]: rename the REPOSITION undos to REORDER.
    
    * app/core/gimpimage-undo-push.[ch]
    * app/core/gimpchannelpropundo.[ch]
    * app/core/gimplayerpropundo.[ch]
    * app/vectors/gimpvectorspropundo.[ch]: change accordingly. Remember
      the old parent item in all item reorder undos.
    
    * app/widgets/gimpitemtreeview.h: change GimpReorderItemFunc prototype
      accordingly.
    
    * app/widgets/gimpchanneltreeview.c
    * app/widgets/gimplayertreeview.c
    * app/widgets/gimpvectorstreeview.c (class_init): follow image API
      name changes.
    
    * app/widgets/gimpitemtreeview.c (gimp_item_tree_view_drop_viewable):
      implement reordering of items between groups.
    
    * app/widgets/gimpcontainertreeview.c
      (gimp_container_tree_view_reorder_item): fix to reorder the item
      within its level of the tree (unrelated to above changes, but needed
      to make them work).

 app/core/core-enums.c               |   12 +-
 app/core/core-enums.h               |    6 +-
 app/core/gimpchannelpropundo.c      |   19 ++-
 app/core/gimpchannelpropundo.h      |    1 +
 app/core/gimpimage-undo-push.c      |   24 ++--
 app/core/gimpimage-undo-push.h      |    6 +-
 app/core/gimpimage.c                |  303 ++++++++++++++++++++++++++---------
 app/core/gimpimage.h                |    9 +-
 app/core/gimplayerpropundo.c        |   19 ++-
 app/core/gimplayerpropundo.h        |   11 +-
 app/vectors/gimpvectorspropundo.c   |   19 ++-
 app/vectors/gimpvectorspropundo.h   |    1 +
 app/widgets/gimpchanneltreeview.c   |    2 +-
 app/widgets/gimpcontainertreeview.c |   30 +++-
 app/widgets/gimpitemtreeview.c      |   49 +++----
 app/widgets/gimpitemtreeview.h      |    1 +
 app/widgets/gimplayertreeview.c     |    2 +-
 app/widgets/gimpvectorstreeview.c   |    2 +-
 18 files changed, 347 insertions(+), 169 deletions(-)
---
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index f6b5e55..6dac060 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -835,7 +835,7 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_ITEM_LINKED, "GIMP_UNDO_ITEM_LINKED", "item-linked" },
     { GIMP_UNDO_LAYER_ADD, "GIMP_UNDO_LAYER_ADD", "layer-add" },
     { GIMP_UNDO_LAYER_REMOVE, "GIMP_UNDO_LAYER_REMOVE", "layer-remove" },
-    { GIMP_UNDO_LAYER_REPOSITION, "GIMP_UNDO_LAYER_REPOSITION", "layer-reposition" },
+    { GIMP_UNDO_LAYER_REORDER, "GIMP_UNDO_LAYER_REORDER", "layer-reorder" },
     { GIMP_UNDO_LAYER_MODE, "GIMP_UNDO_LAYER_MODE", "layer-mode" },
     { GIMP_UNDO_LAYER_OPACITY, "GIMP_UNDO_LAYER_OPACITY", "layer-opacity" },
     { GIMP_UNDO_LAYER_LOCK_ALPHA, "GIMP_UNDO_LAYER_LOCK_ALPHA", "layer-lock-alpha" },
@@ -847,12 +847,12 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_LAYER_MASK_SHOW, "GIMP_UNDO_LAYER_MASK_SHOW", "layer-mask-show" },
     { GIMP_UNDO_CHANNEL_ADD, "GIMP_UNDO_CHANNEL_ADD", "channel-add" },
     { GIMP_UNDO_CHANNEL_REMOVE, "GIMP_UNDO_CHANNEL_REMOVE", "channel-remove" },
-    { GIMP_UNDO_CHANNEL_REPOSITION, "GIMP_UNDO_CHANNEL_REPOSITION", "channel-reposition" },
+    { GIMP_UNDO_CHANNEL_REORDER, "GIMP_UNDO_CHANNEL_REORDER", "channel-reorder" },
     { GIMP_UNDO_CHANNEL_COLOR, "GIMP_UNDO_CHANNEL_COLOR", "channel-color" },
     { GIMP_UNDO_VECTORS_ADD, "GIMP_UNDO_VECTORS_ADD", "vectors-add" },
     { GIMP_UNDO_VECTORS_REMOVE, "GIMP_UNDO_VECTORS_REMOVE", "vectors-remove" },
     { GIMP_UNDO_VECTORS_MOD, "GIMP_UNDO_VECTORS_MOD", "vectors-mod" },
-    { GIMP_UNDO_VECTORS_REPOSITION, "GIMP_UNDO_VECTORS_REPOSITION", "vectors-reposition" },
+    { GIMP_UNDO_VECTORS_REORDER, "GIMP_UNDO_VECTORS_REORDER", "vectors-reorder" },
     { GIMP_UNDO_FS_TO_LAYER, "GIMP_UNDO_FS_TO_LAYER", "fs-to-layer" },
     { GIMP_UNDO_TRANSFORM, "GIMP_UNDO_TRANSFORM", "transform" },
     { GIMP_UNDO_PAINT, "GIMP_UNDO_PAINT", "paint" },
@@ -920,7 +920,7 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_ITEM_LINKED, NC_("undo-type", "Link/Unlink item"), NULL },
     { GIMP_UNDO_LAYER_ADD, NC_("undo-type", "New layer"), NULL },
     { GIMP_UNDO_LAYER_REMOVE, NC_("undo-type", "Delete layer"), NULL },
-    { GIMP_UNDO_LAYER_REPOSITION, NC_("undo-type", "Reposition layer"), NULL },
+    { GIMP_UNDO_LAYER_REORDER, NC_("undo-type", "Reorder layer"), NULL },
     { GIMP_UNDO_LAYER_MODE, NC_("undo-type", "Set layer mode"), NULL },
     { GIMP_UNDO_LAYER_OPACITY, NC_("undo-type", "Set layer opacity"), NULL },
     { GIMP_UNDO_LAYER_LOCK_ALPHA, NC_("undo-type", "Lock/Unlock alpha channel"), NULL },
@@ -932,12 +932,12 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_LAYER_MASK_SHOW, NC_("undo-type", "Show layer mask"), NULL },
     { GIMP_UNDO_CHANNEL_ADD, NC_("undo-type", "New channel"), NULL },
     { GIMP_UNDO_CHANNEL_REMOVE, NC_("undo-type", "Delete channel"), NULL },
-    { GIMP_UNDO_CHANNEL_REPOSITION, NC_("undo-type", "Reposition channel"), NULL },
+    { GIMP_UNDO_CHANNEL_REORDER, NC_("undo-type", "Reorder channel"), NULL },
     { GIMP_UNDO_CHANNEL_COLOR, NC_("undo-type", "Channel color"), NULL },
     { GIMP_UNDO_VECTORS_ADD, NC_("undo-type", "New path"), NULL },
     { GIMP_UNDO_VECTORS_REMOVE, NC_("undo-type", "Delete path"), NULL },
     { GIMP_UNDO_VECTORS_MOD, NC_("undo-type", "Path modification"), NULL },
-    { GIMP_UNDO_VECTORS_REPOSITION, NC_("undo-type", "Reposition path"), NULL },
+    { GIMP_UNDO_VECTORS_REORDER, NC_("undo-type", "Reorder path"), NULL },
     { GIMP_UNDO_FS_TO_LAYER, NC_("undo-type", "Floating selection to layer"), NULL },
     { GIMP_UNDO_TRANSFORM, NC_("undo-type", "Transform"), NULL },
     { GIMP_UNDO_PAINT, NC_("undo-type", "Paint"), NULL },
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index fac35c8..4b1a96c 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -416,7 +416,7 @@ typedef enum /*< pdb-skip >*/
   GIMP_UNDO_ITEM_LINKED,              /*< desc="Link/Unlink item"            >*/
   GIMP_UNDO_LAYER_ADD,                /*< desc="New layer"                   >*/
   GIMP_UNDO_LAYER_REMOVE,             /*< desc="Delete layer"                >*/
-  GIMP_UNDO_LAYER_REPOSITION,         /*< desc="Reposition layer"            >*/
+  GIMP_UNDO_LAYER_REORDER,            /*< desc="Reorder layer"               >*/
   GIMP_UNDO_LAYER_MODE,               /*< desc="Set layer mode"              >*/
   GIMP_UNDO_LAYER_OPACITY,            /*< desc="Set layer opacity"           >*/
   GIMP_UNDO_LAYER_LOCK_ALPHA,         /*< desc="Lock/Unlock alpha channel"   >*/
@@ -428,12 +428,12 @@ typedef enum /*< pdb-skip >*/
   GIMP_UNDO_LAYER_MASK_SHOW,          /*< desc="Show layer mask"             >*/
   GIMP_UNDO_CHANNEL_ADD,              /*< desc="New channel"                 >*/
   GIMP_UNDO_CHANNEL_REMOVE,           /*< desc="Delete channel"              >*/
-  GIMP_UNDO_CHANNEL_REPOSITION,       /*< desc="Reposition channel"          >*/
+  GIMP_UNDO_CHANNEL_REORDER,          /*< desc="Reorder channel"             >*/
   GIMP_UNDO_CHANNEL_COLOR,            /*< desc="Channel color"               >*/
   GIMP_UNDO_VECTORS_ADD,              /*< desc="New path"                    >*/
   GIMP_UNDO_VECTORS_REMOVE,           /*< desc="Delete path"                 >*/
   GIMP_UNDO_VECTORS_MOD,              /*< desc="Path modification"           >*/
-  GIMP_UNDO_VECTORS_REPOSITION,       /*< desc="Reposition path"             >*/
+  GIMP_UNDO_VECTORS_REORDER,          /*< desc="Reorder path"                >*/
   GIMP_UNDO_FS_TO_LAYER,              /*< desc="Floating selection to layer" >*/
   GIMP_UNDO_TRANSFORM,                /*< desc="Transform"                   >*/
   GIMP_UNDO_PAINT,                    /*< desc="Paint"                       >*/
diff --git a/app/core/gimpchannelpropundo.c b/app/core/gimpchannelpropundo.c
index 1d9eb62..582d5b3 100644
--- a/app/core/gimpchannelpropundo.c
+++ b/app/core/gimpchannelpropundo.c
@@ -79,7 +79,8 @@ gimp_channel_prop_undo_constructor (GType                  type,
 
   switch (GIMP_UNDO (object)->undo_type)
     {
-    case GIMP_UNDO_CHANNEL_REPOSITION:
+    case GIMP_UNDO_CHANNEL_REORDER:
+      channel_prop_undo->parent   = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
       channel_prop_undo->position = gimp_item_get_index (GIMP_ITEM (channel));
       break;
 
@@ -106,14 +107,20 @@ gimp_channel_prop_undo_pop (GimpUndo            *undo,
 
   switch (undo->undo_type)
     {
-    case GIMP_UNDO_CHANNEL_REPOSITION:
+    case GIMP_UNDO_CHANNEL_REORDER:
       {
-        gint position;
+        GimpChannel *parent;
+        gint         position;
 
+        parent   = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
         position = gimp_item_get_index (GIMP_ITEM (channel));
-        gimp_image_position_channel (undo->image, channel,
-                                     channel_prop_undo->position,
-                                     FALSE, NULL);
+
+        gimp_image_reorder_channel (undo->image, channel,
+                                    channel_prop_undo->parent,
+                                    channel_prop_undo->position,
+                                    FALSE, NULL);
+
+        channel_prop_undo->parent   = parent;
         channel_prop_undo->position = position;
       }
       break;
diff --git a/app/core/gimpchannelpropundo.h b/app/core/gimpchannelpropundo.h
index 195b1c3..4d66a73 100644
--- a/app/core/gimpchannelpropundo.h
+++ b/app/core/gimpchannelpropundo.h
@@ -36,6 +36,7 @@ struct _GimpChannelPropUndo
 {
   GimpItemUndo  parent_instance;
 
+  GimpChannel  *parent;
   gint          position;
   GimpRGB       color;
 };
diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c
index bb5b55e..1fc5f4f 100644
--- a/app/core/gimpimage-undo-push.c
+++ b/app/core/gimpimage-undo-push.c
@@ -450,16 +450,16 @@ gimp_image_undo_push_layer_remove (GimpImage   *image,
 }
 
 GimpUndo *
-gimp_image_undo_push_layer_reposition (GimpImage   *image,
-                                       const gchar *undo_desc,
-                                       GimpLayer   *layer)
+gimp_image_undo_push_layer_reorder (GimpImage   *image,
+                                    const gchar *undo_desc,
+                                    GimpLayer   *layer)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
 
   return gimp_image_undo_push (image, GIMP_TYPE_LAYER_PROP_UNDO,
-                               GIMP_UNDO_LAYER_REPOSITION, undo_desc,
+                               GIMP_UNDO_LAYER_REORDER, undo_desc,
                                GIMP_DIRTY_IMAGE_STRUCTURE,
                                "item", layer,
                                NULL);
@@ -683,16 +683,16 @@ gimp_image_undo_push_channel_remove (GimpImage   *image,
 }
 
 GimpUndo *
-gimp_image_undo_push_channel_reposition (GimpImage   *image,
-                                         const gchar *undo_desc,
-                                         GimpChannel *channel)
+gimp_image_undo_push_channel_reorder (GimpImage   *image,
+                                      const gchar *undo_desc,
+                                      GimpChannel *channel)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)), NULL);
 
   return gimp_image_undo_push (image, GIMP_TYPE_CHANNEL_PROP_UNDO,
-                               GIMP_UNDO_CHANNEL_REPOSITION, undo_desc,
+                               GIMP_UNDO_CHANNEL_REORDER, undo_desc,
                                GIMP_DIRTY_IMAGE_STRUCTURE,
                                "item", channel,
                                NULL);
@@ -782,16 +782,16 @@ gimp_image_undo_push_vectors_mod (GimpImage   *image,
 }
 
 GimpUndo *
-gimp_image_undo_push_vectors_reposition (GimpImage   *image,
-                                         const gchar *undo_desc,
-                                         GimpVectors *vectors)
+gimp_image_undo_push_vectors_reorder (GimpImage   *image,
+                                      const gchar *undo_desc,
+                                      GimpVectors *vectors)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (vectors)), NULL);
 
   return gimp_image_undo_push (image, GIMP_TYPE_VECTORS_PROP_UNDO,
-                               GIMP_UNDO_VECTORS_REPOSITION, undo_desc,
+                               GIMP_UNDO_VECTORS_REORDER, undo_desc,
                                GIMP_DIRTY_IMAGE_STRUCTURE,
                                "item", vectors,
                                NULL);
diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h
index 16247e1..71a654f 100644
--- a/app/core/gimpimage-undo-push.h
+++ b/app/core/gimpimage-undo-push.h
@@ -114,7 +114,7 @@ GimpUndo * gimp_image_undo_push_layer_remove        (GimpImage     *image,
                                                      GimpLayer     *prev_parent,
                                                      gint           prev_position,
                                                      GimpLayer     *prev_layer);
-GimpUndo * gimp_image_undo_push_layer_reposition    (GimpImage     *image,
+GimpUndo * gimp_image_undo_push_layer_reorder       (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpLayer     *layer);
 GimpUndo * gimp_image_undo_push_layer_mode          (GimpImage     *image,
@@ -169,7 +169,7 @@ GimpUndo * gimp_image_undo_push_channel_remove      (GimpImage     *image,
                                                      GimpChannel   *prev_parent,
                                                      gint           prev_position,
                                                      GimpChannel   *prev_channel);
-GimpUndo * gimp_image_undo_push_channel_reposition  (GimpImage     *image,
+GimpUndo * gimp_image_undo_push_channel_reorder     (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpChannel   *channel);
 GimpUndo * gimp_image_undo_push_channel_color       (GimpImage     *image,
@@ -192,7 +192,7 @@ GimpUndo * gimp_image_undo_push_vectors_remove      (GimpImage     *image,
 GimpUndo * gimp_image_undo_push_vectors_mod         (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpVectors   *vectors);
-GimpUndo * gimp_image_undo_push_vectors_reposition  (GimpImage     *image,
+GimpUndo * gimp_image_undo_push_vectors_reorder     (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpVectors   *vectors);
 
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 641cebe..b1d3082 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -3005,6 +3005,33 @@ gimp_image_get_insert_pos (GimpItem       *parent,
   return parent;
 }
 
+static GimpContainer *
+gimp_image_get_reorder_pos (GimpItem      *item,
+                            GimpItem      *new_parent,
+                            gint          *new_index,
+                            GimpContainer *toplevel_container)
+{
+  GimpContainer *container;
+  GimpContainer *new_container;
+  gint           num_items;
+
+  container = gimp_item_get_container (item);
+
+  if (new_parent)
+    new_container = gimp_viewable_get_children (GIMP_VIEWABLE (new_parent));
+  else
+    new_container = toplevel_container;
+
+  num_items = gimp_container_get_n_children (new_container);
+
+  if (new_container == container)
+    num_items--;
+
+  *new_index = CLAMP (*new_index, 0, num_items);
+
+  return new_container;
+}
+
 gboolean
 gimp_image_add_layer (GimpImage *image,
                       GimpLayer *layer,
@@ -3286,7 +3313,8 @@ gimp_image_raise_layer (GimpImage  *image,
                         GimpLayer  *layer,
                         GError    **error)
 {
-  gint index;
+  GimpLayer *parent;
+  gint       index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE);
@@ -3301,8 +3329,11 @@ gimp_image_raise_layer (GimpImage  *image,
       return FALSE;
     }
 
-  return gimp_image_position_layer (image, layer, index - 1,
-                                    TRUE, _("Raise Layer"));
+  parent = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
+
+  return gimp_image_reorder_layer (image, layer,
+                                   parent, index - 1,
+                                   TRUE, _("Raise Layer"));
 }
 
 gboolean
@@ -3311,6 +3342,7 @@ gimp_image_lower_layer (GimpImage  *image,
                         GError    **error)
 {
   GimpContainer *container;
+  GimpLayer     *parent;
   gint           index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3328,19 +3360,27 @@ gimp_image_lower_layer (GimpImage  *image,
       return FALSE;
     }
 
-  return gimp_image_position_layer (image, layer, index + 1,
-                                    TRUE, _("Lower Layer"));
+  parent = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
+
+  return gimp_image_reorder_layer (image, layer,
+                                   parent, index + 1,
+                                   TRUE, _("Lower Layer"));
 }
 
 gboolean
 gimp_image_raise_layer_to_top (GimpImage *image,
                                GimpLayer *layer)
 {
+  GimpLayer *parent;
+
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE);
 
-  return gimp_image_position_layer (image, layer, 0,
-                                    TRUE, _("Raise Layer to Top"));
+  parent = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
+
+  return gimp_image_reorder_layer (image, layer,
+                                   parent, 0,
+                                   TRUE, _("Raise Layer to Top"));
 }
 
 gboolean
@@ -3348,6 +3388,7 @@ gimp_image_lower_layer_to_bottom (GimpImage *image,
                                   GimpLayer *layer)
 {
   GimpContainer *container;
+  GimpLayer     *parent;
   gint           length;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3357,40 +3398,65 @@ gimp_image_lower_layer_to_bottom (GimpImage *image,
 
   length = gimp_container_get_n_children (container);
 
-  return gimp_image_position_layer (image, layer, length - 1,
-                                    TRUE, _("Lower Layer to Bottom"));
+  parent = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
+
+  return gimp_image_reorder_layer (image, layer,
+                                   parent, length - 1,
+                                   TRUE, _("Lower Layer to Bottom"));
 }
 
 gboolean
-gimp_image_position_layer (GimpImage   *image,
-                           GimpLayer   *layer,
-                           gint         new_index,
-                           gboolean     push_undo,
-                           const gchar *undo_desc)
+gimp_image_reorder_layer (GimpImage   *image,
+                          GimpLayer   *layer,
+                          GimpLayer   *new_parent,
+                          gint         new_index,
+                          gboolean     push_undo,
+                          const gchar *undo_desc)
 {
   GimpContainer *container;
-  gint           index;
-  gint           num_layers;
+  GimpContainer *new_container;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE);
+  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), FALSE);
+  g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (layer)) == image, FALSE);
+  g_return_val_if_fail (new_parent == NULL || GIMP_IS_LAYER (new_parent), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_is_attached (GIMP_ITEM (new_parent)), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_get_image (GIMP_ITEM (new_parent)) == image,
+                        FALSE);
 
   container = gimp_item_get_container (GIMP_ITEM (layer));
 
-  index = gimp_item_get_index (GIMP_ITEM (layer));
-  if (index < 0)
-    return FALSE;
-
-  num_layers = gimp_container_get_n_children (container);
-
-  new_index = CLAMP (new_index, 0, num_layers - 1);
+  new_container = gimp_image_get_reorder_pos (GIMP_ITEM (layer),
+                                              GIMP_ITEM (new_parent),
+                                              &new_index,
+                                              image->layers);
 
-  if (new_index != index)
+  if (new_container != container ||
+      new_index     != gimp_item_get_index (GIMP_ITEM (layer)))
     {
       if (push_undo)
-        gimp_image_undo_push_layer_reposition (image, undo_desc, layer);
+        gimp_image_undo_push_layer_reorder (image, undo_desc, layer);
 
-      gimp_container_reorder (container, GIMP_OBJECT (layer), new_index);
+      if (new_container != container)
+        {
+          g_object_ref (layer);
+
+          gimp_container_remove (container, GIMP_OBJECT (layer));
+
+          gimp_viewable_set_parent (GIMP_VIEWABLE (layer),
+                                    GIMP_VIEWABLE (new_parent));
+
+          gimp_container_insert (new_container, GIMP_OBJECT (layer), new_index);
+
+          g_object_unref (layer);
+        }
+      else
+        {
+          gimp_container_reorder (container, GIMP_OBJECT (layer), new_index);
+        }
     }
 
   return TRUE;
@@ -3547,7 +3613,8 @@ gimp_image_raise_channel (GimpImage    *image,
                           GimpChannel  *channel,
                           GError      **error)
 {
-  gint index;
+  GimpChannel *parent;
+  gint         index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
@@ -3562,19 +3629,27 @@ gimp_image_raise_channel (GimpImage    *image,
       return FALSE;
     }
 
-  return gimp_image_position_channel (image, channel, index - 1,
-                                      TRUE, _("Raise Channel"));
+  parent = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
+
+  return gimp_image_reorder_channel (image, channel,
+                                     parent, index - 1,
+                                     TRUE, _("Raise Channel"));
 }
 
 gboolean
 gimp_image_raise_channel_to_top (GimpImage   *image,
                                  GimpChannel *channel)
 {
+  GimpChannel *parent;
+
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
 
-  return gimp_image_position_channel (image, channel, 0,
-                                      TRUE, _("Raise Channel to Top"));
+  parent = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
+
+  return gimp_image_reorder_channel (image, channel,
+                                     parent, 0,
+                                     TRUE, _("Raise Channel to Top"));
 }
 
 
@@ -3584,6 +3659,7 @@ gimp_image_lower_channel (GimpImage    *image,
                           GError      **error)
 {
   GimpContainer *container;
+  GimpChannel   *parent;
   gint           index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3601,8 +3677,11 @@ gimp_image_lower_channel (GimpImage    *image,
       return FALSE;
     }
 
-  return gimp_image_position_channel (image, channel, index + 1,
-                                      TRUE, _("Lower Channel"));
+  parent = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
+
+  return gimp_image_reorder_channel (image, channel,
+                                     parent, index + 1,
+                                     TRUE, _("Lower Channel"));
 }
 
 gboolean
@@ -3610,6 +3689,7 @@ gimp_image_lower_channel_to_bottom (GimpImage   *image,
                                     GimpChannel *channel)
 {
   GimpContainer *container;
+  GimpChannel   *parent;
   gint           length;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3619,41 +3699,67 @@ gimp_image_lower_channel_to_bottom (GimpImage   *image,
 
   length = gimp_container_get_n_children (container);
 
-  return gimp_image_position_channel (image, channel, length - 1,
-                                      TRUE, _("Lower Channel to Bottom"));
+  parent = GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
+
+  return gimp_image_reorder_channel (image, channel,
+                                     parent, length - 1,
+                                     TRUE, _("Lower Channel to Bottom"));
 }
 
 gboolean
-gimp_image_position_channel (GimpImage   *image,
-                             GimpChannel *channel,
-                             gint         new_index,
-                             gboolean     push_undo,
-                             const gchar *undo_desc)
+gimp_image_reorder_channel (GimpImage   *image,
+                            GimpChannel *channel,
+                            GimpChannel *new_parent,
+                            gint         new_index,
+                            gboolean     push_undo,
+                            const gchar *undo_desc)
 {
   GimpContainer *container;
-  gint           index;
-  gint           num_channels;
+  GimpContainer *new_container;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
+  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)), FALSE);
+  g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (channel)) == image,
+                        FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        GIMP_IS_CHANNEL (new_parent), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_is_attached (GIMP_ITEM (new_parent)), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_get_image (GIMP_ITEM (new_parent)) == image,
+                        FALSE);
 
   container = gimp_item_get_container (GIMP_ITEM (channel));
 
-  index = gimp_item_get_index (GIMP_ITEM (channel));
-  if (index < 0)
-    return FALSE;
+  new_container = gimp_image_get_reorder_pos (GIMP_ITEM (channel),
+                                              GIMP_ITEM (new_parent),
+                                              &new_index,
+                                              image->channels);
 
-  num_channels = gimp_container_get_n_children (container);
+  if (new_container != container ||
+      new_index     != gimp_item_get_index (GIMP_ITEM (channel)))
+    {
+      if (push_undo)
+        gimp_image_undo_push_channel_reorder (image, undo_desc, channel);
 
-  new_index = CLAMP (new_index, 0, num_channels - 1);
+      if (new_container != container)
+        {
+          g_object_ref (channel);
 
-  if (new_index != index)
-    {
+          gimp_container_remove (container, GIMP_OBJECT (channel));
 
-      if (push_undo)
-        gimp_image_undo_push_channel_reposition (image, undo_desc, channel);
+          gimp_viewable_set_parent (GIMP_VIEWABLE (channel),
+                                    GIMP_VIEWABLE (new_parent));
+
+          gimp_container_insert (new_container, GIMP_OBJECT (channel), new_index);
 
-      gimp_container_reorder (container, GIMP_OBJECT (channel), new_index);
+          g_object_unref (channel);
+        }
+      else
+        {
+          gimp_container_reorder (container, GIMP_OBJECT (channel), new_index);
+        }
     }
 
   return TRUE;
@@ -3785,7 +3891,8 @@ gimp_image_raise_vectors (GimpImage    *image,
                           GimpVectors  *vectors,
                           GError      **error)
 {
-  gint index;
+  GimpVectors *parent;
+  gint         index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
@@ -3800,19 +3907,27 @@ gimp_image_raise_vectors (GimpImage    *image,
       return FALSE;
     }
 
-  return gimp_image_position_vectors (image, vectors, index - 1,
-                                      TRUE, _("Raise Path"));
+  parent = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
+
+  return gimp_image_reorder_vectors (image, vectors,
+                                     parent, index - 1,
+                                     TRUE, _("Raise Path"));
 }
 
 gboolean
 gimp_image_raise_vectors_to_top (GimpImage   *image,
                                  GimpVectors *vectors)
 {
+  GimpVectors *parent;
+
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
 
-  return gimp_image_position_vectors (image, vectors, 0,
-                                      TRUE, _("Raise Path to Top"));
+  parent = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
+
+  return gimp_image_reorder_vectors (image, vectors,
+                                     parent, 0,
+                                     TRUE, _("Raise Path to Top"));
 }
 
 gboolean
@@ -3821,6 +3936,7 @@ gimp_image_lower_vectors (GimpImage    *image,
                           GError      **error)
 {
   GimpContainer *container;
+  GimpVectors   *parent;
   gint           index;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3838,8 +3954,11 @@ gimp_image_lower_vectors (GimpImage    *image,
       return FALSE;
     }
 
-  return gimp_image_position_vectors (image, vectors, index + 1,
-                                      TRUE, _("Lower Path"));
+  parent = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
+
+  return gimp_image_reorder_vectors (image, vectors,
+                                     parent, index + 1,
+                                     TRUE, _("Lower Path"));
 }
 
 gboolean
@@ -3847,6 +3966,7 @@ gimp_image_lower_vectors_to_bottom (GimpImage   *image,
                                     GimpVectors *vectors)
 {
   GimpContainer *container;
+  GimpVectors   *parent;
   gint           length;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
@@ -3856,40 +3976,67 @@ gimp_image_lower_vectors_to_bottom (GimpImage   *image,
 
   length = gimp_container_get_n_children (container);
 
-  return gimp_image_position_vectors (image, vectors, length - 1,
-                                      TRUE, _("Lower Path to Bottom"));
+  parent = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
+
+  return gimp_image_reorder_vectors (image, vectors,
+                                     parent, length - 1,
+                                     TRUE, _("Lower Path to Bottom"));
 }
 
 gboolean
-gimp_image_position_vectors (GimpImage   *image,
-                             GimpVectors *vectors,
-                             gint         new_index,
-                             gboolean     push_undo,
-                             const gchar *undo_desc)
+gimp_image_reorder_vectors (GimpImage   *image,
+                            GimpVectors *vectors,
+                            GimpVectors *new_parent,
+                            gint         new_index,
+                            gboolean     push_undo,
+                            const gchar *undo_desc)
 {
   GimpContainer *container;
-  gint           index;
-  gint           num_vectors;
+  GimpContainer *new_container;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
+  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (vectors)), FALSE);
+  g_return_val_if_fail (gimp_item_get_image (GIMP_ITEM (vectors)) == image,
+                        FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        GIMP_IS_VECTORS (new_parent), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_is_attached (GIMP_ITEM (new_parent)), FALSE);
+  g_return_val_if_fail (new_parent == NULL ||
+                        gimp_item_get_image (GIMP_ITEM (new_parent)) == image,
+                        FALSE);
 
   container = gimp_item_get_container (GIMP_ITEM (vectors));
 
-  index = gimp_item_get_index (GIMP_ITEM (vectors));
-  if (index < 0)
-    return FALSE;
-
-  num_vectors = gimp_container_get_n_children (container);
-
-  new_index = CLAMP (new_index, 0, num_vectors - 1);
+  new_container = gimp_image_get_reorder_pos (GIMP_ITEM (vectors),
+                                              GIMP_ITEM (new_parent),
+                                              &new_index,
+                                              image->vectors);
 
-  if (new_index != index)
+  if (new_container != container ||
+      new_index     != gimp_item_get_index (GIMP_ITEM (vectors)))
     {
       if (push_undo)
-        gimp_image_undo_push_vectors_reposition (image, undo_desc, vectors);
+        gimp_image_undo_push_vectors_reorder (image, undo_desc, vectors);
+
+      if (new_container != container)
+        {
+          g_object_ref (vectors);
+
+          gimp_container_remove (container, GIMP_OBJECT (vectors));
+
+          gimp_viewable_set_parent (GIMP_VIEWABLE (vectors),
+                                    GIMP_VIEWABLE (new_parent));
 
-      gimp_container_reorder (container, GIMP_OBJECT (vectors), new_index);
+          gimp_container_insert (new_container, GIMP_OBJECT (vectors), new_index);
+
+          g_object_unref (vectors);
+        }
+      else
+        {
+          gimp_container_reorder (container, GIMP_OBJECT (vectors), new_index);
+        }
     }
 
   return TRUE;
diff --git a/app/core/gimpimage.h b/app/core/gimpimage.h
index 7aa2e7a..b5884f1 100644
--- a/app/core/gimpimage.h
+++ b/app/core/gimpimage.h
@@ -493,8 +493,9 @@ gboolean        gimp_image_raise_layer_to_top    (GimpImage          *image,
                                                   GimpLayer          *layer);
 gboolean        gimp_image_lower_layer_to_bottom (GimpImage          *image,
                                                   GimpLayer          *layer);
-gboolean        gimp_image_position_layer        (GimpImage          *image,
+gboolean        gimp_image_reorder_layer         (GimpImage          *image,
                                                   GimpLayer          *layer,
+                                                  GimpLayer          *new_parent,
                                                   gint                new_index,
                                                   gboolean            push_undo,
                                                   const gchar        *undo_desc);
@@ -519,8 +520,9 @@ gboolean        gimp_image_lower_channel         (GimpImage          *image,
                                                   GError            **error);
 gboolean      gimp_image_lower_channel_to_bottom (GimpImage          *image,
                                                   GimpChannel        *channel);
-gboolean        gimp_image_position_channel      (GimpImage          *image,
+gboolean        gimp_image_reorder_channel       (GimpImage          *image,
                                                   GimpChannel        *channel,
+                                                  GimpChannel        *new_parent,
                                                   gint                new_index,
                                                   gboolean            push_undo,
                                                   const gchar        *undo_desc);
@@ -545,8 +547,9 @@ gboolean        gimp_image_lower_vectors         (GimpImage          *image,
                                                   GError            **error);
 gboolean      gimp_image_lower_vectors_to_bottom (GimpImage          *image,
                                                   GimpVectors        *vectors);
-gboolean        gimp_image_position_vectors      (GimpImage          *image,
+gboolean        gimp_image_reorder_vectors       (GimpImage          *image,
                                                   GimpVectors        *vectors,
+                                                  GimpVectors        *new_parent,
                                                   gint                new_index,
                                                   gboolean            push_undo,
                                                   const gchar        *undo_desc);
diff --git a/app/core/gimplayerpropundo.c b/app/core/gimplayerpropundo.c
index 5e793e7..80c20af 100644
--- a/app/core/gimplayerpropundo.c
+++ b/app/core/gimplayerpropundo.c
@@ -79,7 +79,8 @@ gimp_layer_prop_undo_constructor (GType                  type,
 
   switch (GIMP_UNDO (object)->undo_type)
     {
-    case GIMP_UNDO_LAYER_REPOSITION:
+    case GIMP_UNDO_LAYER_REORDER:
+      layer_prop_undo->parent = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
       layer_prop_undo->position = gimp_item_get_index (GIMP_ITEM (layer));
       break;
 
@@ -114,14 +115,20 @@ gimp_layer_prop_undo_pop (GimpUndo            *undo,
 
   switch (undo->undo_type)
     {
-    case GIMP_UNDO_LAYER_REPOSITION:
+    case GIMP_UNDO_LAYER_REORDER:
       {
-        gint position;
+        GimpLayer *parent;
+        gint       position;
 
+        parent   = GIMP_LAYER (gimp_viewable_get_parent (GIMP_VIEWABLE (layer)));
         position = gimp_item_get_index (GIMP_ITEM (layer));
-        gimp_image_position_layer (undo->image, layer,
-                                   layer_prop_undo->position,
-                                   FALSE, NULL);
+
+        gimp_image_reorder_layer (undo->image, layer,
+                                  layer_prop_undo->parent,
+                                  layer_prop_undo->position,
+                                  FALSE, NULL);
+
+        layer_prop_undo->parent   = parent;
         layer_prop_undo->position = position;
       }
       break;
diff --git a/app/core/gimplayerpropundo.h b/app/core/gimplayerpropundo.h
index 98bc2bc..e3032a1 100644
--- a/app/core/gimplayerpropundo.h
+++ b/app/core/gimplayerpropundo.h
@@ -34,12 +34,13 @@ typedef struct _GimpLayerPropUndoClass GimpLayerPropUndoClass;
 
 struct _GimpLayerPropUndo
 {
-  GimpItemUndo         parent_instance;
+  GimpItemUndo          parent_instance;
 
-  gint                 position;
-  GimpLayerModeEffects mode;
-  gdouble              opacity;
-  gboolean             lock_alpha;
+  GimpLayer            *parent;
+  gint                  position;
+  GimpLayerModeEffects  mode;
+  gdouble               opacity;
+  gboolean              lock_alpha;
 };
 
 struct _GimpLayerPropUndoClass
diff --git a/app/vectors/gimpvectorspropundo.c b/app/vectors/gimpvectorspropundo.c
index 508524e..7aed3d4 100644
--- a/app/vectors/gimpvectorspropundo.c
+++ b/app/vectors/gimpvectorspropundo.c
@@ -78,7 +78,8 @@ gimp_vectors_prop_undo_constructor (GType                  type,
 
   switch (GIMP_UNDO (object)->undo_type)
     {
-    case GIMP_UNDO_VECTORS_REPOSITION:
+    case GIMP_UNDO_VECTORS_REORDER:
+      vectors_prop_undo->parent   = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
       vectors_prop_undo->position = gimp_item_get_index (GIMP_ITEM (vectors));
       break;
 
@@ -101,14 +102,20 @@ gimp_vectors_prop_undo_pop (GimpUndo            *undo,
 
   switch (undo->undo_type)
     {
-    case GIMP_UNDO_VECTORS_REPOSITION:
+    case GIMP_UNDO_VECTORS_REORDER:
       {
-        gint position;
+        GimpVectors *parent;
+        gint         position;
 
+        parent   = GIMP_VECTORS (gimp_viewable_get_parent (GIMP_VIEWABLE (vectors)));
         position = gimp_item_get_index (GIMP_ITEM (vectors));
-        gimp_image_position_vectors (undo->image, vectors,
-                                     vectors_prop_undo->position,
-                                     FALSE, NULL);
+
+        gimp_image_reorder_vectors (undo->image, vectors,
+                                    vectors_prop_undo->parent,
+                                    vectors_prop_undo->position,
+                                    FALSE, NULL);
+
+        vectors_prop_undo->parent   = parent;
         vectors_prop_undo->position = position;
       }
       break;
diff --git a/app/vectors/gimpvectorspropundo.h b/app/vectors/gimpvectorspropundo.h
index e41ea77..fde7d3a 100644
--- a/app/vectors/gimpvectorspropundo.h
+++ b/app/vectors/gimpvectorspropundo.h
@@ -36,6 +36,7 @@ struct _GimpVectorsPropUndo
 {
   GimpItemUndo  parent_instance;
 
+  GimpVectors  *parent;
   gint          position;
 };
 
diff --git a/app/widgets/gimpchanneltreeview.c b/app/widgets/gimpchanneltreeview.c
index 43beabc..9e961f0 100644
--- a/app/widgets/gimpchanneltreeview.c
+++ b/app/widgets/gimpchanneltreeview.c
@@ -115,7 +115,7 @@ gimp_channel_tree_view_class_init (GimpChannelTreeViewClass *klass)
   iv_class->get_container    = gimp_image_get_channels;
   iv_class->get_active_item  = (GimpGetItemFunc) gimp_image_get_active_channel;
   iv_class->set_active_item  = (GimpSetItemFunc) gimp_image_set_active_channel;
-  iv_class->reorder_item     = (GimpReorderItemFunc) gimp_image_position_channel;
+  iv_class->reorder_item     = (GimpReorderItemFunc) gimp_image_reorder_channel;
   iv_class->add_item         = (GimpAddItemFunc) gimp_image_add_channel;
   iv_class->remove_item      = (GimpRemoveItemFunc) gimp_image_remove_channel;
   iv_class->new_item         = gimp_channel_tree_view_item_new;
diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c
index 21d8512..7df967d 100644
--- a/app/widgets/gimpcontainertreeview.c
+++ b/app/widgets/gimpcontainertreeview.c
@@ -213,6 +213,7 @@ gimp_container_tree_view_constructor (GType                  type,
   gtk_tree_view_insert_column (tree_view->view, tree_view->main_column, 0);
 
   gtk_tree_view_set_expander_column (tree_view->view, tree_view->main_column);
+  gtk_tree_view_set_enable_tree_lines (tree_view->view, TRUE);
 
   tree_view->renderer_cell = gimp_cell_renderer_viewable_new ();
   gtk_tree_view_column_pack_start (tree_view->main_column,
@@ -653,12 +654,17 @@ gimp_container_tree_view_reorder_item (GimpContainerView *view,
 
   if (iter)
     {
+      GimpViewable  *parent;
       GimpContainer *container;
-      GtkTreePath   *path;
       GtkTreeIter    selected_iter;
       gboolean       selected;
 
-      container = gimp_container_view_get_container (view);
+      parent = gimp_viewable_get_parent (viewable);
+
+      if (parent)
+        container = gimp_viewable_get_children (parent);
+      else
+        container = gimp_container_view_get_container (view);
 
       selected = gtk_tree_selection_get_selected (tree_view->priv->selection,
                                                   NULL, &selected_iter);
@@ -690,18 +696,24 @@ gimp_container_tree_view_reorder_item (GimpContainerView *view,
         }
       else
         {
-          GtkTreeIter place_iter;
-          gint        old_index;
+          GtkTreePath *path;
+          GtkTreeIter  place_iter;
+          gint         depth;
+          gint        *indices;
+          gint         old_index;
 
           path = gtk_tree_model_get_path (tree_view->model, iter);
-          old_index = gtk_tree_path_get_indices (path)[0];
-          gtk_tree_path_free (path);
+          indices = gtk_tree_path_get_indices (path);
+
+          depth = gtk_tree_path_get_depth (path);
+
+          old_index = indices[depth - 1];
 
           if (new_index != old_index)
             {
-              path = gtk_tree_path_new_from_indices (new_index, -1);
+              indices[depth - 1] = new_index;
+
               gtk_tree_model_get_iter (tree_view->model, &place_iter, path);
-              gtk_tree_path_free (path);
 
               if (new_index > old_index)
                 gtk_tree_store_move_after (GTK_TREE_STORE (tree_view->model),
@@ -710,6 +722,8 @@ gimp_container_tree_view_reorder_item (GimpContainerView *view,
                 gtk_tree_store_move_before (GTK_TREE_STORE (tree_view->model),
                                             iter, &place_iter);
             }
+
+          gtk_tree_path_free (path);
         }
 
       if (selected)
diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c
index 7d49a36..be1ecc4 100644
--- a/app/widgets/gimpitemtreeview.c
+++ b/app/widgets/gimpitemtreeview.c
@@ -815,41 +815,30 @@ gimp_item_tree_view_drop_viewable (GimpContainerTreeView   *tree_view,
     }
   else if (dest_viewable)
     {
-      GimpContainer *src_container;
-      GimpContainer *dest_container;
-      gint           src_index;
-      gint           dest_index;
+      GimpItem *src_parent;
+      GimpItem *dest_parent;
+      gint      src_index;
+      gint      dest_index;
 
-      src_container = gimp_item_get_container (GIMP_ITEM (src_viewable));
-      src_index     = gimp_item_get_index (GIMP_ITEM (src_viewable));
+      src_parent = GIMP_ITEM (gimp_viewable_get_parent (src_viewable));
+      src_index  = gimp_item_get_index (GIMP_ITEM (src_viewable));
 
-      dest_container = gimp_item_get_container (GIMP_ITEM (dest_viewable));
-      dest_index     = gimp_item_get_index (GIMP_ITEM (dest_viewable));
-
-      if (src_container == dest_container)
-        {
-          if (drop_pos == GTK_TREE_VIEW_DROP_AFTER &&
-              src_index > dest_index)
-            {
-              dest_index++;
-            }
-          else if (drop_pos == GTK_TREE_VIEW_DROP_BEFORE &&
-                   src_index < dest_index)
-            {
-              dest_index--;
-            }
+      dest_index = gimp_item_tree_view_get_drop_index (item_view, dest_viewable,
+                                                       drop_pos,
+                                                       (GimpViewable **) &dest_parent);
 
-          item_view_class->reorder_item (item_view->priv->image,
-                                         GIMP_ITEM (src_viewable),
-                                         dest_index,
-                                         TRUE,
-                                         item_view_class->reorder_desc);
-        }
-      else
+      if (src_parent == dest_parent)
         {
-          g_printerr ("%s: dnd between containers (%d -> %d)\n",
-                      G_STRFUNC, src_index, dest_index);
+          if (src_index < dest_index)
+            dest_index--;
         }
+
+      item_view_class->reorder_item (item_view->priv->image,
+                                     GIMP_ITEM (src_viewable),
+                                     dest_parent,
+                                     dest_index,
+                                     TRUE,
+                                     item_view_class->reorder_desc);
     }
 
   gimp_image_flush (item_view->priv->image);
diff --git a/app/widgets/gimpitemtreeview.h b/app/widgets/gimpitemtreeview.h
index a2a58bc..e027aa9 100644
--- a/app/widgets/gimpitemtreeview.h
+++ b/app/widgets/gimpitemtreeview.h
@@ -31,6 +31,7 @@ typedef void            (* GimpSetItemFunc)      (GimpImage       *image,
                                                   GimpItem        *item);
 typedef void            (* GimpReorderItemFunc)  (GimpImage       *image,
                                                   GimpItem        *item,
+                                                  GimpItem        *new_parent,
                                                   gint             new_index,
                                                   gboolean         push_undo,
                                                   const gchar     *undo_desc);
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index a8797d9..7d60bf7 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -222,7 +222,7 @@ gimp_layer_tree_view_class_init (GimpLayerTreeViewClass *klass)
   item_view_class->get_container   = gimp_image_get_layers;
   item_view_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_layer;
   item_view_class->set_active_item = (GimpSetItemFunc) gimp_image_set_active_layer;
-  item_view_class->reorder_item    = (GimpReorderItemFunc) gimp_image_position_layer;
+  item_view_class->reorder_item    = (GimpReorderItemFunc) gimp_image_reorder_layer;
   item_view_class->add_item        = (GimpAddItemFunc) gimp_image_add_layer;
   item_view_class->remove_item     = (GimpRemoveItemFunc) gimp_image_remove_layer;
   item_view_class->new_item        = gimp_layer_tree_view_item_new;
diff --git a/app/widgets/gimpvectorstreeview.c b/app/widgets/gimpvectorstreeview.c
index 4f36223..03f40f7 100644
--- a/app/widgets/gimpvectorstreeview.c
+++ b/app/widgets/gimpvectorstreeview.c
@@ -97,7 +97,7 @@ gimp_vectors_tree_view_class_init (GimpVectorsTreeViewClass *klass)
   iv_class->get_container   = gimp_image_get_vectors;
   iv_class->get_active_item = (GimpGetItemFunc) gimp_image_get_active_vectors;
   iv_class->set_active_item = (GimpSetItemFunc) gimp_image_set_active_vectors;
-  iv_class->reorder_item    = (GimpReorderItemFunc) gimp_image_position_vectors;
+  iv_class->reorder_item    = (GimpReorderItemFunc) gimp_image_reorder_vectors;
   iv_class->add_item        = (GimpAddItemFunc) gimp_image_add_vectors;
   iv_class->remove_item     = (GimpRemoveItemFunc) gimp_image_remove_vectors;
   iv_class->new_item        = gimp_vectors_tree_view_item_new;



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