When parsing the added items from the child model, the filter model was retrieving the wrong iterator, causing the filter model to send 'items-changed' with the wrong values.
This is because it was looking for "position + 1" when parsing the added items. Assuming that there is no filter function set, and the following sequence:
⥛ Item0 ⇋ Item1 ⇋ Item2 ⇋ Item3 ⥓
Where each arrow represents an iterator. Now, suppose that filter model receives from the child model:
items-changed(position=2, removed=1, added=1).
Using the above example, that means "first, remove the item at position=2; then, add Item4 at position=2". Theoretically, the filter model should be like this this after those operations:
⥛ Item0 ⇋ Item1 ⇋ Item4 ⇋ Item3 ⥓
And should emit the following signals:
- items-changed(position=2, n_removed=1, n_added=0)
- items-changed(position=2, n_removed=0, n_added=1)
That is, effectively, replacing Item2 by Item4. However, filter model currently does as following:
- At position=2, remove N=removed items. This will remove Item2:
⥛ Item0 ⇋ Item1 ⇋ Item3 ⥓
-
Emit items-changed(position=2, n_removed=1, n_added=0)
-
At position=3, add N=added items. At position=3, there is only the end iterator. Item4 is then added to before Item3, as expected.
⥛ Item0 ⇋ Item1 ⇋ Item4 ⇋ Item3 ⥓
- Emit items-changed(position=3, n_removed=0, n_added=1)
In this scenario, the order of the elements is correct, but the
value of position
is wrong. That happens because at (3), filter
model used position + 1, and the end iterator's position reports
that value. In the example, it reports 3, and the filter model
sends that value in 'items-changed'.
This is a very visible issue when binding the filter model to a GtkListBox.
Fix that by not adding 1 to the position at (3). Additionally, add tests to make sure this behavior is maintained.