[gimp/wip/Jehan/layers-dockable-refresh: 29/58] app: add a select_items() implementation on various classes…




commit d2a55f5d9140ad1ddef6e1619ad8af2a7a5d00ad
Author: Jehan <jehan girinstud io>
Date:   Fri Jun 11 19:33:03 2021 +0200

    app: add a select_items() implementation on various classes…
    
    … implementing GimpContainerViewInterface.

 app/widgets/gimpcontainereditor.c   | 45 +++++++++++++++--------
 app/widgets/gimpcontainerentry.c    | 55 ++++++++++++++++++++++++++++
 app/widgets/gimpcontainericonview.c | 73 +++++++++++++++++++++++++++++++++++++
 app/widgets/gimpdrawabletreeview.c  | 49 ++++++++++++++++++++++---
 4 files changed, 201 insertions(+), 21 deletions(-)
---
diff --git a/app/widgets/gimpcontainereditor.c b/app/widgets/gimpcontainereditor.c
index cbfe1d037b..91f2836aa1 100644
--- a/app/widgets/gimpcontainereditor.c
+++ b/app/widgets/gimpcontainereditor.c
@@ -85,9 +85,9 @@ static void   gimp_container_editor_get_property     (GObject             *objec
                                                       GValue              *value,
                                                       GParamSpec          *pspec);
 
-static gboolean gimp_container_editor_select_item    (GtkWidget           *widget,
-                                                      GimpViewable        *viewable,
-                                                      gpointer             insert_data,
+static gboolean gimp_container_editor_select_items   (GimpContainerView   *view,
+                                                      GList               *items,
+                                                      GList               *paths,
                                                       GimpContainerEditor *editor);
 static void   gimp_container_editor_activate_item    (GtkWidget           *widget,
                                                       GimpViewable        *viewable,
@@ -277,12 +277,12 @@ gimp_container_editor_constructed (GObject *object)
                           editor->view,           "visible",
                           G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
 
-  /*  Connect "select-item" with G_CONNECT_AFTER because it's a
+  /*  Connect "select-items" with G_CONNECT_AFTER because it's a
    *  RUN_LAST signal and the default handler selecting the row must
    *  run before signal connections. See bug #784176.
    */
-  g_signal_connect_object (editor->view, "select-item",
-                           G_CALLBACK (gimp_container_editor_select_item),
+  g_signal_connect_object (editor->view, "select-items",
+                           G_CALLBACK (gimp_container_editor_select_items),
                            editor, G_CONNECT_AFTER);
 
   g_signal_connect_object (editor->view, "activate-item",
@@ -293,12 +293,16 @@ gimp_container_editor_constructed (GObject *object)
                            editor, 0);
 
   {
-    GimpObject *object = gimp_context_get_by_type (editor->priv->context,
-                                                   gimp_container_get_children_type 
(editor->priv->container));
+    GList      *objects = NULL;
+    GimpObject *object  = gimp_context_get_by_type (editor->priv->context,
+                                                    gimp_container_get_children_type 
(editor->priv->container));
+
+    if (object)
+      objects = g_list_prepend (objects, object);
 
-    gimp_container_editor_select_item (GTK_WIDGET (editor->view),
-                                       (GimpViewable *) object, NULL,
-                                       editor);
+    gimp_container_editor_select_items (editor->view, objects, NULL, editor);
+
+    g_list_free (objects);
   }
 }
 
@@ -432,12 +436,21 @@ gimp_container_editor_set_selection_mode (GimpContainerEditor *editor,
 /*  private functions  */
 
 static gboolean
-gimp_container_editor_select_item (GtkWidget           *widget,
-                                   GimpViewable        *viewable,
-                                   gpointer             insert_data,
-                                   GimpContainerEditor *editor)
+gimp_container_editor_select_items (GimpContainerView   *view,
+                                    GList               *items,
+                                    GList               *paths,
+                                    GimpContainerEditor *editor)
 {
-  GimpContainerEditorClass *klass = GIMP_CONTAINER_EDITOR_GET_CLASS (editor);
+  GimpContainerEditorClass *klass    = GIMP_CONTAINER_EDITOR_GET_CLASS (editor);
+  GimpViewable             *viewable = NULL;
+
+  /* XXX Right now a GimpContainerEditor only supports 1 item selected
+   * at once. Let's see later if we want to allow more.
+   */
+  /*g_return_val_if_fail (g_list_length (items) < 2, FALSE);*/
+
+  if (items)
+    viewable = items->data;
 
   if (klass->select_item)
     klass->select_item (editor, viewable);
diff --git a/app/widgets/gimpcontainerentry.c b/app/widgets/gimpcontainerentry.c
index a90f2a0495..fdc96ef11c 100644
--- a/app/widgets/gimpcontainerentry.c
+++ b/app/widgets/gimpcontainerentry.c
@@ -63,6 +63,9 @@ static void     gimp_container_entry_rename_item  (GimpContainerView      *view,
 static gboolean  gimp_container_entry_select_item (GimpContainerView      *view,
                                                    GimpViewable           *viewable,
                                                    gpointer                insert_data);
+static gboolean  gimp_container_entry_select_items(GimpContainerView      *view,
+                                                   GList                  *items,
+                                                   GList                  *paths);
 static void     gimp_container_entry_clear_items  (GimpContainerView      *view);
 static void    gimp_container_entry_set_view_size (GimpContainerView      *view);
 
@@ -110,6 +113,7 @@ gimp_container_entry_view_iface_init (GimpContainerViewInterface *iface)
   iface->reorder_item  = gimp_container_entry_reorder_item;
   iface->rename_item   = gimp_container_entry_rename_item;
   iface->select_item   = gimp_container_entry_select_item;
+  iface->select_items  = gimp_container_entry_select_items;
   iface->clear_items   = gimp_container_entry_clear_items;
   iface->set_view_size = gimp_container_entry_set_view_size;
 
@@ -357,6 +361,57 @@ gimp_container_entry_select_item (GimpContainerView *view,
   return TRUE;
 }
 
+static gboolean
+gimp_container_entry_select_items (GimpContainerView   *view,
+                                   GList               *viewables,
+                                   GList               *paths)
+{
+  GimpContainerEntry *container_entry = GIMP_CONTAINER_ENTRY (view);
+  GtkEntry           *entry           = GTK_ENTRY (view);
+  GimpViewable       *viewable        = NULL;
+
+  /* XXX Only support 1 selected viewable for now. */
+  if (viewables)
+    viewable = viewables->data;
+
+  g_signal_handlers_block_by_func (entry,
+                                   gimp_container_entry_changed,
+                                   view);
+
+  if (container_entry->viewable)
+    {
+      g_object_remove_weak_pointer (G_OBJECT (container_entry->viewable),
+                                    (gpointer) &container_entry->viewable);
+      container_entry->viewable = NULL;
+    }
+
+  if (viewable)
+    {
+      container_entry->viewable = viewable;
+      g_object_add_weak_pointer (G_OBJECT (container_entry->viewable),
+                                 (gpointer) &container_entry->viewable);
+
+      gtk_entry_set_icon_from_icon_name (entry,
+                                         GTK_ENTRY_ICON_SECONDARY,
+                                         NULL);
+    }
+  else
+    {
+      /* The selected item does not exist. */
+      gtk_entry_set_icon_from_icon_name (entry,
+                                         GTK_ENTRY_ICON_SECONDARY,
+                                         GIMP_ICON_WILBER_EEK);
+    }
+
+  gtk_entry_set_text (entry, viewable? gimp_object_get_name (viewable) : "");
+
+  g_signal_handlers_unblock_by_func (entry,
+                                     gimp_container_entry_changed,
+                                     view);
+
+  return TRUE;
+}
+
 static void
 gimp_container_entry_clear_items (GimpContainerView *view)
 {
diff --git a/app/widgets/gimpcontainericonview.c b/app/widgets/gimpcontainericonview.c
index ecc89176a6..f8f86b8f79 100644
--- a/app/widgets/gimpcontainericonview.c
+++ b/app/widgets/gimpcontainericonview.c
@@ -80,6 +80,9 @@ static void          gimp_container_icon_view_rename_item       (GimpContainerVi
 static gboolean      gimp_container_icon_view_select_item       (GimpContainerView           *view,
                                                                  GimpViewable                *viewable,
                                                                  gpointer                     insert_data);
+static gboolean      gimp_container_icon_view_select_items      (GimpContainerView           *view,
+                                                                 GList                       *items,
+                                                                 GList                       *paths);
 static void          gimp_container_icon_view_clear_items       (GimpContainerView           *view);
 static void          gimp_container_icon_view_set_view_size     (GimpContainerView           *view);
 
@@ -150,6 +153,7 @@ gimp_container_icon_view_view_iface_init (GimpContainerViewInterface *iface)
   iface->reorder_item       = gimp_container_icon_view_reorder_item;
   iface->rename_item        = gimp_container_icon_view_rename_item;
   iface->select_item        = gimp_container_icon_view_select_item;
+  iface->select_items       = gimp_container_icon_view_select_items;
   iface->clear_items        = gimp_container_icon_view_clear_items;
   iface->set_view_size      = gimp_container_icon_view_set_view_size;
   iface->get_selected       = gimp_container_icon_view_get_selected;
@@ -563,6 +567,75 @@ gimp_container_icon_view_select_item (GimpContainerView *view,
   return TRUE;
 }
 
+static gboolean
+gimp_container_icon_view_select_items (GimpContainerView *view,
+                                       GList             *viewables,
+                                       GList             *paths)
+{
+  GimpContainerIconView *icon_view = GIMP_CONTAINER_ICON_VIEW (view);
+  GList                 *list;
+
+  if (viewables)
+    {
+      gboolean free_paths = FALSE;
+
+      if (g_list_length (paths) != g_list_length (viewables))
+        {
+          free_paths = TRUE;
+          paths = NULL;
+          for (list = viewables; list; list = list->next)
+            {
+              GtkTreeIter *iter;
+              GtkTreePath *path;
+
+              iter = gimp_container_view_lookup (GIMP_CONTAINER_VIEW (view),
+                                                 list->data);
+              if (! iter)
+                /* This may happen when the GimpContainerIconView only
+                 * shows a subpart of the whole icons. We don't select
+                 * what is not shown.
+                 */
+                continue;
+
+              path = gtk_tree_model_get_path (icon_view->model, iter);
+
+              paths = g_list_prepend (paths, path);
+            }
+          paths = g_list_reverse (paths);
+        }
+
+      g_signal_handlers_block_by_func (icon_view->view,
+                                       gimp_container_icon_view_selection_changed,
+                                       icon_view);
+
+      gtk_icon_view_unselect_all (icon_view->view);
+
+      for (list = paths; list; list = list->next)
+        {
+          gtk_icon_view_select_path (icon_view->view, list->data);
+        }
+
+      if (list)
+        {
+          gtk_icon_view_set_cursor (icon_view->view, list->data, NULL, FALSE);
+          gtk_icon_view_scroll_to_path (icon_view->view, list->data, FALSE, 0.0, 0.0);
+        }
+
+      g_signal_handlers_unblock_by_func (icon_view->view,
+                                         gimp_container_icon_view_selection_changed,
+                                         icon_view);
+
+      if (free_paths)
+        g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
+    }
+  else
+    {
+      gtk_icon_view_unselect_all (icon_view->view);
+    }
+
+  return TRUE;
+}
+
 static void
 gimp_container_icon_view_clear_items (GimpContainerView *view)
 {
diff --git a/app/widgets/gimpdrawabletreeview.c b/app/widgets/gimpdrawabletreeview.c
index 1c64cef4bd..b393b68291 100644
--- a/app/widgets/gimpdrawabletreeview.c
+++ b/app/widgets/gimpdrawabletreeview.c
@@ -45,11 +45,14 @@
 
 static void   gimp_drawable_tree_view_view_iface_init (GimpContainerViewInterface *iface);
 
-static void     gimp_drawable_tree_view_constructed (GObject           *object);
+static void     gimp_drawable_tree_view_constructed   (GObject           *object);
 
-static gboolean gimp_drawable_tree_view_select_item (GimpContainerView *view,
-                                                     GimpViewable      *item,
-                                                     gpointer           insert_data);
+static gboolean gimp_drawable_tree_view_select_item   (GimpContainerView *view,
+                                                       GimpViewable      *item,
+                                                       gpointer           insert_data);
+static gboolean gimp_drawable_tree_view_select_items  (GimpContainerView *view,
+                                                       GList             *items,
+                                                       GList             *paths);
 
 static gboolean gimp_drawable_tree_view_drop_possible(GimpContainerTreeView *view,
                                                       GimpDndType          src_type,
@@ -131,7 +134,8 @@ gimp_drawable_tree_view_view_iface_init (GimpContainerViewInterface *iface)
 {
   parent_view_iface = g_type_interface_peek_parent (iface);
 
-  iface->select_item = gimp_drawable_tree_view_select_item;
+  iface->select_item  = gimp_drawable_tree_view_select_item;
+  iface->select_items = gimp_drawable_tree_view_select_items;
 }
 
 static void
@@ -199,6 +203,41 @@ gimp_drawable_tree_view_select_item (GimpContainerView *view,
   return success;
 }
 
+static gboolean
+gimp_drawable_tree_view_select_items (GimpContainerView *view,
+                                      GList             *items,
+                                      GList             *paths)
+{
+  GimpItemTreeView *item_view = GIMP_ITEM_TREE_VIEW (view);
+  GimpImage        *image     = gimp_item_tree_view_get_image (item_view);
+  gboolean          success   = TRUE;
+
+  if (image)
+    {
+      GimpLayer *floating_sel = gimp_image_get_floating_selection (image);
+
+      success = (items        == NULL ||
+                 floating_sel == NULL ||
+                 (g_list_length (items) == 1 &&
+                  items->data           == GIMP_VIEWABLE (floating_sel)));
+
+      if (! success)
+        {
+          Gimp        *gimp    = image->gimp;
+          GimpContext *context = gimp_get_user_context (gimp);
+          GimpDisplay *display = gimp_context_get_display (context);
+
+          gimp_message_literal (gimp, G_OBJECT (display), GIMP_MESSAGE_WARNING,
+                                _("Cannot select items while a floating "
+                                  "selection is active."));
+        }
+    }
+
+  if (success)
+    success = parent_view_iface->select_items (view, items, paths);
+
+  return success;
+}
 
 /*  GimpContainerTreeView methods  */
 


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