simpleselection: Improve items-changed

Make items-changed never emit 2 signals, instead, always emit only one,
potentially by extending the range reported in items-changed.

And be a lot more exhaustive about autoselect tests.
This commit is contained in:
Benjamin Otte 2019-02-11 06:01:19 +01:00
parent 1f56f5c2e9
commit 07722582ef
2 changed files with 93 additions and 17 deletions

View File

@ -199,8 +199,6 @@ gtk_single_selection_items_changed_cb (GListModel *model,
guint added,
GtkSingleSelection *self)
{
gboolean emit_selection_changed = FALSE;
g_object_freeze_notify (G_OBJECT (self));
if (self->selected_item == NULL)
@ -260,12 +258,27 @@ gtk_single_selection_items_changed_cb (GListModel *model,
self->selected = position - 1;
self->selected_item = g_list_model_get_item (self->model, self->selected);
g_assert (self->selected_item);
/* We pretend the newly selected item was part of the original model change.
* This way we get around inconsistent state (no item selected) during
* the items-changed emission. */
position--;
removed++;
added++;
}
else
self->selected = GTK_INVALID_LIST_POSITION;
}
emit_selection_changed = TRUE;
else
{
if (self->selected == position + added)
{
/* We pretend the newly selected item was part of the original model change.
* This way we get around inconsistent state (no item selected) during
* the items-changed emission. */
removed++;
added++;
}
}
}
else
{
@ -279,9 +292,6 @@ gtk_single_selection_items_changed_cb (GListModel *model,
g_list_model_items_changed (G_LIST_MODEL (self), position, removed, added);
if (emit_selection_changed && self->selected != GTK_INVALID_LIST_POSITION)
gtk_selection_model_selection_changed (GTK_SELECTION_MODEL (self), self->selected, 1);
g_object_thaw_notify (G_OBJECT (self));
}

View File

@ -390,31 +390,96 @@ test_autoselect (void)
GtkSelectionModel *selection;
GListStore *store;
store = new_store (2, 1, 1);
store = new_empty_store ();
selection = new_model (store, TRUE, FALSE);
assert_model (selection, "");
assert_changes (selection, "");
assert_selection (selection, "");
assert_selection_changes (selection, "");
add (store, 1);
assert_model (selection, "1");
assert_changes (selection, "+0");
assert_selection (selection, "1");
assert_selection_changes (selection, "");
splice (store, 0, 1, (guint[]) { 97 }, 1);
assert_selection (selection, "97");
assert_selection_changes (selection, "0:1");
splice (store, 0, 1, (guint[]) { 7, 8, 9 }, 3);
assert_model (selection, "7 8 9");
assert_changes (selection, "0-1+3");
assert_selection (selection, "7");
assert_selection_changes (selection, "");
splice (store, 0, 0, (guint[]) { 5, 6 }, 2);
assert_model (selection, "5 6 7 8 9");
assert_changes (selection, "0+2");
assert_selection (selection, "7");
assert_selection_changes (selection, "");
g_list_store_remove (store, 2);
assert_model (selection, "5 6 8 9");
assert_changes (selection, "2-2+1");
assert_selection (selection, "8");
assert_selection_changes (selection, "");
splice (store, 2, 2, NULL, 0);
assert_model (selection, "5 6");
assert_changes (selection, "1-3+1");
assert_selection (selection, "6");
assert_selection_changes (selection, "");
splice (store, 0, 2, (guint[]) { 1, 2 }, 2);
assert_model (selection, "1 2");
assert_changes (selection, "0-2+2");
assert_selection (selection, "2");
assert_selection_changes (selection, "");
g_list_store_remove (store, 0);
assert_model (selection, "2");
assert_changes (selection, "-0");
assert_selection (selection, "2");
assert_selection_changes (selection, "");
g_list_store_remove (store, 0);
assert_model (selection, "");
assert_changes (selection, "-0");
assert_selection (selection, "");
assert_selection_changes (selection, "");
g_object_unref (store);
g_object_unref (selection);
}
static void
test_autoselect_toggle (void)
{
GtkSelectionModel *selection;
GListStore *store;
store = new_store (1, 1, 1);
selection = new_model (store, TRUE, TRUE);
assert_model (selection, "1");
assert_changes (selection, "");
assert_selection (selection, "1");
assert_selection_changes (selection, "");
gtk_single_selection_set_autoselect (GTK_SINGLE_SELECTION (selection), FALSE);
gtk_single_selection_set_can_unselect (GTK_SINGLE_SELECTION (selection), TRUE);
assert_model (selection, "1");
assert_changes (selection, "");
assert_selection (selection, "1");
assert_selection_changes (selection, "");
gtk_selection_model_unselect_item (selection, 0);
assert_model (selection, "1");
assert_changes (selection, "");
assert_selection (selection, "");
assert_selection_changes (selection, "0:1");
gtk_single_selection_set_autoselect (GTK_SINGLE_SELECTION (selection), TRUE);
assert_selection (selection, "97");
assert_model (selection, "1");
assert_changes (selection, "");
assert_selection (selection, "1");
assert_selection_changes (selection, "0:1");
ignore_changes (selection);
g_object_unref (store);
g_object_unref (selection);
}
@ -546,16 +611,17 @@ main (int argc, char *argv[])
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
selection_quark = g_quark_from_static_string ("Mana mana, badibidibi");
g_test_add_func ("/singleselection/create", test_create);
#if GLIB_CHECK_VERSION (2, 59, 0) /* g_list_store_get_item() has overflow issues before */
g_test_add_func ("/singleselection/create", test_create);
g_test_add_func ("/singleselection/autoselect", test_autoselect);
g_test_add_func ("/singleselection/autoselect-toggle", test_autoselect_toggle);
g_test_add_func ("/singleselection/selection", test_selection);
g_test_add_func ("/singleselection/can-unselect", test_can_unselect);
g_test_add_func ("/singleselection/persistence", test_persistence);
#endif
g_test_add_func ("/singleselection/query-range", test_query_range);
#if GLIB_CHECK_VERSION (2, 58, 0) /* g_list_store_splice() is broken before 2.58 */
g_test_add_func ("/singleselection/changes", test_changes);
#endif
#endif
return g_test_run ();