[gimp] app, devel-docs, libgimp, pdb: remove gimp_item_set_linked().



commit 084906dbf1e75817765fa37c2877c31741dfb321
Author: Jehan <jehan girinstud io>
Date:   Thu Dec 16 00:35:20 2021 +0100

    app, devel-docs, libgimp, pdb: remove gimp_item_set_linked().
    
    I cleaned many remaining places where the concept of linked item still
    survived.
    On loading an XCF file with linked items, we are now going to create a
    named sets for the linked items, allowing people to easily select these
    back if the relation was still needed.
    
    We don't remove gimp_item_get_linked() yet and in particular, we don't
    save stored items into XCF files. This will come in an upcoming change.

 app/actions/items-commands.c                       |   2 +-
 app/core/core-enums.c                              |   4 -
 app/core/core-enums.h                              |   2 -
 app/core/gimpimage-new.c                           |   4 -
 app/core/gimpimage-private.h                       |   5 +-
 app/core/gimpimage-undo-push.c                     |  16 --
 app/core/gimpimage-undo-push.h                     |   3 -
 app/core/gimpimage-undo.c                          |   1 -
 app/core/gimpimage.c                               | 275 ++++++++++++++-------
 app/core/gimpimage.h                               |   8 +-
 app/core/gimpitem-exclusive.c                      |  87 -------
 app/core/gimpitem-exclusive.h                      |   2 -
 app/core/gimpitem.c                                |  30 ---
 app/core/gimpitem.h                                |   3 -
 app/core/gimpitempropundo.c                        |  14 --
 app/display/gimpdisplayshell-dnd.c                 |   1 -
 app/gimpcore.def                                   |   2 -
 app/pdb/internal-procs.c                           |   2 +-
 app/pdb/item-cmds.c                                | 111 ---------
 app/tools/gimptransformgridtool.c                  |  30 ---
 app/widgets/gimpchanneltreeview.c                  |   2 -
 app/widgets/gimpitemtreeview.c                     |   2 -
 app/widgets/gimplayertreeview.c                    |   4 +-
 app/xcf/xcf-load.c                                 |  47 +++-
 app/xcf/xcf-private.h                              |   9 +
 .../removed_functions.md                           |  14 +-
 devel-docs/app/app-sections.txt                    |   2 -
 devel-docs/libgimp/libgimp3-sections.txt           |   2 -
 libgimp/gimp.def                                   |   2 -
 libgimp/gimpitem_pdb.c                             |  74 ------
 libgimp/gimpitem_pdb.h                             |   3 -
 pdb/groups/item.pdb                                |  50 ----
 32 files changed, 263 insertions(+), 550 deletions(-)
---
diff --git a/app/actions/items-commands.c b/app/actions/items-commands.c
index fc6f49b4a6..e2aa909ed5 100644
--- a/app/actions/items-commands.c
+++ b/app/actions/items-commands.c
@@ -99,7 +99,7 @@ items_lock_content_cmd_callback (GimpAction *action,
       gboolean  push_undo = TRUE;
 
       undo = gimp_image_undo_can_compress (image, GIMP_TYPE_ITEM_UNDO,
-                                           GIMP_UNDO_ITEM_LINKED);
+                                           GIMP_UNDO_ITEM_LOCK_CONTENT);
 
       if (undo && GIMP_ITEM_UNDO (undo)->item == item)
         push_undo = FALSE;
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index f2d805d53c..793184a8db 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -1173,7 +1173,6 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_GROUP_DRAWABLE_MOD, "GIMP_UNDO_GROUP_DRAWABLE_MOD", "group-drawable-mod" },
     { GIMP_UNDO_GROUP_MASK, "GIMP_UNDO_GROUP_MASK", "group-mask" },
     { GIMP_UNDO_GROUP_ITEM_VISIBILITY, "GIMP_UNDO_GROUP_ITEM_VISIBILITY", "group-item-visibility" },
-    { GIMP_UNDO_GROUP_ITEM_LINKED, "GIMP_UNDO_GROUP_ITEM_LINKED", "group-item-linked" },
     { GIMP_UNDO_GROUP_ITEM_LOCK_CONTENTS, "GIMP_UNDO_GROUP_ITEM_LOCK_CONTENTS", "group-item-lock-contents" },
     { GIMP_UNDO_GROUP_ITEM_LOCK_POSITION, "GIMP_UNDO_GROUP_ITEM_LOCK_POSITION", "group-item-lock-position" },
     { GIMP_UNDO_GROUP_ITEM_LOCK_VISIBILITY, "GIMP_UNDO_GROUP_ITEM_LOCK_VISIBILITY", 
"group-item-lock-visibility" },
@@ -1220,7 +1219,6 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_ITEM_RENAME, "GIMP_UNDO_ITEM_RENAME", "item-rename" },
     { GIMP_UNDO_ITEM_DISPLACE, "GIMP_UNDO_ITEM_DISPLACE", "item-displace" },
     { GIMP_UNDO_ITEM_VISIBILITY, "GIMP_UNDO_ITEM_VISIBILITY", "item-visibility" },
-    { GIMP_UNDO_ITEM_LINKED, "GIMP_UNDO_ITEM_LINKED", "item-linked" },
     { GIMP_UNDO_ITEM_COLOR_TAG, "GIMP_UNDO_ITEM_COLOR_TAG", "item-color-tag" },
     { GIMP_UNDO_ITEM_LOCK_CONTENT, "GIMP_UNDO_ITEM_LOCK_CONTENT", "item-lock-content" },
     { GIMP_UNDO_ITEM_LOCK_POSITION, "GIMP_UNDO_ITEM_LOCK_POSITION", "item-lock-position" },
@@ -1283,7 +1281,6 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_GROUP_DRAWABLE_MOD, NC_("undo-type", "Layer/Channel modification"), NULL },
     { GIMP_UNDO_GROUP_MASK, NC_("undo-type", "Selection mask"), NULL },
     { GIMP_UNDO_GROUP_ITEM_VISIBILITY, NC_("undo-type", "Item visibility"), NULL },
-    { GIMP_UNDO_GROUP_ITEM_LINKED, NC_("undo-type", "Link/Unlink item"), NULL },
     { GIMP_UNDO_GROUP_ITEM_LOCK_CONTENTS, NC_("undo-type", "Lock/Unlock contents"), NULL },
     { GIMP_UNDO_GROUP_ITEM_LOCK_POSITION, NC_("undo-type", "Lock/Unlock position"), NULL },
     { GIMP_UNDO_GROUP_ITEM_LOCK_VISIBILITY, NC_("undo-type", "Lock/Unlock visibility"), NULL },
@@ -1330,7 +1327,6 @@ gimp_undo_type_get_type (void)
     { GIMP_UNDO_ITEM_RENAME, NC_("undo-type", "Rename item"), NULL },
     { GIMP_UNDO_ITEM_DISPLACE, NC_("undo-type", "Move item"), NULL },
     { GIMP_UNDO_ITEM_VISIBILITY, NC_("undo-type", "Item visibility"), NULL },
-    { GIMP_UNDO_ITEM_LINKED, NC_("undo-type", "Link/Unlink item"), NULL },
     { GIMP_UNDO_ITEM_COLOR_TAG, NC_("undo-type", "Item color tag"), NULL },
     { GIMP_UNDO_ITEM_LOCK_CONTENT, NC_("undo-type", "Lock/Unlock content"), NULL },
     { GIMP_UNDO_ITEM_LOCK_POSITION, NC_("undo-type", "Lock/Unlock position"), NULL },
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 409605c50c..cc6d64b179 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -541,7 +541,6 @@ typedef enum /*< pdb-skip >*/
   GIMP_UNDO_GROUP_DRAWABLE_MOD,          /*< desc="Layer/Channel modification"     >*/
   GIMP_UNDO_GROUP_MASK,                  /*< desc="Selection mask"                 >*/
   GIMP_UNDO_GROUP_ITEM_VISIBILITY,       /*< desc="Item visibility"                >*/
-  GIMP_UNDO_GROUP_ITEM_LINKED,           /*< desc="Link/Unlink item"               >*/
   GIMP_UNDO_GROUP_ITEM_LOCK_CONTENTS,    /*< desc="Lock/Unlock contents"           >*/
   GIMP_UNDO_GROUP_ITEM_LOCK_POSITION,    /*< desc="Lock/Unlock position"           >*/
   GIMP_UNDO_GROUP_ITEM_LOCK_VISIBILITY,  /*< desc="Lock/Unlock visibility"         >*/
@@ -593,7 +592,6 @@ typedef enum /*< pdb-skip >*/
   GIMP_UNDO_ITEM_RENAME,                 /*< desc="Rename item"                    >*/
   GIMP_UNDO_ITEM_DISPLACE,               /*< desc="Move item"                      >*/
   GIMP_UNDO_ITEM_VISIBILITY,             /*< desc="Item visibility"                >*/
-  GIMP_UNDO_ITEM_LINKED,                 /*< desc="Link/Unlink item"               >*/
   GIMP_UNDO_ITEM_COLOR_TAG,              /*< desc="Item color tag"                 >*/
   GIMP_UNDO_ITEM_LOCK_CONTENT,           /*< desc="Lock/Unlock content"            >*/
   GIMP_UNDO_ITEM_LOCK_POSITION,          /*< desc="Lock/Unlock position"           >*/
diff --git a/app/core/gimpimage-new.c b/app/core/gimpimage-new.c
index ab19e1acbc..e9e7308a6a 100644
--- a/app/core/gimpimage-new.c
+++ b/app/core/gimpimage-new.c
@@ -219,7 +219,6 @@ gimp_image_new_from_drawable (Gimp         *gimp,
   gimp_item_get_offset (GIMP_ITEM (new_layer), &off_x, &off_y);
   gimp_item_translate (GIMP_ITEM (new_layer), -off_x, -off_y, FALSE);
   gimp_item_set_visible (GIMP_ITEM (new_layer), TRUE, FALSE);
-  gimp_item_set_linked (GIMP_ITEM (new_layer), FALSE, FALSE);
   gimp_layer_set_mode (new_layer,
                        gimp_image_get_default_new_layer_mode (new_image),
                        FALSE);
@@ -316,9 +315,6 @@ gimp_image_new_copy_drawables (GimpImage *image,
           gimp_object_set_name (GIMP_OBJECT (new_layer),
                                 gimp_object_get_name (iter->data));
 
-          gimp_item_set_linked (GIMP_ITEM (new_layer),
-                                gimp_item_get_linked (iter->data), FALSE);
-
           /* Visibility, mode and opacity mimic the source image if
            * multiple items are copied. Otherwise we just set them to
            * defaults.
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index c965d06083..6f8e617d78 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -110,7 +110,10 @@ struct _GimpImagePrivate
   GimpItemTree      *channels;              /*  the tree of masks            */
   GimpItemTree      *vectors;               /*  the tree of vectors          */
   GSList            *layer_stack;           /*  the layers in MRU order      */
-  GList             *linked_layers;
+
+  GList             *stored_layer_sets;
+  GList             *stored_channel_sets;
+  GList             *stored_vectors_sets;
 
   GQuark             layer_offset_x_handler;
   GQuark             layer_offset_y_handler;
diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c
index c2f9190114..aa4a05e42c 100644
--- a/app/core/gimpimage-undo-push.c
+++ b/app/core/gimpimage-undo-push.c
@@ -418,22 +418,6 @@ gimp_image_undo_push_item_visibility (GimpImage   *image,
                                NULL);
 }
 
-GimpUndo *
-gimp_image_undo_push_item_linked (GimpImage   *image,
-                                  const gchar *undo_desc,
-                                  GimpItem    *item)
-{
-  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
-  g_return_val_if_fail (GIMP_IS_ITEM (item), NULL);
-  g_return_val_if_fail (gimp_item_is_attached (item), NULL);
-
-  return gimp_image_undo_push (image, GIMP_TYPE_ITEM_PROP_UNDO,
-                               GIMP_UNDO_ITEM_LINKED, undo_desc,
-                               GIMP_DIRTY_ITEM_META,
-                               "item", item,
-                               NULL);
-}
-
 GimpUndo *
 gimp_image_undo_push_item_color_tag (GimpImage   *image,
                                      const gchar *undo_desc,
diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h
index 57a3ec9fc0..e9081885db 100644
--- a/app/core/gimpimage-undo-push.h
+++ b/app/core/gimpimage-undo-push.h
@@ -101,9 +101,6 @@ GimpUndo * gimp_image_undo_push_item_displace       (GimpImage     *image,
 GimpUndo * gimp_image_undo_push_item_visibility     (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpItem      *item);
-GimpUndo * gimp_image_undo_push_item_linked         (GimpImage     *image,
-                                                     const gchar   *undo_desc,
-                                                     GimpItem      *item);
 GimpUndo * gimp_image_undo_push_item_color_tag      (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpItem      *item);
diff --git a/app/core/gimpimage-undo.c b/app/core/gimpimage-undo.c
index fbf808b650..42a12d6591 100644
--- a/app/core/gimpimage-undo.c
+++ b/app/core/gimpimage-undo.c
@@ -642,7 +642,6 @@ gimp_image_undo_dirty_from_type (GimpUndoType undo_type)
       return GIMP_DIRTY_SELECTION;
 
     case GIMP_UNDO_GROUP_ITEM_VISIBILITY:
-    case GIMP_UNDO_GROUP_ITEM_LINKED:
     case GIMP_UNDO_GROUP_ITEM_PROPERTIES:
       return GIMP_DIRTY_ITEM_META;
 
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index e070bfc164..850a6f34f1 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -103,7 +103,6 @@ enum
   SELECTED_CHANNELS_CHANGED,
   SELECTED_VECTORS_CHANGED,
   SELECTED_LAYERS_CHANGED,
-  LINKED_ITEMS_CHANGED,
   COMPONENT_VISIBILITY_CHANGED,
   COMPONENT_ACTIVE_CHANGED,
   MASK_CHANGED,
@@ -127,7 +126,9 @@ enum
   PARASITE_DETACHED,
   COLORMAP_CHANGED,
   UNDO_EVENT,
-  LAYER_LINKS_CHANGED,
+  LAYER_SETS_CHANGED,
+  CHANNEL_SETS_CHANGED,
+  VECTORS_SETS_CHANGED,
   LAST_SIGNAL
 };
 
@@ -359,14 +360,6 @@ gimp_image_class_init (GimpImageClass *klass)
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
-  gimp_image_signals[LINKED_ITEMS_CHANGED] =
-    g_signal_new ("linked-items-changed",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GimpImageClass, linked_items_changed),
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 0);
-
   gimp_image_signals[COMPONENT_VISIBILITY_CHANGED] =
     g_signal_new ("component-visibility-changed",
                   G_TYPE_FROM_CLASS (klass),
@@ -574,11 +567,27 @@ gimp_image_class_init (GimpImageClass *klass)
                   GIMP_TYPE_UNDO_EVENT,
                   GIMP_TYPE_UNDO);
 
-  gimp_image_signals[LAYER_LINKS_CHANGED] =
-    g_signal_new ("layer-links-changed",
+  gimp_image_signals[LAYER_SETS_CHANGED] =
+    g_signal_new ("layer-sets-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpImageClass, layer_sets_changed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  gimp_image_signals[CHANNEL_SETS_CHANGED] =
+    g_signal_new ("channel-sets-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpImageClass, channel_sets_changed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  gimp_image_signals[VECTORS_SETS_CHANGED] =
+    g_signal_new ("vectors-sets-changed",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GimpImageClass, layer_links_changed),
+                  G_STRUCT_OFFSET (GimpImageClass, vectors_sets_changed),
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
@@ -786,7 +795,9 @@ gimp_image_init (GimpImage *image)
                                                      GIMP_TYPE_VECTORS);
   private->layer_stack         = NULL;
 
-  private->linked_layers       = NULL;
+  private->stored_layer_sets   = NULL;
+  private->stored_channel_sets = NULL;
+  private->stored_vectors_sets = NULL;
 
   g_signal_connect (private->projection, "notify::buffer",
                     G_CALLBACK (gimp_image_projection_buffer_notify),
@@ -1065,7 +1076,9 @@ gimp_image_dispose (GObject *object)
 
   gimp_image_undo_free (image);
 
-  g_list_free_full (private->linked_layers, g_object_unref);
+  g_list_free_full (private->stored_layer_sets, g_object_unref);
+  g_list_free_full (private->stored_channel_sets, g_object_unref);
+  g_list_free_full (private->stored_vectors_sets, g_object_unref);
 
   g_signal_handlers_disconnect_by_func (private->layers->container,
                                         gimp_image_invalidate,
@@ -3575,14 +3588,6 @@ gimp_image_alpha_changed (GimpImage *image)
   g_signal_emit (image, gimp_image_signals[ALPHA_CHANGED], 0);
 }
 
-void
-gimp_image_linked_items_changed (GimpImage *image)
-{
-  g_return_if_fail (GIMP_IS_IMAGE (image));
-
-  g_signal_emit (image, gimp_image_signals[LINKED_ITEMS_CHANGED], 0);
-}
-
 void
 gimp_image_invalidate (GimpImage *image,
                        gint       x,
@@ -5391,8 +5396,8 @@ gimp_image_add_layers (GimpImage   *image,
 /*
  * gimp_image_store_item_set:
  * @image:
- * @set: (transfer full): a set of linked items which @images takes
- *                        ownership of.
+ * @set: (transfer full): a set of items which @images takes ownership
+ *                        of.
  *
  * Store a new set of @layers.
  * If a set with the same name and type existed, this call will silently
@@ -5402,19 +5407,37 @@ void
 gimp_image_store_item_set (GimpImage    *image,
                            GimpItemList *set)
 {
-  GimpImagePrivate *private;
-  GList            *iter;
+  GimpImagePrivate  *private;
+  GList            **stored_sets;
+  GList             *iter;
+  guint              signal;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (GIMP_IS_ITEM_LIST (set));
-  /* XXX Only layer sets supported so far as we haven't enabled
-   * multi-selection of channels and vectors yet.
-   */
-  g_return_if_fail (gimp_item_list_get_item_type (set) == GIMP_TYPE_LAYER);
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
-  for (iter = private->linked_layers; iter; iter = iter->next)
+  if (gimp_item_list_get_item_type (set) == GIMP_TYPE_LAYER)
+    {
+      stored_sets = &private->stored_layer_sets;
+      signal = gimp_image_signals[LAYER_SETS_CHANGED];
+    }
+  else if (gimp_item_list_get_item_type (set) == GIMP_TYPE_CHANNEL)
+    {
+      stored_sets = &private->stored_channel_sets;
+      signal = gimp_image_signals[CHANNEL_SETS_CHANGED];
+    }
+  else if (gimp_item_list_get_item_type (set) == GIMP_TYPE_VECTORS)
+    {
+      stored_sets = &private->stored_vectors_sets;
+      signal = gimp_image_signals[VECTORS_SETS_CHANGED];
+    }
+  else
+    {
+      g_return_if_reached ();
+    }
+
+  for (iter = *stored_sets; iter; iter = iter->next)
     {
       /* Remove a previous item set of same type and name. */
       if (gimp_item_list_is_pattern (iter->data) == gimp_item_list_is_pattern (set) &&
@@ -5424,15 +5447,15 @@ gimp_image_store_item_set (GimpImage    *image,
   if (iter)
     {
       g_object_unref (iter->data);
-      private->linked_layers = g_list_delete_link (private->linked_layers, iter);
+      *stored_sets = g_list_delete_link (*stored_sets, iter);
     }
 
-  private->linked_layers = g_list_prepend (private->linked_layers, set);
-  g_signal_emit (image, gimp_image_signals[LAYER_LINKS_CHANGED], 0);
+  *stored_sets = g_list_prepend (*stored_sets, set);
+  g_signal_emit (image, signal, 0);
 }
 
 /*
- * @gimp_image_unlink_layers:
+ * @gimp_image_unlink_item_set:
  * @image:
  * @link_name:
  *
@@ -5445,21 +5468,43 @@ gboolean
 gimp_image_unlink_item_set (GimpImage    *image,
                             GimpItemList *set)
 {
-  GimpImagePrivate *private;
-  GList            *found;
-  gboolean          success;
+  GimpImagePrivate  *private;
+  GList             *found;
+  GList            **stored_sets;
+  guint              signal;
+  gboolean           success;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
-  found = g_list_find (private->linked_layers, set);
+  if (gimp_item_list_get_item_type (set) == GIMP_TYPE_LAYER)
+    {
+      stored_sets = &private->stored_layer_sets;
+      signal = gimp_image_signals[LAYER_SETS_CHANGED];
+    }
+  else if (gimp_item_list_get_item_type (set) == GIMP_TYPE_CHANNEL)
+    {
+      stored_sets = &private->stored_channel_sets;
+      signal = gimp_image_signals[CHANNEL_SETS_CHANGED];
+    }
+  else if (gimp_item_list_get_item_type (set) == GIMP_TYPE_VECTORS)
+    {
+      stored_sets = &private->stored_vectors_sets;
+      signal = gimp_image_signals[VECTORS_SETS_CHANGED];
+    }
+  else
+    {
+      g_return_val_if_reached (FALSE);
+    }
+
+  found = g_list_find (*stored_sets, set);
   success = (found != NULL);
   if (success)
     {
-      private->linked_layers = g_list_delete_link (private->linked_layers, found);
+      *stored_sets = g_list_delete_link (*stored_sets, found);
       g_object_unref (set);
-      g_signal_emit (image, gimp_image_signals[LAYER_LINKS_CHANGED], 0);
+      g_signal_emit (image, signal, 0);
     }
 
   return success;
@@ -5473,7 +5518,8 @@ gimp_image_unlink_item_set (GimpImage    *image,
  *          should not modify). Order of items is not relevant.
  */
 GList *
-gimp_image_get_stored_item_sets (GimpImage *image)
+gimp_image_get_stored_item_sets (GimpImage *image,
+                                 GType      item_type)
 {
   GimpImagePrivate *private;
 
@@ -5481,7 +5527,14 @@ gimp_image_get_stored_item_sets (GimpImage *image)
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
-  return private->linked_layers;
+  if (item_type == GIMP_TYPE_LAYER)
+    return private->stored_layer_sets;
+  else if (item_type == GIMP_TYPE_CHANNEL)
+    return private->stored_channel_sets;
+  else if (item_type == GIMP_TYPE_VECTORS)
+    return private->stored_vectors_sets;
+
+  g_return_val_if_reached (FALSE);
 }
 
 /*
@@ -5496,18 +5549,29 @@ void
 gimp_image_select_item_set (GimpImage    *image,
                             GimpItemList *set)
 {
-  GList  *linked;
+  GList  *items;
   GError *error = NULL;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (GIMP_IS_ITEM_LIST (set));
 
-  linked = gimp_item_list_get_items (set, &error);
+  items = gimp_item_list_get_items (set, &error);
 
   if (! error)
-    gimp_image_set_selected_layers (image, linked);
+    {
+      GType item_type = gimp_item_list_get_item_type (set);
+
+      if (item_type == GIMP_TYPE_LAYER)
+        gimp_image_set_selected_layers (image, items);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        gimp_image_set_selected_channels (image, items);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        gimp_image_set_selected_vectors (image, items);
+      else
+        g_return_if_reached ();
+    }
 
-  g_list_free (linked);
+  g_list_free (items);
   g_clear_error (&error);
 }
 
@@ -5516,40 +5580,51 @@ gimp_image_select_item_set (GimpImage    *image,
  * @image:
  * @set:
  *
- * Add the layers belonging to the set named @link_name (which must
- * exist) to the layers currently selected in @image.
- *
- * Returns: %TRUE if the selection change is done (even if it turned out
- *          selected layers stay the same), %FALSE if no sets with this
- *          name existed.
+ * Add the layers belonging to @set to the items currently selected in
+ * @image.
  */
 void
 gimp_image_add_item_set (GimpImage    *image,
                          GimpItemList *set)
 {
-  GList  *linked;
+  GList  *items;
   GError *error = NULL;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (GIMP_IS_ITEM_LIST (set));
 
-  linked = gimp_item_list_get_items (set, &error);
+  items = gimp_item_list_get_items (set, &error);
 
   if (! error)
     {
-      GList *layers;
+      GList *selected;
       GList *iter;
+      GType  item_type = gimp_item_list_get_item_type (set);
+
+      if (item_type == GIMP_TYPE_LAYER)
+        selected = gimp_image_get_selected_layers (image);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        selected = gimp_image_get_selected_channels (image);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        selected = gimp_image_get_selected_vectors (image);
+      else
+        g_return_if_reached ();
 
-      layers = gimp_image_get_selected_layers (image);
-      layers = g_list_copy (layers);
-      for (iter = linked; iter; iter = iter->next)
+      selected = g_list_copy (selected);
+      for (iter = items; iter; iter = iter->next)
         {
-          if (! g_list_find (layers, iter->data))
-            layers = g_list_prepend (layers, iter->data);
+          if (! g_list_find (selected, iter->data))
+            selected = g_list_prepend (selected, iter->data);
         }
 
-      gimp_image_set_selected_layers (image, layers);
-      g_list_free (layers);
+      if (item_type == GIMP_TYPE_LAYER)
+        gimp_image_set_selected_layers (image, selected);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        gimp_image_set_selected_channels (image, selected);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        gimp_image_set_selected_vectors (image, items);
+
+      g_list_free (selected);
     }
   g_clear_error (&error);
 }
@@ -5570,31 +5645,46 @@ void
 gimp_image_remove_item_set (GimpImage    *image,
                             GimpItemList *set)
 {
-  GList  *linked;
+  GList  *items;
   GError *error = NULL;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (GIMP_IS_ITEM_LIST (set));
 
-  linked = gimp_item_list_get_items (set, &error);
+  items = gimp_item_list_get_items (set, &error);
 
   if (! error)
     {
-      GList *layers;
+      GList *selected;
       GList *iter;
+      GType  item_type = gimp_item_list_get_item_type (set);
+
+      if (item_type == GIMP_TYPE_LAYER)
+        selected = gimp_image_get_selected_layers (image);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        selected = gimp_image_get_selected_channels (image);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        selected = gimp_image_get_selected_vectors (image);
+      else
+        g_return_if_reached ();
 
-      layers = gimp_image_get_selected_layers (image);
-      layers = g_list_copy (layers);
-      for (iter = linked; iter; iter = iter->next)
+      selected = g_list_copy (selected);
+      for (iter = items; iter; iter = iter->next)
         {
           GList *remove;
 
-          if ((remove = g_list_find (layers, iter->data)))
-            layers = g_list_delete_link (layers, remove);
+          if ((remove = g_list_find (selected, iter->data)))
+            selected = g_list_delete_link (selected, remove);
         }
 
-      gimp_image_set_selected_layers (image, layers);
-      g_list_free (layers);
+      if (item_type == GIMP_TYPE_LAYER)
+        gimp_image_set_selected_layers (image, selected);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        gimp_image_set_selected_channels (image, selected);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        gimp_image_set_selected_vectors (image, items);
+
+      g_list_free (selected);
     }
   g_clear_error (&error);
 }
@@ -5616,36 +5706,51 @@ void
 gimp_image_intersect_item_set (GimpImage    *image,
                                GimpItemList *set)
 {
-  GList *linked;
+  GList *items;
   GError *error = NULL;
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (GIMP_IS_ITEM_LIST (set));
 
-  linked = gimp_item_list_get_items (set, &error);
+  items = gimp_item_list_get_items (set, &error);
 
   if (! error)
     {
-      GList *layers;
+      GList *selected;
       GList *remove = NULL;
       GList *iter;
+      GType  item_type = gimp_item_list_get_item_type (set);
+
+      if (item_type == GIMP_TYPE_LAYER)
+        selected = gimp_image_get_selected_layers (image);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        selected = gimp_image_get_selected_channels (image);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        selected = gimp_image_get_selected_vectors (image);
+      else
+        g_return_if_reached ();
 
-      layers = gimp_image_get_selected_layers (image);
-      layers = g_list_copy (layers);
+      selected = g_list_copy (selected);
 
-      /* Remove items in layers but not in linked. */
-      for (iter = layers; iter; iter = iter->next)
+      /* Remove items in selected but not in items. */
+      for (iter = selected; iter; iter = iter->next)
         {
-          if (! g_list_find (linked, iter->data))
+          if (! g_list_find (items, iter->data))
             remove = g_list_prepend (remove, iter);
         }
       for (iter = remove; iter; iter = iter->next)
-        layers = g_list_delete_link (layers, iter->data);
+        selected = g_list_delete_link (selected, iter->data);
       g_list_free (remove);
 
       /* Finally select the intersection. */
-      gimp_image_set_selected_layers (image, layers);
-      g_list_free (layers);
+      if (item_type == GIMP_TYPE_LAYER)
+        gimp_image_set_selected_layers (image, selected);
+      else if (item_type == GIMP_TYPE_CHANNEL)
+        gimp_image_set_selected_channels (image, selected);
+      else if (item_type == GIMP_TYPE_VECTORS)
+        gimp_image_set_selected_vectors (image, items);
+
+      g_list_free (selected);
     }
   g_clear_error (&error);
 }
diff --git a/app/core/gimpimage.h b/app/core/gimpimage.h
index b3f0de5eb7..845e648db5 100644
--- a/app/core/gimpimage.h
+++ b/app/core/gimpimage.h
@@ -104,7 +104,9 @@ struct _GimpImageClass
   void (* undo_event)                   (GimpImage            *image,
                                          GimpUndoEvent         event,
                                          GimpUndo             *undo);
-  void (* layer_links_changed)          (GimpImage            *image);
+  void (* layer_sets_changed)           (GimpImage            *image);
+  void (* channel_sets_changed)         (GimpImage            *image);
+  void (* vectors_sets_changed)         (GimpImage            *image);
 };
 
 
@@ -256,7 +258,6 @@ GimpComponentMask gimp_image_get_visible_mask    (GimpImage          *image);
 void            gimp_image_mode_changed          (GimpImage          *image);
 void            gimp_image_precision_changed     (GimpImage          *image);
 void            gimp_image_alpha_changed         (GimpImage          *image);
-void            gimp_image_linked_items_changed  (GimpImage          *image);
 void            gimp_image_invalidate            (GimpImage          *image,
                                                   gint                x,
                                                   gint                y,
@@ -458,7 +459,8 @@ void            gimp_image_store_item_set        (GimpImage          *image,
                                                   GimpItemList       *set);
 gboolean        gimp_image_unlink_item_set       (GimpImage          *image,
                                                   GimpItemList       *set);
-GList         * gimp_image_get_stored_item_sets   (GimpImage         *image);
+GList         * gimp_image_get_stored_item_sets   (GimpImage         *image,
+                                                   GType              item_type);
 void            gimp_image_select_item_set       (GimpImage          *image,
                                                   GimpItemList       *set);
 void            gimp_image_add_item_set          (GimpImage          *image,
diff --git a/app/core/gimpitem-exclusive.c b/app/core/gimpitem-exclusive.c
index dc680be8d2..d449922c1c 100644
--- a/app/core/gimpitem-exclusive.c
+++ b/app/core/gimpitem-exclusive.c
@@ -160,93 +160,6 @@ gimp_item_toggle_exclusive (GimpItem               *item,
   g_list_free (ancestry);
 }
 
-void
-gimp_item_toggle_exclusive_linked (GimpItem    *item,
-                                   GimpContext *context)
-{
-  GList *on  = NULL;
-  GList *off = NULL;
-  GList *list;
-
-  g_return_if_fail (GIMP_IS_ITEM (item));
-  g_return_if_fail (gimp_item_is_attached (item));
-  g_return_if_fail (GIMP_IS_CONTEXT (context));
-
-  for (list = gimp_item_get_container_iter (item);
-       list;
-       list = g_list_next (list))
-    {
-      GimpItem *other = list->data;
-
-      if (other != item)
-        {
-          if (gimp_item_get_linked (other))
-            on = g_list_prepend (on, other);
-          else
-            off = g_list_prepend (off, other);
-        }
-    }
-
-  if (on || off || ! gimp_item_get_linked (item))
-    {
-      GimpImage *image = gimp_item_get_image (item);
-      GimpUndo  *undo;
-      gboolean   push_undo = TRUE;
-
-      undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
-                                           GIMP_UNDO_GROUP_ITEM_LINKED);
-
-      if (undo && (g_object_get_data (G_OBJECT (undo), "exclusive-linked-item") ==
-                   (gpointer) item))
-        push_undo = FALSE;
-
-      if (push_undo)
-        {
-          if (gimp_image_undo_group_start (image,
-                                           GIMP_UNDO_GROUP_ITEM_LINKED,
-                                           _("Set Item Exclusive Linked")))
-            {
-              undo = gimp_image_undo_can_compress (image, GIMP_TYPE_UNDO_STACK,
-                                                   GIMP_UNDO_GROUP_ITEM_LINKED);
-
-              if (undo)
-                g_object_set_data (G_OBJECT (undo), "exclusive-linked-item",
-                                   (gpointer) item);
-            }
-
-          gimp_image_undo_push_item_linked (image, NULL, item);
-
-          for (list = on; list; list = g_list_next (list))
-            gimp_image_undo_push_item_linked (image, NULL, list->data);
-
-          for (list = off; list; list = g_list_next (list))
-            gimp_image_undo_push_item_linked (image, NULL, list->data);
-
-          gimp_image_undo_group_end (image);
-        }
-      else
-        {
-          gimp_undo_refresh_preview (undo, context);
-        }
-
-      if (off || ! gimp_item_get_linked (item))
-        {
-          gimp_item_set_linked (item, TRUE, FALSE);
-
-          for (list = off; list; list = g_list_next (list))
-            gimp_item_set_linked (list->data, TRUE, FALSE);
-        }
-      else
-        {
-          for (list = on; list; list = g_list_next (list))
-            gimp_item_set_linked (list->data, FALSE, FALSE);
-        }
-
-      g_list_free (on);
-      g_list_free (off);
-    }
-}
-
 
 /*  private functions  */
 
diff --git a/app/core/gimpitem-exclusive.h b/app/core/gimpitem-exclusive.h
index efb7030df9..2bf3a63719 100644
--- a/app/core/gimpitem-exclusive.h
+++ b/app/core/gimpitem-exclusive.h
@@ -44,8 +44,6 @@ void   gimp_item_toggle_exclusive         (GimpItem             *item,
                                            GimpUndoType          group_undo_type,
                                            gboolean              only_selected,
                                            GimpContext          *context);
-void   gimp_item_toggle_exclusive_linked  (GimpItem             *item,
-                                           GimpContext          *context);
 
 
 #endif /* __GIMP_ITEM_EXCLUSIVE_H__ */
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index fb236debab..f4817bba6b 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -589,7 +589,6 @@ gimp_item_real_duplicate (GimpItem *item,
   GET_PRIVATE (new_item)->parasites = gimp_parasite_list_copy (private->parasites);
 
   gimp_item_set_visible   (new_item, gimp_item_get_visible   (item), FALSE);
-  gimp_item_set_linked    (new_item, gimp_item_get_linked    (item), FALSE);
   gimp_item_set_color_tag (new_item, gimp_item_get_color_tag (item), FALSE);
 
   if (gimp_item_can_lock_content (new_item))
@@ -2097,7 +2096,6 @@ gimp_item_replace_item (GimpItem *item,
                       gimp_item_get_height (replace));
 
   gimp_item_set_visible       (item, gimp_item_get_visible (replace), FALSE);
-  gimp_item_set_linked        (item, gimp_item_get_linked (replace), FALSE);
   gimp_item_set_color_tag     (item, gimp_item_get_color_tag (replace), FALSE);
   gimp_item_set_lock_content  (item, gimp_item_get_lock_content (replace), FALSE);
   gimp_item_set_lock_position (item, gimp_item_get_lock_position (replace), FALSE);
@@ -2382,34 +2380,6 @@ gimp_item_bind_visible_to_active (GimpItem *item,
     gimp_filter_set_active (GIMP_FILTER (item), gimp_item_get_visible (item));
 }
 
-void
-gimp_item_set_linked (GimpItem *item,
-                      gboolean  linked,
-                      gboolean  push_undo)
-{
-  g_return_if_fail (GIMP_IS_ITEM (item));
-
-  linked = linked ? TRUE : FALSE;
-
-  if (gimp_item_get_linked (item) != linked)
-    {
-      GimpImage *image       = gimp_item_get_image (item);
-      gboolean   is_attached = gimp_item_is_attached (item);
-
-      if (push_undo && is_attached && image)
-        gimp_image_undo_push_item_linked (image, NULL, item);
-
-      GET_PRIVATE (item)->linked = linked;
-
-      g_signal_emit (item, gimp_item_signals[LINKED_CHANGED], 0);
-
-      if (is_attached && image)
-        gimp_image_linked_items_changed (image);
-
-      g_object_notify_by_pspec (G_OBJECT (item), gimp_item_props[PROP_LINKED]);
-    }
-}
-
 gboolean
 gimp_item_get_linked (GimpItem *item)
 {
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index a12a1487c2..53ae990430 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -364,9 +364,6 @@ gboolean        gimp_item_is_visible         (GimpItem           *item);
 void        gimp_item_bind_visible_to_active (GimpItem           *item,
                                               gboolean            bind);
 
-void            gimp_item_set_linked         (GimpItem           *item,
-                                              gboolean            linked,
-                                              gboolean            push_undo);
 gboolean        gimp_item_get_linked         (GimpItem           *item);
 
 void            gimp_item_set_color_tag      (GimpItem           *item,
diff --git a/app/core/gimpitempropundo.c b/app/core/gimpitempropundo.c
index 4c96c203e5..f4ad681c5e 100644
--- a/app/core/gimpitempropundo.c
+++ b/app/core/gimpitempropundo.c
@@ -123,10 +123,6 @@ gimp_item_prop_undo_constructed (GObject *object)
       item_prop_undo->visible = gimp_item_get_visible (item);
       break;
 
-    case GIMP_UNDO_ITEM_LINKED:
-      item_prop_undo->linked = gimp_item_get_linked (item);
-      break;
-
     case GIMP_UNDO_ITEM_COLOR_TAG:
       item_prop_undo->color_tag = gimp_item_get_color_tag (item);
       break;
@@ -283,16 +279,6 @@ gimp_item_prop_undo_pop (GimpUndo            *undo,
       }
       break;
 
-    case GIMP_UNDO_ITEM_LINKED:
-      {
-        gboolean linked;
-
-        linked = gimp_item_get_linked (item);
-        gimp_item_set_linked (item, item_prop_undo->linked, FALSE);
-        item_prop_undo->linked = linked;
-      }
-      break;
-
     case GIMP_UNDO_ITEM_COLOR_TAG:
       {
         GimpColorTag color_tag;
diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c
index 7949720423..dfce2570c2 100644
--- a/app/display/gimpdisplayshell-dnd.c
+++ b/app/display/gimpdisplayshell-dnd.c
@@ -251,7 +251,6 @@ gimp_display_shell_drop_drawable (GtkWidget    *widget,
       gimp_display_shell_dnd_position_item (shell, image, new_item);
 
       gimp_item_set_visible (new_item, TRUE, FALSE);
-      gimp_item_set_linked (new_item, FALSE, FALSE);
 
       gimp_image_add_layer (image, new_layer,
                             GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
diff --git a/app/gimpcore.def b/app/gimpcore.def
index 12b40500aa..b93cbb91ba 100644
--- a/app/gimpcore.def
+++ b/app/gimpcore.def
@@ -374,7 +374,6 @@ EXPORTS
        gimp_image_undo_push
        gimp_image_undo_push_drawable_mod
        gimp_image_undo_push_image_grid
-       gimp_image_undo_push_item_linked
        gimp_image_undo_push_item_visibility
        gimp_image_undo_push_text_layer
        gimp_image_undo_push_text_layer_modified
@@ -405,7 +404,6 @@ EXPORTS
        gimp_item_resize
        gimp_item_rotate
        gimp_item_scale_by_origin
-       gimp_item_set_linked
        gimp_item_set_visible
        gimp_item_stroke
        gimp_item_transform
diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c
index 08410e66eb..25446a4097 100644
--- a/app/pdb/internal-procs.c
+++ b/app/pdb/internal-procs.c
@@ -28,7 +28,7 @@
 #include "internal-procs.h"
 
 
-/* 761 procedures registered total */
+/* 759 procedures registered total */
 
 void
 internal_procs_init (GimpPDB *pdb)
diff --git a/app/pdb/item-cmds.c b/app/pdb/item-cmds.c
index f5901e7948..aa5919bd30 100644
--- a/app/pdb/item-cmds.c
+++ b/app/pdb/item-cmds.c
@@ -634,59 +634,6 @@ item_set_visible_invoker (GimpProcedure         *procedure,
                                            error ? *error : NULL);
 }
 
-static GimpValueArray *
-item_get_linked_invoker (GimpProcedure         *procedure,
-                         Gimp                  *gimp,
-                         GimpContext           *context,
-                         GimpProgress          *progress,
-                         const GimpValueArray  *args,
-                         GError               **error)
-{
-  gboolean success = TRUE;
-  GimpValueArray *return_vals;
-  GimpItem *item;
-  gboolean linked = FALSE;
-
-  item = g_value_get_object (gimp_value_array_index (args, 0));
-
-  if (success)
-    {
-      linked = gimp_item_get_linked (GIMP_ITEM (item));
-    }
-
-  return_vals = gimp_procedure_get_return_values (procedure, success,
-                                                  error ? *error : NULL);
-
-  if (success)
-    g_value_set_boolean (gimp_value_array_index (return_vals, 1), linked);
-
-  return return_vals;
-}
-
-static GimpValueArray *
-item_set_linked_invoker (GimpProcedure         *procedure,
-                         Gimp                  *gimp,
-                         GimpContext           *context,
-                         GimpProgress          *progress,
-                         const GimpValueArray  *args,
-                         GError               **error)
-{
-  gboolean success = TRUE;
-  GimpItem *item;
-  gboolean linked;
-
-  item = g_value_get_object (gimp_value_array_index (args, 0));
-  linked = g_value_get_boolean (gimp_value_array_index (args, 1));
-
-  if (success)
-    {
-      gimp_item_set_linked (GIMP_ITEM (item), linked, TRUE);
-    }
-
-  return gimp_procedure_get_return_values (procedure, success,
-                                           error ? *error : NULL);
-}
-
 static GimpValueArray *
 item_get_lock_content_invoker (GimpProcedure         *procedure,
                                Gimp                  *gimp,
@@ -1637,64 +1584,6 @@ register_item_procs (GimpPDB *pdb)
   gimp_pdb_register_procedure (pdb, procedure);
   g_object_unref (procedure);
 
-  /*
-   * gimp-item-get-linked
-   */
-  procedure = gimp_procedure_new (item_get_linked_invoker);
-  gimp_object_set_static_name (GIMP_OBJECT (procedure),
-                               "gimp-item-get-linked");
-  gimp_procedure_set_static_help (procedure,
-                                  "Get the linked state of the specified item.",
-                                  "This procedure returns the specified item's linked state.",
-                                  NULL);
-  gimp_procedure_set_static_attribution (procedure,
-                                         "Wolfgang Hofer",
-                                         "Wolfgang Hofer",
-                                         "1998");
-  gimp_procedure_add_argument (procedure,
-                               gimp_param_spec_item ("item",
-                                                     "item",
-                                                     "The item",
-                                                     FALSE,
-                                                     GIMP_PARAM_READWRITE));
-  gimp_procedure_add_return_value (procedure,
-                                   g_param_spec_boolean ("linked",
-                                                         "linked",
-                                                         "The item linked state (for moves)",
-                                                         FALSE,
-                                                         GIMP_PARAM_READWRITE));
-  gimp_pdb_register_procedure (pdb, procedure);
-  g_object_unref (procedure);
-
-  /*
-   * gimp-item-set-linked
-   */
-  procedure = gimp_procedure_new (item_set_linked_invoker);
-  gimp_object_set_static_name (GIMP_OBJECT (procedure),
-                               "gimp-item-set-linked");
-  gimp_procedure_set_static_help (procedure,
-                                  "Set the linked state of the specified item.",
-                                  "This procedure sets the specified item's linked state.",
-                                  NULL);
-  gimp_procedure_set_static_attribution (procedure,
-                                         "Wolfgang Hofer",
-                                         "Wolfgang Hofer",
-                                         "1998");
-  gimp_procedure_add_argument (procedure,
-                               gimp_param_spec_item ("item",
-                                                     "item",
-                                                     "The item",
-                                                     FALSE,
-                                                     GIMP_PARAM_READWRITE));
-  gimp_procedure_add_argument (procedure,
-                               g_param_spec_boolean ("linked",
-                                                     "linked",
-                                                     "The new item linked state",
-                                                     FALSE,
-                                                     GIMP_PARAM_READWRITE));
-  gimp_pdb_register_procedure (pdb, procedure);
-  g_object_unref (procedure);
-
   /*
    * gimp-item-get-lock-content
    */
diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c
index 899397ad7e..13b9f0376e 100644
--- a/app/tools/gimptransformgridtool.c
+++ b/app/tools/gimptransformgridtool.c
@@ -193,10 +193,6 @@ static void      gimp_transform_grid_tool_widget_response    (GimpToolWidget
 static void      gimp_transform_grid_tool_filter_flush       (GimpDrawableFilter     *filter,
                                                               GimpTransformGridTool  *tg_tool);
 
-static void      gimp_transform_grid_tool_image_linked_items_changed
-                                                             (GimpImage              *image,
-                                                              GimpTransformGridTool  *tg_tool);
-
 static void      gimp_transform_grid_tool_halt               (GimpTransformGridTool  *tg_tool);
 static void      gimp_transform_grid_tool_commit             (GimpTransformGridTool  *tg_tool);
 
@@ -402,11 +398,6 @@ gimp_transform_grid_tool_initialize (GimpTool     *tool,
   if (tg_options->direction_chain_button)
     gtk_widget_set_sensitive (tg_options->direction_chain_button, TRUE);
 
-  g_signal_connect (
-    image, "linked-items-changed",
-    G_CALLBACK (gimp_transform_grid_tool_image_linked_items_changed),
-    tg_tool);
-
   return TRUE;
 }
 
@@ -1156,17 +1147,6 @@ gimp_transform_grid_tool_filter_flush (GimpDrawableFilter    *filter,
   gimp_projection_flush (gimp_image_get_projection (image));
 }
 
-static void
-gimp_transform_grid_tool_image_linked_items_changed (GimpImage             *image,
-                                                     GimpTransformGridTool *tg_tool)
-{
-  if (tg_tool->filters)
-    {
-      gimp_transform_grid_tool_update_filters (tg_tool);
-      gimp_transform_grid_tool_update_preview (tg_tool);
-    }
-}
-
 static void
 gimp_transform_grid_tool_halt (GimpTransformGridTool *tg_tool)
 {
@@ -1174,16 +1154,6 @@ gimp_transform_grid_tool_halt (GimpTransformGridTool *tg_tool)
   GimpTransformTool        *tr_tool    = GIMP_TRANSFORM_TOOL (tg_tool);
   GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool);
 
-  if (tool->display)
-    {
-      GimpImage *image = gimp_display_get_image (tool->display);
-
-      g_signal_handlers_disconnect_by_func (
-        image,
-        gimp_transform_grid_tool_image_linked_items_changed,
-        tg_tool);
-    }
-
   if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (tg_tool)))
     gimp_draw_tool_stop (GIMP_DRAW_TOOL (tg_tool));
 
diff --git a/app/widgets/gimpchanneltreeview.c b/app/widgets/gimpchanneltreeview.c
index 4f97fb090b..335c9681c7 100644
--- a/app/widgets/gimpchanneltreeview.c
+++ b/app/widgets/gimpchanneltreeview.c
@@ -223,8 +223,6 @@ gimp_channel_tree_view_drop_viewables (GimpContainerTreeView   *tree_view,
                                         gimp_item_tree_view_get_image (item_view),
                                         item_view_class->item_type);
 
-          gimp_item_set_linked (new_item, FALSE, FALSE);
-
           item_view_class->add_item (image, new_item, parent, index, TRUE);
 
           gimp_image_flush (image);
diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c
index 19cf4bfb6f..55a1cdabdb 100644
--- a/app/widgets/gimpitemtreeview.c
+++ b/app/widgets/gimpitemtreeview.c
@@ -1363,8 +1363,6 @@ gimp_item_tree_view_drop_viewables (GimpContainerTreeView   *tree_view,
           new_item = gimp_item_convert (GIMP_ITEM (src_viewable),
                                         item_view->priv->image, item_type);
 
-          gimp_item_set_linked (new_item, FALSE, FALSE);
-
           item_view_class->add_item (item_view->priv->image, new_item,
                                      parent, dest_index, TRUE);
         }
diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c
index f589314fd8..83715ca94a 100644
--- a/app/widgets/gimplayertreeview.c
+++ b/app/widgets/gimplayertreeview.c
@@ -1001,7 +1001,7 @@ gimp_layer_tree_view_set_image (GimpItemTreeView *view,
                         G_CALLBACK (gimp_layer_tree_view_floating_selection_changed),
                         view);
       g_signal_connect (gimp_item_tree_view_get_image (view),
-                        "layer-links-changed",
+                        "layer-sets-changed",
                         G_CALLBACK (gimp_layer_tree_view_layer_links_changed),
                         view);
 
@@ -1113,7 +1113,7 @@ gimp_layer_tree_view_layer_links_changed (GimpImage         *image,
   if (! image)
     return;
 
-  links = gimp_image_get_stored_item_sets (image);
+  links = gimp_image_get_stored_item_sets (image, GIMP_TYPE_LAYER);
 
   label_size = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
   for (iter = links; iter; iter = iter->next)
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index ba88b31248..6920956a81 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -48,6 +48,7 @@
 #include "core/gimpimage-sample-points.h"
 #include "core/gimpimage-symmetry.h"
 #include "core/gimpimage-undo.h"
+#include "core/gimpitemlist.h"
 #include "core/gimpitemstack.h"
 #include "core/gimplayer-floating-selection.h"
 #include "core/gimplayer-new.h"
@@ -683,6 +684,40 @@ xcf_load_image (Gimp     *gimp,
   if (info->selected_channels)
     gimp_image_set_selected_channels (image, info->selected_channels);
 
+  /* We don't have linked items concept anymore. We transform formerly
+   * linked items into stored sets of named items instead.
+   */
+  if (info->linked_layers)
+    {
+      GimpItemList *set;
+
+      set = gimp_item_list_named_new (image, GIMP_TYPE_LAYER,
+                                      _("Linked Layers"),
+                                      info->linked_layers);
+      gimp_image_store_item_set (image, set);
+      g_clear_pointer (&info->linked_layers, g_list_free);
+    }
+  if (info->linked_channels)
+    {
+      GimpItemList *set;
+
+      set = gimp_item_list_named_new (image, GIMP_TYPE_CHANNEL,
+                                      _("Linked Channels"),
+                                      info->linked_channels);
+      gimp_image_store_item_set (image, set);
+      g_clear_pointer (&info->linked_layers, g_list_free);
+    }
+  if (info->linked_paths)
+    {
+      GimpItemList *set;
+
+      set = gimp_item_list_named_new (image, GIMP_TYPE_VECTORS,
+                                      _("Linked Paths"),
+                                      info->linked_paths);
+      gimp_image_store_item_set (image, set);
+      g_clear_pointer (&info->linked_layers, g_list_free);
+    }
+
   if (info->file)
     gimp_image_set_file (image, info->file);
 
@@ -1251,7 +1286,8 @@ xcf_load_layer_props (XcfInfo    *info,
 
             xcf_read_int32 (info, (guint32 *) &linked, 1);
 
-            gimp_item_set_linked (GIMP_ITEM (*layer), linked, FALSE);
+            if (linked)
+              info->linked_layers = g_list_prepend (info->linked_layers, *layer);
           }
           break;
 
@@ -1755,7 +1791,8 @@ xcf_load_channel_props (XcfInfo      *info,
 
             xcf_read_int32 (info, (guint32 *) &linked, 1);
 
-            gimp_item_set_linked (GIMP_ITEM (*channel), linked, FALSE);
+            if (linked)
+              info->linked_channels = g_list_prepend (info->linked_channels, *channel);
           }
           break;
 
@@ -2894,7 +2931,8 @@ xcf_load_old_path (XcfInfo   *info,
   g_free (name);
   g_free (points);
 
-  gimp_item_set_linked (GIMP_ITEM (vectors), locked, FALSE);
+  if (locked)
+    info->linked_paths = g_list_prepend (info->linked_paths, vectors);
 
   if (tattoo)
     gimp_item_set_tattoo (GIMP_ITEM (vectors), tattoo);
@@ -2989,7 +3027,8 @@ xcf_load_vector (XcfInfo   *info,
   g_free (name);
 
   gimp_item_set_visible (GIMP_ITEM (vectors), visible, FALSE);
-  gimp_item_set_linked (GIMP_ITEM (vectors), linked, FALSE);
+  if (linked)
+    info->linked_paths = g_list_prepend (info->linked_paths, vectors);
 
   if (tattoo)
     gimp_item_set_tattoo (GIMP_ITEM (vectors), tattoo);
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index c3a0938d2e..b9fecf8f9a 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -107,6 +107,15 @@ struct _XcfInfo
   GimpTattoo          tattoo_state;
   GList              *selected_layers;
   GList              *selected_channels;
+
+  /* Old deprecated "linked" concept which we keep in the XcfInfo
+   * probably forever to transform these tags into named stored item
+   * sets instead.
+   */
+  GList              *linked_layers;
+  GList              *linked_channels;
+  GList              *linked_paths;
+
   GimpDrawable       *floating_sel_drawable;
   GimpLayer          *floating_sel;
   goffset             floating_sel_offset;
diff --git a/devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md 
b/devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md
index d6eb88e09a..6e9ea38d9a 100644
--- a/devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md
+++ b/devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md
@@ -41,7 +41,7 @@ possible in the previous API is obviously still possible.
 | `gimp_drawable_bpp()`                           | `gimp_drawable_get_bpp()`                         |
 | `gimp_drawable_delete()`                        | `gimp_item_delete()`                              |
 | `gimp_drawable_get_image()`                     | `gimp_item_get_image()`                           |
-| `gimp_drawable_get_linked()`                    | `gimp_item_get_linked()`                          |
+| `gimp_drawable_get_linked()`                    | *N/A*                                             |
 | `gimp_drawable_get_name()`                      | `gimp_item_get_name()`                            |
 | `gimp_drawable_get_tattoo()`                    | `gimp_item_get_tattoo()`                          |
 | `gimp_drawable_get_visible()`                   | `gimp_item_get_visible()`                         |
@@ -60,7 +60,7 @@ possible in the previous API is obviously still possible.
 | `gimp_drawable_preview_new()`                   | `gimp_drawable_preview_new_from_drawable()`       |
 | `gimp_drawable_preview_new_from_drawable_id()`  | `gimp_drawable_preview_new_from_drawable()`       |
 | `gimp_drawable_set_image()`                     | *N/A*                                             |
-| `gimp_drawable_set_linked()`                    | `gimp_item_set_linked()`                          |
+| `gimp_drawable_set_linked()`                    | *N/A*                                             |
 | `gimp_drawable_set_name()`                      | `gimp_item_set_name()`                            |
 | `gimp_drawable_set_tattoo()`                    | `gimp_item_set_tattoo()`                          |
 | `gimp_drawable_set_visible()`                   | `gimp_item_set_visible()`                         |
@@ -143,6 +143,8 @@ possible in the previous API is obviously still possible.
 | `gimp_image_width()`                            | `gimp_image_get_width()`                          |
 | `gimp_install_cmap()`                           | *N/A*                                             |
 | `gimp_invert()`                                 | `gimp_drawable_invert()`                          |
+| `gimp_item_get_linked()`                        | *N/A*                                             |
+| `gimp_item_set_linked()`                        | *N/A*                                             |
 | `gimp_layer_menu_new()`                         | `gimp_layer_combo_box_new()`                      |
 | `gimp_layer_scale_full()`                       | `gimp_layer_scale()`                              |
 | `gimp_layer_translate()`                        | `gimp_item_transform_translate()`                 |
@@ -162,14 +164,14 @@ possible in the previous API is obviously still possible.
 | `gimp_parasite_name()`                          | `gimp_parasite_get_name()`                        |
 | `gimp_path_delete()`                            | `gimp_image_remove_vectors()`                     |
 | `gimp_path_get_current()`                       | `gimp_image_get_active_vectors()`                 |
-| `gimp_path_get_locked()`                        | `gimp_item_get_linked()`                          |
+| `gimp_path_get_locked()`                        | *N/A*                                             |
 | `gimp_path_get_points()`                        | `gimp_vectors_stroke_get_points()`                |
 | `gimp_path_get_point_at_dist()`                 | `gimp_vectors_stroke_get_point_at_dist()`         |
 | `gimp_path_get_tattoo()`                        | `gimp_item_get_tattoo()`                          |
 | `gimp_path_import()`                            | `gimp_vectors_import_from_file()`                 |
 | `gimp_path_list()`                              | `gimp_image_get_vectors()`                        |
 | `gimp_path_set_current()`                       | `gimp_image_set_active_vectors()`                 |
-| `gimp_path_set_locked()`                        | `gimp_item_set_linked()`                          |
+| `gimp_path_set_locked()`                        | *N/A*                                             |
 | `gimp_path_set_points()`                        | `gimp_vectors_stroke_new_from_points()`           |
 | `gimp_path_set_tattoo()`                        | `gimp_item_set_tattoo()`                          |
 | `gimp_path_stroke_current()`                    | `gimp_edit_stroke_vectors()`                      |
@@ -199,7 +201,7 @@ possible in the previous API is obviously still possible.
 | `gimp_transform_2d()`                           | `gimp_item_transform_2d()`                        |
 | `gimp_unit_menu_update()`                       | `#GimpUnitComboBox`                               |
 | `gimp_vectors_get_image()`                      | `gimp_item_get_image()`                           |
-| `gimp_vectors_get_linked()`                     | `gimp_item_get_linked()`                          |
+| `gimp_vectors_get_linked()`                     | *N/A*                                             |
 | `gimp_vectors_get_name()`                       | `gimp_item_get_name()`                            |
 | `gimp_vectors_get_tattoo()`                     | `gimp_item_get_tattoo()`                          |
 | `gimp_vectors_get_visible()`                    | `gimp_item_get_visible()`                         |
@@ -208,7 +210,7 @@ possible in the previous API is obviously still possible.
 | `gimp_vectors_parasite_detach()`                | `gimp_item_detach_parasite()`                     |
 | `gimp_vectors_parasite_find()`                  | `gimp_item_get_parasite()`                        |
 | `gimp_vectors_parasite_list()`                  | `gimp_item_get_parasite_list()`                   |
-| `gimp_vectors_set_linked()`                     | `gimp_item_set_linked()`                          |
+| `gimp_vectors_set_linked()`                     | *N/A*                                             |
 | `gimp_vectors_set_name()`                       | `gimp_item_set_name()`                            |
 | `gimp_vectors_set_tattoo()`                     | `gimp_item_set_tattoo()`                          |
 | `gimp_vectors_set_visible()`                    | `gimp_item_set_visible()`                         |
diff --git a/devel-docs/app/app-sections.txt b/devel-docs/app/app-sections.txt
index ac552bc395..19b2ddf2b3 100644
--- a/devel-docs/app/app-sections.txt
+++ b/devel-docs/app/app-sections.txt
@@ -2514,7 +2514,6 @@ gimp_item_get_visible
 gimp_item_set_visible
 gimp_item_is_visible
 gimp_item_get_linked
-gimp_item_set_linked
 gimp_item_get_lock_content
 gimp_item_set_lock_content
 gimp_item_can_lock_content
@@ -11379,7 +11378,6 @@ gimp_image_undo_push_drawable_mod
 gimp_image_undo_push_mask
 gimp_image_undo_push_item_rename
 gimp_image_undo_push_item_displace
-gimp_image_undo_push_item_linked
 gimp_image_undo_push_item_visibility
 gimp_image_undo_push_item_reorder
 gimp_image_undo_push_item_parasite
diff --git a/devel-docs/libgimp/libgimp3-sections.txt b/devel-docs/libgimp/libgimp3-sections.txt
index 3a1ce66258..72a51768f6 100644
--- a/devel-docs/libgimp/libgimp3-sections.txt
+++ b/devel-docs/libgimp/libgimp3-sections.txt
@@ -733,8 +733,6 @@ gimp_item_get_name
 gimp_item_set_name
 gimp_item_get_visible
 gimp_item_set_visible
-gimp_item_get_linked
-gimp_item_set_linked
 gimp_item_get_lock_content
 gimp_item_set_lock_content
 gimp_item_get_lock_position
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index 8260814dfe..eaaad20487 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -512,7 +512,6 @@ EXPORTS
        gimp_item_get_expanded
        gimp_item_get_id
        gimp_item_get_image
-       gimp_item_get_linked
        gimp_item_get_lock_content
        gimp_item_get_lock_position
        gimp_item_get_lock_visibility
@@ -543,7 +542,6 @@ EXPORTS
        gimp_item_list_children
        gimp_item_set_color_tag
        gimp_item_set_expanded
-       gimp_item_set_linked
        gimp_item_set_lock_content
        gimp_item_set_lock_position
        gimp_item_set_lock_visibility
diff --git a/libgimp/gimpitem_pdb.c b/libgimp/gimpitem_pdb.c
index f7bfcec1b9..338ea161a7 100644
--- a/libgimp/gimpitem_pdb.c
+++ b/libgimp/gimpitem_pdb.c
@@ -742,80 +742,6 @@ gimp_item_set_visible (GimpItem *item,
   return success;
 }
 
-/**
- * gimp_item_get_linked:
- * @item: The item.
- *
- * Get the linked state of the specified item.
- *
- * This procedure returns the specified item's linked state.
- *
- * Returns: The item linked state (for moves).
- *
- * Since: 2.8
- **/
-gboolean
-gimp_item_get_linked (GimpItem *item)
-{
-  GimpValueArray *args;
-  GimpValueArray *return_vals;
-  gboolean linked = FALSE;
-
-  args = gimp_value_array_new_from_types (NULL,
-                                          GIMP_TYPE_ITEM, item,
-                                          G_TYPE_NONE);
-
-  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
-                                              "gimp-item-get-linked",
-                                              args);
-  gimp_value_array_unref (args);
-
-  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
-    linked = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
-
-  gimp_value_array_unref (return_vals);
-
-  return linked;
-}
-
-/**
- * gimp_item_set_linked:
- * @item: The item.
- * @linked: The new item linked state.
- *
- * Set the linked state of the specified item.
- *
- * This procedure sets the specified item's linked state.
- *
- * Returns: TRUE on success.
- *
- * Since: 2.8
- **/
-gboolean
-gimp_item_set_linked (GimpItem *item,
-                      gboolean  linked)
-{
-  GimpValueArray *args;
-  GimpValueArray *return_vals;
-  gboolean success = TRUE;
-
-  args = gimp_value_array_new_from_types (NULL,
-                                          GIMP_TYPE_ITEM, item,
-                                          G_TYPE_BOOLEAN, linked,
-                                          G_TYPE_NONE);
-
-  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
-                                              "gimp-item-set-linked",
-                                              args);
-  gimp_value_array_unref (args);
-
-  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
-
-  gimp_value_array_unref (return_vals);
-
-  return success;
-}
-
 /**
  * gimp_item_get_lock_content:
  * @item: The item.
diff --git a/libgimp/gimpitem_pdb.h b/libgimp/gimpitem_pdb.h
index d0daa3b286..839fdb61d0 100644
--- a/libgimp/gimpitem_pdb.h
+++ b/libgimp/gimpitem_pdb.h
@@ -55,9 +55,6 @@ gboolean      gimp_item_set_name            (GimpItem           *item,
 gboolean      gimp_item_get_visible         (GimpItem           *item);
 gboolean      gimp_item_set_visible         (GimpItem           *item,
                                              gboolean            visible);
-gboolean      gimp_item_get_linked          (GimpItem           *item);
-gboolean      gimp_item_set_linked          (GimpItem           *item,
-                                             gboolean            linked);
 gboolean      gimp_item_get_lock_content    (GimpItem           *item);
 gboolean      gimp_item_set_lock_content    (GimpItem           *item,
                                              gboolean            lock_content);
diff --git a/pdb/groups/item.pdb b/pdb/groups/item.pdb
index 8a06b76ae2..e1385661d3 100644
--- a/pdb/groups/item.pdb
+++ b/pdb/groups/item.pdb
@@ -599,55 +599,6 @@ CODE
     );
 }
 
-sub item_get_linked {
-    $blurb = "Get the linked state of the specified item.";
-
-    $help = "This procedure returns the specified item's linked state.";
-
-    &wolfgang_pdb_misc('1998', '2.8');
-
-    @inargs = (
-       { name => 'item', type => 'item',
-         desc => 'The item' }
-    );
-
-    @outargs = (
-       { name => 'linked', type => 'boolean',
-         desc => "The item linked state (for moves)" }
-    );
-
-    %invoke = (
-       code => <<'CODE'
-{
-  linked = gimp_item_get_linked (GIMP_ITEM (item));
-}
-CODE
-    );
-}
-
-sub item_set_linked {
-    $blurb = "Set the linked state of the specified item.";
-
-    $help = "This procedure sets the specified item's linked state.";
-
-    &wolfgang_pdb_misc('1998', '2.8');
-
-    @inargs = (
-       { name => 'item', type => 'item',
-         desc => 'The item' },
-       { name => 'linked', type => 'boolean',
-         desc => "The new item linked state" }
-    );
-
-    %invoke = (
-       code => <<'CODE'
-{
-  gimp_item_set_linked (GIMP_ITEM (item), linked, TRUE);
-}
-CODE
-    );
-}
-
 sub item_get_lock_content {
     $blurb = "Get the 'lock content' state of the specified item.";
 
@@ -1049,7 +1000,6 @@ CODE
             item_get_expanded item_set_expanded
             item_get_name item_set_name
             item_get_visible item_set_visible
-            item_get_linked item_set_linked
             item_get_lock_content item_set_lock_content
             item_get_lock_position item_set_lock_position
             item_get_lock_visibility item_set_lock_visibility


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