From 80fbc1b72d3719c1de9cb82d86c15f22a7433e7f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 5 Jun 2020 13:49:32 -0400 Subject: [PATCH] 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 00d02998d5..31572072a7 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 (); }