예제 #1
0
 def test_random_filtered_model_updates(self):
     list_model = ListModel.ListModel("data_items")
     filtered_data_items = ListModel.FilteredListModel(items_key="data_items")
     filtered_data_items.container = list_model
     data_items = list()
     cc = 30
     for _ in range(cc):
         data_item = DataItem.DataItem(numpy.zeros((16, 16), numpy.uint32))
         list_model.insert_item(0, data_item)
         data_items.append(data_item)
     selection = Selection.IndexedSelection()
     filtered_data_items2 = ListModel.FilteredListModel(items_key="data_items", container=filtered_data_items, selection=selection)
     import random
     for xx in range(10):
         c1 = [n for n in range(cc)]
         c2 = [n for n in range(cc) if random.randint(0,100) > 20]
         random.shuffle(c1)
         random.shuffle(c2)
         def is_live_filter(data_item):
             return data_items.index(data_item) in c1
         def is_live_filter2(data_item):
             return data_items.index(data_item) in c2
         filtered_data_items.sort_key = lambda x: data_items.index(x)
         with filtered_data_items.changes():
             filtered_data_items.filter = ListModel.PredicateFilter(is_live_filter)
             filtered_data_items.filter = ListModel.PredicateFilter(is_live_filter2)
         self.assertEqual(set(c2), set([data_items.index(d) for d in filtered_data_items2.items]))
     for data_item in data_items:
         data_item.close()
예제 #2
0
 def slow_test_threaded_filtered_model_updates(self):
     for _ in range(1000):
         list_model = ListModel.ListModel("data_items")
         filtered_data_items = ListModel.FilteredListModel(items_key="data_items")
         data_items = list()
         cc = 30
         for _ in range(cc):
             data_item = DataItem.DataItem(numpy.zeros((16, 16), numpy.uint32))
             data_items.append(data_item)
         c1 = [n for n in range(cc) if random.randint(0,100) > 50]
         def is_live_filter(data_item):
             return data_items.index(data_item) in c1
         filtered_data_items.container = list_model
         filtered_data_items.sort_key = lambda x: data_items.index(x)
         selection = Selection.IndexedSelection()
         filtered_data_items2 = ListModel.FilteredListModel(items_key="data_items", container=filtered_data_items, selection=selection)
         filtered_data_items2.filter = ListModel.PredicateFilter(is_live_filter)
         finished = threading.Event()
         def update_randomly():
             for _ in range(cc):
                 data_item = random.choice(filtered_data_items._get_master_items())
                 data_item.data_item_changed_event.fire()
             finished.set()
         list_model.insert_item(0, data_items[0])
         threading.Thread(target = update_randomly).start()
         for index in range(1, cc):
             list_model.insert_item(index, data_items[index])
         finished.wait()
         filtered_data_items2.close()
         filtered_data_items.close()
예제 #3
0
    def project_filter(self) -> ListModel.Filter:
        def is_display_item_active(
                project_weak_ref,
                display_item: DisplayItem.DisplayItem) -> bool:
            return display_item.project == project_weak_ref()

        # use a weak reference to avoid circular references loops that prevent garbage collection
        return ListModel.PredicateFilter(
            functools.partial(is_display_item_active, weakref.ref(self)))
예제 #4
0
 def test_filtered_list_changing_from_sorted_to_unsorted_retains_order(self):
     l = ListModel.ListModel("items")
     l.append_item("3")
     l.append_item("1")
     l.append_item("4")
     l.append_item("2")
     l2 = ListModel.FilteredListModel(container=l, items_key="items")
     l2.sort_key = lambda x: x
     self.assertEqual(["1", "2", "3", "4"], l2.items)
     l2.filter = ListModel.PredicateFilter(lambda x: x != "4")
     l2.sort_key = None
     self.assertEqual(["3", "1", "2"], l2.items)
     l.remove_item(1)
     self.assertEqual(["3", "2"], l2.items)
예제 #5
0
 def test_filtered_list_updates_filtered_selection(self) -> None:
     l = ListModel.ListModel[typing.Any]("items")
     l.append_item("A1")
     l.append_item("B1")
     l.append_item("A2")
     l.append_item("B2")
     l.append_item("A3")
     l.append_item("B3")
     l2 = ListModel.FilteredListModel(container=l, items_key="items")
     s = l2.make_selection()
     s.set_multiple({0, 1, 2, 3})
     l2.filter = ListModel.PredicateFilter(
         lambda x: bool(x.startswith("A")))
     s.set_multiple({0, 1, 2})
     l.remove_item(1)  # B
     self.assertEqual({0, 1, 2}, s.indexes)
     l.remove_item(0)  # A
     self.assertEqual({0, 1}, s.indexes)
예제 #6
0
 def test_filtered_list_unsorted_retains_order(self):
     l = ListModel.ListModel("items")
     l.append_item("3")
     l.append_item("1")
     l.append_item("4")
     l.append_item("2")
     l2 = ListModel.FilteredListModel(container=l, items_key="items")
     l2.filter = ListModel.PredicateFilter(lambda x: x != "4")
     self.assertEqual(["3", "1", "2"], l2.items)
     l.remove_item(0)
     self.assertEqual(["1", "2"], l2.items)
     l.insert_item(0, "3")
     l.append_item("44")
     self.assertEqual(["3", "1", "2", "44"], l2.items)
     l2.begin_change()
     l.insert_item(0, "5")
     l.append_item("6")
     l2.end_change()
     self.assertEqual(["5", "3", "1", "2", "44", "6"], l2.items)
예제 #7
0
    def show_choose_project_dialog(self) -> None:
        with self.prevent_close():
            u = Declarative.DeclarativeUI()
            button_row = u.create_row(
                u.create_push_button(text=_("New..."),
                                     on_clicked="new_project"),
                u.create_push_button(text=_("Open..."),
                                     on_clicked="open_project"),
                u.create_stretch(),
                u.create_push_button(text=_("Cancel"),
                                     on_clicked="close_window"),
                u.create_push_button(text=_("Open Recent"),
                                     on_clicked="open_recent"),
                spacing=8)

            project_references_model = ListModel.FilteredListModel(
                container=self.__profile, items_key="project_references")
            project_references_model.filter = ListModel.PredicateFilter(
                lambda pr: pr.project_state != "loaded")
            project_references_model.sort_key = lambda pr: pr.last_used
            project_references_model.sort_reverse = True

            class ProjectReferenceItem:
                # provides a str converter and a tool tip.
                def __init__(self,
                             project_reference: Profile.ProjectReference):
                    self.project_reference = project_reference

                def __str__(self) -> str:
                    project_reference = self.project_reference
                    project_title = project_reference.title
                    if project_reference.project_state == "needs_upgrade":
                        project_title += " " + _("(NEEDS UPGRADE)")
                    elif project_reference.project_state != "unloaded" or project_reference.project_version != FileStorageSystem.PROJECT_VERSION:
                        project_title += " " + _("(MISSING OR UNREADABLE)")
                    return project_title

                @property
                def tool_tip(self) -> str:
                    return str(self.project_reference.path)

            project_reference_items_model = ListModel.MappedListModel(
                container=project_references_model,
                master_items_key="project_references",
                items_key="project_reference_items",
                map_fn=ProjectReferenceItem)

            item_list = u.create_list_box(
                items_ref="@binding(list_property_model.value)",
                current_index="@binding(current_index)",
                height=240,
                min_height=180,
                size_policy_horizontal="expanding",
                on_item_selected="recent_item_selected",
                on_item_handle_context_menu="item_handle_context_menu")

            main_column = u.create_column(
                u.create_label(text=_("Recent Projects")),
                item_list,
                u.create_spacing(13),
                button_row,
                spacing=8,
                width=380)
            window = u.create_window(main_column,
                                     title=_("Choose Project"),
                                     margin=12,
                                     window_style="tool")

            def open_project_reference(
                    project_reference: Profile.ProjectReference) -> None:
                self.open_project_reference(project_reference)

            def show_open_project_dialog() -> None:
                self.show_open_project_dialog()

            def show_new_project_dialog() -> None:
                NewProjectAction().invoke(
                    UIWindow.ActionContext(self, None, None))

            from nion.utils import Observable

            class ListPropertyModel(Observable.Observable):
                # copied from nionutils to avoid requiring new version.
                # remove this code once nionutils 0.3.24+ is released.

                def __init__(self, list_model):
                    super().__init__()
                    self.__list_model = list_model
                    self.__item_inserted_event_listener = list_model.item_inserted_event.listen(
                        self.__item_inserted)
                    self.__item_removed_event_listener = list_model.item_removed_event.listen(
                        self.__item_removed)

                def close(self) -> None:
                    self.__list_model = None
                    self.__item_inserted_event_listener = None
                    self.__item_removed_event_listener = None

                def __item_inserted(self, key: str, item,
                                    before_index: int) -> None:
                    self.notify_property_changed("value")

                def __item_removed(self, key: str, item, index: int) -> None:
                    self.notify_property_changed("value")

                @property
                def value(self):
                    return self.__list_model.items

            class ChooseProjectHandler(Declarative.WindowHandler):
                def __init__(self, application: Application):
                    super().__init__()
                    self.__application = application
                    self.current_index = 0
                    self.list_property_model = ListPropertyModel(
                        project_reference_items_model)

                def recent_item_selected(self, widget: Declarative.UIWidget,
                                         current_index: int) -> None:
                    if 0 <= current_index < len(project_reference_items_model.
                                                project_reference_items):
                        # to ensure the application does not close upon closing the last window, force it
                        # to stay open while the window is closed and another reopened.
                        with self.__application.prevent_close():
                            self.close_window()
                            project_reference_item = project_reference_items_model.project_reference_items[
                                current_index]
                            open_project_reference(
                                project_reference_item.project_reference)

                def new_project(self, widget: Declarative.UIWidget) -> None:
                    # to ensure the application does not close upon closing the last window, force it
                    # to stay open while the window is closed and another reopened.
                    with self.__application.prevent_close():
                        show_new_project_dialog()
                        self.close_window()

                def open_project(self, widget: Declarative.UIWidget) -> None:
                    # to ensure the application does not close upon closing the last window, force it
                    # to stay open while the window is closed and another reopened.
                    with self.__application.prevent_close():
                        show_open_project_dialog()
                        self.close_window()

                def open_recent(self, widget: Declarative.UIWidget) -> None:
                    self.recent_item_selected(widget, self.current_index)

                def item_handle_context_menu(self,
                                             widget: Declarative.UIWidget, *,
                                             gx: int, gy: int,
                                             index: typing.Optional[int],
                                             **kwargs) -> bool:
                    if index is not None:
                        project_reference_item = project_reference_items_model.project_reference_items[
                            index]
                        menu = self.window.create_context_menu()
                        menu.add_menu_item(
                            _(f"Open Project Location"),
                            functools.partial(
                                ProjectPanel.reveal_project,
                                project_reference_item.project_reference))
                        menu.add_separator()

                        def remove_project(index: int) -> None:
                            project_reference_item = project_reference_items_model.project_reference_items[
                                index]
                            self.__application.profile.remove_project_reference(
                                project_reference_item.project_reference)

                        menu.add_menu_item(
                            _(f"Remove Project from List"),
                            functools.partial(remove_project, index))
                        menu.popup(gx, gy)
                    return True

            ChooseProjectHandler(self).run(window, app=self)