[gtk/prop-list: 73/96] multiselection: Add a copy constructor



commit 466aec41f57a6885127ff8354f19b92b694d3035
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Dec 22 11:15:27 2019 -0500

    multiselection: Add a copy constructor
    
    Add a function to create a multiselection that
    is a copy of an existing selection model. We
    can do this efficiently if the original is a
    multiselection as well, by just copying the
    entire set in on go.

 gtk/gtkmultiselection.c | 38 ++++++++++++++++++++++++++++++++++++++
 gtk/gtkmultiselection.h |  4 ++++
 gtk/gtkset.c            | 11 +++++++++++
 gtk/gtkset.h            |  1 +
 4 files changed, 54 insertions(+)
---
diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c
index 522c524788..1cfa9ffaf3 100644
--- a/gtk/gtkmultiselection.c
+++ b/gtk/gtkmultiselection.c
@@ -331,3 +331,41 @@ gtk_multi_selection_new (GListModel *model)
                        NULL);
 }
 
+GtkMultiSelection *
+gtk_multi_selection_copy (GtkSelectionModel *selection)
+{
+  GtkMultiSelection *copy;
+  GListModel *model;
+
+  g_object_get (selection, "model", &model, NULL);
+
+  copy = GTK_MULTI_SELECTION (gtk_multi_selection_new (model));
+
+  if (GTK_IS_MULTI_SELECTION (selection))
+    {
+      GtkMultiSelection *multi = GTK_MULTI_SELECTION (selection);
+
+      gtk_set_free (copy->selected);
+      copy->selected = gtk_set_copy (multi->selected);
+      copy->last_selected = multi->last_selected;
+    }
+  else
+    {
+      guint pos, n;
+      guint start, n_items;
+      gboolean selected;
+
+      n = g_list_model_get_n_items (model);
+      n_items = 0;
+      for (pos = 0; pos < n; pos += n_items)
+        {
+          gtk_selection_model_query_range (selection, pos, &start, &n_items, &selected);
+          if (selected)
+            gtk_selection_model_select_range (GTK_SELECTION_MODEL (copy), start, n_items, FALSE);
+        }
+    }
+
+  g_object_unref (model);
+
+  return copy;
+}
diff --git a/gtk/gtkmultiselection.h b/gtk/gtkmultiselection.h
index cca0dc62d2..1de2b2aa14 100644
--- a/gtk/gtkmultiselection.h
+++ b/gtk/gtkmultiselection.h
@@ -21,6 +21,7 @@
 #define __GTK_MULTI_SELECTION_H__
 
 #include <gtk/gtktypes.h>
+#include <gtk/gtkselectionmodel.h>
 
 G_BEGIN_DECLS
 
@@ -32,6 +33,9 @@ G_DECLARE_FINAL_TYPE (GtkMultiSelection, gtk_multi_selection, GTK, MULTI_SELECTI
 GDK_AVAILABLE_IN_ALL
 GListModel *    gtk_multi_selection_new                (GListModel           *model);
 
+GDK_AVAILABLE_IN_ALL
+GtkMultiSelection * gtk_multi_selection_copy           (GtkSelectionModel    *model);
+
 G_END_DECLS
 
 #endif /* __GTK_MULTI_SELECTION_H__ */
diff --git a/gtk/gtkset.c b/gtk/gtkset.c
index 807743a7dc..f2e61aa8ed 100644
--- a/gtk/gtkset.c
+++ b/gtk/gtkset.c
@@ -52,6 +52,17 @@ gtk_set_new (void)
   return set;
 }
 
+GtkSet *
+gtk_set_copy (GtkSet *set)
+{
+  GtkSet *copy;
+
+  copy = g_new (GtkSet, 1);
+  copy->ranges = g_array_copy (set->ranges);
+
+  return copy;
+}
+
 void
 gtk_set_free (GtkSet *set)
 {
diff --git a/gtk/gtkset.h b/gtk/gtkset.h
index 25351e2090..d0ba4e1a96 100644
--- a/gtk/gtkset.h
+++ b/gtk/gtkset.h
@@ -35,6 +35,7 @@ struct _GtkSetIter
 
 GtkSet   *gtk_set_new          (void);
 void      gtk_set_free         (GtkSet   *set);
+GtkSet   *gtk_set_copy         (GtkSet   *set);
 
 gboolean  gtk_set_contains     (GtkSet   *set,
                                 guint     item);


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