Esempio n. 1
0
def set_selected_multiple(editor, rows):
    """ Clears old selection and selects specified rows in an editor
    with multi_select=True.
    """
    if is_wx():
        clear_selection(editor)
        for row in rows:
            editor.control.Select(row)

    elif is_qt():
        from pyface.qt.QtGui import QItemSelectionModel

        clear_selection(editor)
        smodel = editor.control.selectionModel()
        for row in rows:
            mi = editor.model.index(row, 0)
            # Add `Rows` flag to select the whole row
            smodel.select(
                mi, QItemSelectionModel.Select | QItemSelectionModel.Rows)

    else:
        raise unittest.SkipTest("Test not implemented for this toolkit")
Esempio n. 2
0
def set_combobox_text(combobox, text):
    """ Set the text given a combobox control """
    if is_wx():
        import wx

        if isinstance(combobox, wx.Choice):
            event_type = wx.EVT_CHOICE.typeId
            event = wx.CommandEvent(event_type, combobox.GetId())
            event.SetString(text)
            wx.PostEvent(combobox, event)
        else:
            combobox.SetValue(text)
            event_type = wx.EVT_COMBOBOX.typeId
            event = wx.CommandEvent(event_type, combobox.GetId())
            event.SetString(text)
            wx.PostEvent(combobox, event)

    elif is_qt():
        combobox.setEditText(text)

    else:
        raise unittest.SkipTest("Test not implemented for this toolkit")
Esempio n. 3
0
    def test_list_str_editor_multi_selection_changed(self):
        view = get_view(multi_select=True)

        with reraise_exceptions(), self.setup_gui(
            ListStrModel(), view
        ) as editor:

            self.assertEqual(get_selected_indices(editor), [])

            editor.multi_selected_indices = [0, 1]
            process_cascade_events()

            self.assertEqual(get_selected_indices(editor), [0, 1])
            self.assertEqual(editor.multi_selected, ["one", "two"])

            editor.multi_selected = ["three", "one"]
            process_cascade_events()

            self.assertEqual(sorted(get_selected_indices(editor)), [0, 2])
            self.assertEqual(sorted(editor.multi_selected_indices), [0, 2])

            editor.multi_selected = ["three", "four"]
            process_cascade_events()

            if is_qt():
                # Invalid values assigned to multi_selected are ignored
                self.assertEqual(get_selected_indices(editor), [2])
                self.assertEqual(editor.multi_selected_indices, [2])
            elif is_wx():
                # Selection indices are not updated at all
                self.assertEqual(get_selected_indices(editor), [0, 2])
                self.assertEqual(editor.multi_selected_indices, [0, 2])

            # Setting selected indices to an empty list clears selection
            editor.multi_selected_indices = []
            process_cascade_events()

            self.assertEqual(get_selected_indices(editor), [])
            self.assertEqual(editor.multi_selected, [])
def get_selected_indices(editor):
    """ Returns a list of the indices of all currently selected list items.
    """
    if is_wx():
        import wx
        # "item" in this context means "index of the item"
        item = -1
        selected = []
        while True:
            item = editor.control.GetNextItem(item, wx.LIST_NEXT_ALL,
                                              wx.LIST_STATE_SELECTED)
            if item == -1:
                break
            selected.append(item)
        return selected

    elif is_qt():
        indices = editor.list_view.selectionModel().selectedRows()
        return [i.row() for i in indices]

    else:
        raise unittest.SkipTest("Test not implemented for this toolkit")
def get_selected_rows(editor):
    """ Returns a list of all currently selected rows.
    """
    if is_wx():
        import wx
        # "item" in this context means "row number"
        item = -1
        selected = []
        while True:
            item = editor.control.GetNextItem(item, wx.LIST_NEXT_ALL,
                                              wx.LIST_STATE_SELECTED)
            if item == -1:
                break
            selected.append(item)
        return selected

    elif is_qt():
        rows = editor.control.selectionModel().selectedRows()
        return [r.row() for r in rows]

    else:
        raise unittest.SkipTest("Test not implemented for this toolkit")
    def test_simple_set_editor_deleted_valid_values(self):
        editor_factory = SetEditor(values=["one", "two", "three", "four"])
        view = View(UItem("value", editor=editor_factory, style="simple",))
        list_edit = ListModel()

        with reraise_exceptions(), \
                self.setup_gui(list_edit, view) as editor:

            self.assertEqual(get_list_items(editor._unused), ["four", "three"])
            self.assertEqual(get_list_items(editor._used), ["one", "two"])

            editor_factory.values = ["two", "three", "four"]
            process_cascade_events()

            self.assertEqual(get_list_items(editor._unused), ["four", "three"])
            # FIXME issue enthought/traitsui#840
            if is_wx():
                with self.assertRaises(AssertionError):
                    self.assertEqual(get_list_items(editor._used), ["two"])
                self.assertEqual(get_list_items(editor._used), ["one", "two"])
            else:
                self.assertEqual(get_list_items(editor._used), ["two"])
            self.assertEqual(list_edit.value, ["two"])
Esempio n. 7
0
 def test_range_text_editor_set_with_text_valid(self):
     model = RangeModel()
     view = View(
         Item(
             "value",
             editor=RangeEditor(low=1, high=12, mode="text")
         )
     )
     tester = UITester()
     with tester.create_ui(model, dict(view=view)) as ui:
         # sanity check
         self.assertEqual(model.value, 1)
         number_field_text = tester.find_by_name(ui, "value")
         if is_windows and is_wx():
             # For RangeTextEditor on wx and windows, the textbox
             # automatically gets focus and the full content is selected.
             # Insertion point is moved to keep the test consistent
             number_field_text.perform(KeyClick("End"))
         number_field_text.perform(KeyClick("0"))
         number_field_text.perform(KeyClick("Enter"))
         displayed = number_field_text.inspect(DisplayedText())
         self.assertEqual(model.value, 10)
         self.assertEqual(displayed, str(model.value))
Esempio n. 8
0
class TestTabularEditor(BaseTestMixin, UnittestTools, unittest.TestCase):

    def setUp(self):
        BaseTestMixin.setUp(self)

    def tearDown(self):
        BaseTestMixin.tearDown(self)

    @unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
    def test_tabular_editor_single_selection(self):

        with reraise_exceptions(), \
                self.report_and_editor(get_view()) as (report, editor):
            process_cascade_events()
            people = report.people

            self.assertEqual(report.selected_row, -1)
            self.assertIsNone(report.selected)

            set_selected_single(editor, 1)
            process_cascade_events()

            self.assertEqual(report.selected_row, 1)
            self.assertEqual(report.selected, people[1])

            set_selected_single(editor, 2)
            process_cascade_events()

            self.assertEqual(report.selected_row, 2)
            self.assertEqual(report.selected, people[2])

            # Can't clear selection via UI when multi_select=False

    @unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
    def test_tabular_editor_multi_selection(self):
        view = get_view(multi_select=True)

        with reraise_exceptions(), \
                self.report_and_editor(view) as (report, editor):
            process_cascade_events()
            people = report.people

            self.assertEqual(report.selected_rows, [])
            self.assertEqual(report.multi_selected, [])

            set_selected_multiple(editor, [0, 1])
            process_cascade_events()

            self.assertEqual(report.selected_rows, [0, 1])
            self.assertEqual(report.multi_selected, people[:2])

            set_selected_multiple(editor, [2])
            process_cascade_events()

            self.assertEqual(report.selected_rows, [2])
            self.assertEqual(report.multi_selected, [people[2]])

            clear_selection(editor)
            process_cascade_events()

            self.assertEqual(report.selected_rows, [])
            self.assertEqual(report.multi_selected, [])

    @unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
    def test_tabular_editor_single_selection_changed(self):

        with reraise_exceptions(), \
                self.report_and_editor(get_view()) as (report, editor):
            process_cascade_events()
            people = report.people

            self.assertEqual(get_selected_rows(editor), [])

            report.selected_row = 1
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [1])
            self.assertEqual(report.selected, people[1])

            report.selected = people[2]
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [2])
            self.assertEqual(report.selected_row, 2)

            # Selected set to invalid value doesn't change anything
            report.selected = Person(name="invalid", age=-1)
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [2])
            self.assertEqual(report.selected_row, 2)

            # -1 clears selection
            report.selected_row = -1
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [])
            self.assertEqual(report.selected, None)

    @unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
    def test_tabular_editor_multi_selection_changed(self):
        view = get_view(multi_select=True)

        with reraise_exceptions(), \
                self.report_and_editor(view) as (report, editor):
            process_cascade_events()
            people = report.people

            self.assertEqual(get_selected_rows(editor), [])

            report.selected_rows = [0, 1]
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [0, 1])
            self.assertEqual(report.multi_selected, people[:2])

            report.multi_selected = [people[2], people[0]]
            process_cascade_events()

            self.assertEqual(sorted(get_selected_rows(editor)), [0, 2])
            self.assertEqual(sorted(report.selected_rows), [0, 2])

            # If there's a single invalid value, nothing is updated
            invalid_person = Person(name="invalid", age=-1)
            report.multi_selected = [people[2], invalid_person]
            process_cascade_events()

            self.assertEqual(sorted(get_selected_rows(editor)), [0, 2])
            self.assertEqual(sorted(report.selected_rows), [0, 2])

            # Empty list clears selection
            report.selected_rows = []
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [])
            self.assertEqual(report.multi_selected, [])

    @unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
    def test_tabular_editor_multi_selection_items_changed(self):
        view = get_view(multi_select=True)

        with reraise_exceptions(), \
                self.report_and_editor(view) as (report, editor):
            process_cascade_events()
            people = report.people

            self.assertEqual(get_selected_rows(editor), [])

            report.selected_rows.extend([0, 1])
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [0, 1])
            self.assertEqual(report.multi_selected, people[:2])

            report.selected_rows[1] = 2
            process_cascade_events()

            self.assertEqual(get_selected_rows(editor), [0, 2])
            self.assertEqual(report.multi_selected, people[0:3:2])

            report.multi_selected[0] = people[1]
            process_cascade_events()

            self.assertEqual(sorted(get_selected_rows(editor)), [1, 2])
            self.assertEqual(sorted(report.selected_rows), [1, 2])

            # If there's a single invalid value, nothing is updated
            report.multi_selected[0] = Person(name="invalid", age=-1)
            process_cascade_events()

            self.assertEqual(sorted(get_selected_rows(editor)), [1, 2])
            self.assertEqual(sorted(report.selected_rows), [1, 2])

    def test_selected_reacts_to_model_changes(self):
        with self.report_and_editor(get_view()) as (report, editor):
            people = report.people

            self.assertIsNone(report.selected)
            self.assertEqual(report.selected_row, -1)

            report.selected = people[1]
            self.assertEqual(report.selected, people[1])
            self.assertEqual(report.selected_row, 1)

            report.selected = None
            self.assertIsNone(report.selected)
            self.assertEqual(report.selected_row, -1)

            report.selected_row = 0
            self.assertEqual(report.selected, people[0])
            self.assertEqual(report.selected_row, 0)

            report.selected_row = -1
            self.assertIsNone(report.selected)
            self.assertEqual(report.selected_row, -1)

    def test_event_synchronization(self):
        with self.report_and_editor(get_view()) as (report, editor):
            with self.assertTraitChanges(editor, "refresh", count=1):
                report.refresh = True
            # Should happen every time.
            with self.assertTraitChanges(editor, "refresh", count=1):
                report.refresh = True

            with self.assertTraitChanges(editor, "update", count=1):
                report.update = True
            with self.assertTraitChanges(editor, "update", count=1):
                report.update = True

    def test_adapter_columns_changes(self):
        # Regression test for enthought/traitsui#894
        with reraise_exceptions(), \
                self.report_and_editor(get_view()) as (report, editor):

            # Reproduce the scenario when the column count is reduced.
            editor.adapter.columns = [
                ("Name", "name"), ("Age", "age"),
            ]
            # Recalculating column widths take into account the user defined
            # widths, cached in the view. The cache should be invalidated
            # when the columns is updated such that recalculation does not
            # fail.
            editor.adapter.columns = [("Name", "name")]
            process_cascade_events()

    def test_view_column_resized_attribute_error_workaround(self):
        # This tests the workaround which checks if `factory` is None before
        # using it while resizing the columns.
        # The resize event is processed after UI.dispose is called.
        # Maybe related to enthought/traits#431
        with reraise_exceptions(), \
                self.report_and_editor(get_view()) as (_, editor):
            editor.adapter.columns = [("Name", "name")]

    @contextlib.contextmanager
    def report_and_editor(self, view):
        """
        Context manager to temporarily create and clean up a Report model object
        and the corresponding TabularEditor.
        """
        report = Report(
            people=[
                Person(name="Theresa", age=60),
                Person(name="Arlene", age=46),
                Person(name="Karen", age=40),
            ]
        )
        with create_ui(report, dict(view=view)) as ui:
            editor, = ui.get_editors("people")
            yield report, editor
Esempio n. 9
0
            self.max_n_events = max_n_events
            self.n_events = 0

        def event(self, event):
            if event.type() != QtCore.QEvent.User:
                return super().event(event)

            self.n_events += 1

            if self.n_events < self.max_n_events:
                new_event = QtCore.QEvent(QtCore.QEvent.User)
                QtCore.QCoreApplication.postEvent(self, new_event)
            return True


if is_wx():

    # Create a wx.EvtHandler that will emit a new event to itself as long as
    # it has not received enough.

    import wx
    import wx.lib.newevent

    NewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()

    class DummyWxHandler(wx.EvtHandler):
        def __init__(self, max_n_events):
            super().__init__()
            self.max_n_events = max_n_events
            self.n_events = 0
Esempio n. 10
0
    "This example depends on PyTables which may be built to require CPUs with "
    "a specific AVX version that is not supported on a paricular OSX host.",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Advanced", "Table_editor_with_progress_column.py"),
    is_wx,
    "ProgressRenderer is not implemented in wx.",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Advanced", "Scrubber_editor_demo.py"),
    is_qt,
    "ScrubberEditor is not implemented in qt.",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Extras", "animated_GIF.py"),
    lambda: not is_wx(),
    "Only support wx",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Extras", "Tree_editor_with_TreeNodeRenderer.py"),
    lambda: not is_qt(),
    "Only support Qt",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Extras", "windows", "flash.py"),
    lambda: not is_wx(),
    "Only support wx",
)
SEARCHER.skip_file_if(
    os.path.join(DEMO, "Extras", "windows", "internet_explorer.py"),
    lambda: not is_wx(),
Esempio n. 11
0
        from pyface.qt import QtCore
        from pyface.qt.QtTest import QTest

        view = editor.list_view
        rect = view.rect()
        QTest.mouseClick(
            view.viewport(),
            QtCore.Qt.MouseButton.RightButton,
            QtCore.Qt.KeyboardModifier.NoModifier,
            rect.center(),
        )
    else:
        raise unittest.SkipTest("Test not implemented for this toolkit")


@unittest.skipIf(is_wx(), "Issue enthought/traitsui#752")
@requires_toolkit([ToolkitName.qt, ToolkitName.wx])
class TestListStrEditor(BaseTestMixin, unittest.TestCase):
    def setUp(self):
        BaseTestMixin.setUp(self)

    def tearDown(self):
        BaseTestMixin.tearDown(self)

    @contextlib.contextmanager
    def setup_gui(self, model, view):
        with create_ui(model, dict(view=view)) as ui:
            process_cascade_events()
            editor = ui.get_editors("value")[0]
            yield editor