def test_and_filter(self): f1 = ListModel.Filter(True) f2 = ListModel.Filter(True) f3 = ListModel.Filter(False) f4 = ListModel.Filter(False) self.assertTrue(ListModel.AndFilter([f1, f2]).matches(None)) self.assertFalse(ListModel.AndFilter([f2, f3]).matches(None)) self.assertTrue(ListModel.OrFilter([f2, f3]).matches(None)) self.assertFalse(ListModel.OrFilter([f3, f4]).matches(None))
def test_filtered_list_changing_container_under_changes_retains_order( self): # the bug was that if list model is under a change and items are only # being rearranged (easy to occur with dependent list being sorted differently) # then there is no way to detect that it is not sorted anymore so it proceeds # as if it is already sorted properly. l = ListModel.ListModel("items") l.append_item("3") l.append_item("1") l.append_item("4") l.append_item("2") l2 = ListModel.ListModel("items") l2.append_item("4") l2.append_item("1") l2.append_item("2") l2.append_item("3") l3 = ListModel.FilteredListModel(container=l, items_key="items") self.assertEqual(["3", "1", "4", "2"], l3.items) l4 = ListModel.FilteredListModel(container=l3, items_key="items") self.assertEqual(["3", "1", "4", "2"], l4.items) l4.begin_change() l3.begin_change() l3.filter = ListModel.Filter(True) l3.end_change() l4.end_change() l4.begin_change() l3.begin_change() l3.container = l2 l3.end_change() l4.end_change() self.assertEqual(["4", "1", "2", "3"], l3.items) self.assertEqual(["4", "1", "2", "3"], l4.items)
def __init__(self, base_title: str, data_group: typing.Optional[DataGroup.DataGroup], filter_id: typing.Optional[str], document_controller: DocumentController.DocumentController): self.__base_title = base_title self.__data_group = data_group self.__filter_id = filter_id self.__filter_predicate = document_controller.get_filter_predicate( filter_id) if self.__filter_id else ListModel.Filter(True) self.on_title_changed: typing.Optional[typing.Callable[[str], None]] = None self.__count = 0 # useful for drag and drop self.document_controller = document_controller self.document_model = document_controller.document_model container = self.__data_group or document_controller.document_model def count_changed(count: Observer.ItemValue) -> None: self.__count = count if callable(self.on_title_changed): self.on_title_changed(self.title) oo = Observer.ObserverBuilder() oo.source(container).sequence_from_array( "display_items", predicate=self.__filter_predicate.matches).len().action_fn( count_changed) self.__count_observer = typing.cast(Observer.AbstractItemSource, oo.make_observable())