Merge branch 'selection-filter-fixes' into 'master'

Selection filter fixes

See merge request GNOME/gtk!2186
This commit is contained in:
Matthias Clasen 2020-07-03 16:10:03 +00:00
commit be20a04e04
2 changed files with 164 additions and 33 deletions

View File

@ -100,22 +100,26 @@ G_DEFINE_TYPE_WITH_CODE (GtkSelectionFilterModel, gtk_selection_filter_model, G_
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_selection_filter_model_list_model_init))
static void
gtk_selection_filter_model_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkSelectionFilterModel *self)
selection_filter_model_items_changed (GtkSelectionFilterModel *self,
guint position,
guint removed,
guint added)
{
GtkBitset *selection;
guint sel_position;
guint sel_removed;
guint sel_added;
guint sel_position = 0;
guint sel_removed = 0;
guint sel_added = 0;
selection = gtk_selection_model_get_selection (self->model);
sel_position = gtk_bitset_get_size_in_range (self->selection, 0, position - 1);
sel_removed = gtk_bitset_get_size_in_range (self->selection, position, position + removed);
sel_added = gtk_bitset_get_size_in_range (selection, position, position + added);
if (position > 0)
sel_position = gtk_bitset_get_size_in_range (self->selection, 0, position - 1);
if (removed > 0)
sel_removed = gtk_bitset_get_size_in_range (self->selection, position, position + removed - 1);
if (added > 0)
sel_added = gtk_bitset_get_size_in_range (selection, position, position + added - 1);
gtk_bitset_unref (self->selection);
self->selection = gtk_bitset_copy (selection);
@ -127,29 +131,22 @@ gtk_selection_filter_model_items_changed_cb (GListModel *model,
}
static void
gtk_selection_filter_model_selection_changed_cb (GListModel *model,
guint position,
guint n_items,
gtk_selection_filter_model_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkSelectionFilterModel *self)
{
selection_filter_model_items_changed (self, position, removed, added);
}
static void
gtk_selection_filter_model_selection_changed_cb (GListModel *model,
guint position,
guint n_items,
GtkSelectionFilterModel *self)
{
GtkBitset *selection;
guint sel_position;
guint sel_removed;
guint sel_added;
selection = gtk_selection_model_get_selection (self->model);
sel_position = gtk_bitset_get_size_in_range (self->selection, 0, position - 1);
sel_removed = gtk_bitset_get_size_in_range (self->selection, position, position + n_items);
sel_added = gtk_bitset_get_size_in_range (selection, position, position + n_items);
gtk_bitset_unref (self->selection);
self->selection = gtk_bitset_copy (selection);
gtk_bitset_unref (selection);
if (sel_removed > 0 || sel_added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), sel_position, sel_removed, sel_added);
selection_filter_model_items_changed (self, position, n_items, n_items);
}
static void

View File

@ -263,6 +263,21 @@ new_model (GListStore *store)
return result;
}
static GtkSelectionFilterModel *
new_filter_model (GtkSelectionModel *model)
{
GtkSelectionFilterModel *result;
GString *changes;
result = gtk_selection_filter_model_new (model);
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
return result;
}
static void
test_create (void)
{
@ -291,7 +306,8 @@ test_changes (void)
{
GtkSelectionModel *selection;
GListStore *store;
gboolean ret;
store = new_store (1, 5, 1);
selection = new_model (store);
assert_model (selection, "1 2 3 4 5");
@ -317,6 +333,17 @@ test_changes (void)
assert_selection (selection, "");
assert_selection_changes (selection, "");
ret = gtk_selection_model_select_range (selection, 1, 2, FALSE);
g_assert_true (ret);
assert_selection (selection, "2 3");
assert_selection_changes (selection, "1:2");
insert (store, 2, 22);
assert_model (selection, "1 2 22 3 97");
assert_changes (selection, "+2");
assert_selection (selection, "2 3");
assert_selection_changes (selection, "");
g_object_unref (store);
g_object_unref (selection);
}
@ -480,6 +507,112 @@ test_set_selection (void)
g_object_unref (selection);
}
static void
test_selection_filter (void)
{
GtkSelectionModel *selection;
GtkSelectionFilterModel *filter;
GListStore *store;
gboolean ret;
store = new_store (1, 5, 1);
selection = new_model (store);
assert_selection (selection, "");
assert_selection_changes (selection, "");
filter = new_filter_model (selection);
assert_model (filter, "");
assert_changes (filter, "");
ret = gtk_selection_model_select_item (selection, 3, FALSE);
g_assert_true (ret);
assert_selection (selection, "4");
assert_selection_changes (selection, "3:1");
assert_model (filter, "4");
assert_changes (filter, "+0");
ret = gtk_selection_model_unselect_item (selection, 3);
g_assert_true (ret);
assert_selection (selection, "");
assert_selection_changes (selection, "3:1");
assert_model (filter, "");
assert_changes (filter, "-0");
ret = gtk_selection_model_select_item (selection, 1, FALSE);
g_assert_true (ret);
assert_selection (selection, "2");
assert_selection_changes (selection, "1:1");
assert_model (filter, "2");
assert_changes (filter, "+0");
ret = gtk_selection_model_select_item (selection, 0, FALSE);
g_assert_true (ret);
assert_selection (selection, "1 2");
assert_selection_changes (selection, "0:1");
assert_model (filter, "1 2");
assert_changes (filter, "+0");
ret = gtk_selection_model_unselect_item (selection, 0);
g_assert_true (ret);
assert_selection (selection, "2");
assert_selection_changes (selection, "0:1");
assert_model (filter, "2");
assert_changes (filter, "-0");
ret = gtk_selection_model_select_range (selection, 3, 2, FALSE);
g_assert_true (ret);
assert_selection (selection, "2 4 5");
assert_selection_changes (selection, "3:2");
assert_model (filter, "2 4 5");
assert_changes (filter, "1+2");
ret = gtk_selection_model_unselect_range (selection, 3, 2);
g_assert_true (ret);
assert_selection (selection, "2");
assert_selection_changes (selection, "3:2");
assert_model (filter, "2");
assert_changes (filter, "1-2");
ret = gtk_selection_model_select_all (selection);
g_assert_true (ret);
assert_selection (selection, "1 2 3 4 5");
assert_selection_changes (selection, "0:5");
assert_model (filter, "1 2 3 4 5");
assert_changes (filter, "0-1+5");
ret = gtk_selection_model_unselect_all (selection);
g_assert_true (ret);
assert_selection (selection, "");
assert_selection_changes (selection, "0:5");
assert_model (filter, "");
assert_changes (filter, "0-5");
ret = gtk_selection_model_select_range (selection, 1, 3, FALSE);
g_assert_true (ret);
assert_selection (selection, "2 3 4");
assert_selection_changes (selection, "1:3");
assert_model (filter, "2 3 4");
assert_changes (filter, "0+3");
insert (store, 2, 22);
assert_model (selection, "1 2 22 3 4 5");
assert_changes (selection, "+2");
assert_selection (selection, "2 3 4");
assert_selection_changes (selection, "");
assert_model (filter, "2 3 4");
assert_changes (filter, "");
g_list_store_remove (store, 2);
assert_model (selection, "1 2 3 4 5");
assert_changes (selection, "-2");
assert_selection (selection, "2 3 4");
assert_selection_changes (selection, "");
assert_model (filter, "2 3 4");
assert_changes (filter, "");
g_object_unref (store);
g_object_unref (selection);
}
int
main (int argc, char *argv[])
{
@ -499,6 +632,7 @@ main (int argc, char *argv[])
g_test_add_func ("/multiselection/select-range", test_select_range);
g_test_add_func ("/multiselection/readd", test_readd);
g_test_add_func ("/multiselection/set_selection", test_set_selection);
g_test_add_func ("/multiselection/selection-filter", test_selection_filter);
return g_test_run ();
}