[gtk/matthiasc/for-master: 12/12] multiselection: Fix the select_range implementation



commit 99a1d10bf139729eb284e296a73a7a0dea5128d0
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jun 5 13:49:32 2020 -0400

    multiselection: Fix the select_range implementation
    
    When exclusive is TRUE, we would not always emit a
    ::selection-changed signal that covers all the items
    that were unselected.
    
    This commit includes a test.

 gtk/gtkmultiselection.c        | 15 +++++++++++++--
 testsuite/gtk/multiselection.c | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkmultiselection.c b/gtk/gtkmultiselection.c
index f8ed44c2d4..6115d8adfd 100644
--- a/gtk/gtkmultiselection.c
+++ b/gtk/gtkmultiselection.c
@@ -109,11 +109,22 @@ gtk_multi_selection_select_range (GtkSelectionModel *model,
                                   gboolean           exclusive)
 {
   GtkMultiSelection *self = GTK_MULTI_SELECTION (model);
+  guint min = G_MAXUINT;
+  guint max = 0;
 
   if (exclusive)
-    gtk_set_remove_all (self->selected);
+    {
+      min = gtk_set_get_min (self->selected);
+      max = gtk_set_get_max (self->selected);
+      gtk_set_remove_all (self->selected);
+    }
+
   gtk_set_add_range (self->selected, position, n_items);
-  gtk_selection_model_selection_changed (model, position, n_items);
+
+  min = MIN (position, min);
+  max = MAX (max, position + n_items - 1);
+
+  gtk_selection_model_selection_changed (model, min, max - min + 1);
 
   return TRUE;
 }
diff --git a/testsuite/gtk/multiselection.c b/testsuite/gtk/multiselection.c
index b00c68c7c8..4e8622e0eb 100644
--- a/testsuite/gtk/multiselection.c
+++ b/testsuite/gtk/multiselection.c
@@ -372,6 +372,38 @@ test_selection (void)
   g_object_unref (selection);
 }
 
+static void
+test_select_range (void)
+{
+  GtkSelectionModel *selection;
+  GListStore *store;
+  gboolean ret;
+
+  store = new_store (1, 5, 1);
+  selection = new_model (store);
+  assert_selection (selection, "");
+  assert_selection_changes (selection, "");
+
+  ret = gtk_selection_model_select_range (selection, 2, 2, FALSE);
+  g_assert_true (ret);
+  assert_selection (selection, "3 4");
+  assert_selection_changes (selection, "2:2");
+
+  ret = gtk_selection_model_select_range (selection, 3, 2, FALSE);
+  g_assert_true (ret);
+  assert_selection (selection, "3 4 5");
+  assert_selection_changes (selection, "3:2");
+
+  ret = gtk_selection_model_select_range (selection, 0, 1, TRUE);
+  g_assert_true (ret);
+  assert_selection (selection, "1");
+  assert_selection_changes (selection, "0:5");
+
+  g_object_unref (store);
+  g_object_unref (selection);
+}
+
+
 int
 main (int argc, char *argv[])
 {
@@ -388,6 +420,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/multiselection/changes", test_changes);
 #endif
   g_test_add_func ("/multiselection/selection", test_selection);
+  g_test_add_func ("/multiselection/select-range", test_select_range);
 
   return g_test_run ();
 }


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