From 807783f8d0e64a3dd807e2d4ce9d15a104a74ee7 Mon Sep 17 00:00:00 2001 From: "Nicholas H.Tollervey" Date: Thu, 26 Mar 2020 14:38:55 +0000 Subject: [PATCH] Re-order widgets in the SourceList on update. --- securedrop_client/gui/widgets.py | 25 +++++++++++++++++++++++-- tests/gui/test_widgets.py | 6 +++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/securedrop_client/gui/widgets.py b/securedrop_client/gui/widgets.py index 86d35df51..7680676dd 100644 --- a/securedrop_client/gui/widgets.py +++ b/securedrop_client/gui/widgets.py @@ -889,6 +889,22 @@ def show_no_source_selected_message(self): self.no_source_selected.show() +class SourceListWidgetItem(QListWidgetItem): + + def __lt__(self, other): + """ + Used for ordering widgets by timestamp of last interaction. + """ + lw = self.listWidget() + me = lw.itemWidget(self) + them = lw.itemWidget(other) + if me and them: + my_ts = arrow.get(me.source.last_updated) + other_ts = arrow.get(them.source.last_updated) + return my_ts < other_ts + return True + + class SourceList(QListWidget): """ Displays the list of sources. @@ -921,6 +937,9 @@ def __init__(self): layout = QVBoxLayout(self) self.setLayout(layout) + # Enable ordering. + self.setSortingEnabled(True) + # To hold references to SourceWidget instances indexed by source UUID. self.source_widgets = {} @@ -975,11 +994,13 @@ def update(self, sources: List[Source]) -> List[str]: new_source = SourceWidget(self.controller, source) self.source_widgets[source.uuid] = new_source - list_item = QListWidgetItem() + list_item = SourceListWidgetItem() self.insertItem(0, list_item) list_item.setSizeHint(new_source.sizeHint()) self.setItemWidget(list_item, new_source) + # Sort..! + self.sortItems(Qt.DescendingOrder) return deleted_uuids def initial_update(self, sources: List[Source]): @@ -1003,7 +1024,7 @@ def schedule_source_management(slice_size=slice_size): for source in sources_slice: new_source = SourceWidget(self.controller, source) self.source_widgets[source.uuid] = new_source - list_item = QListWidgetItem(self) + list_item = SourceListWidgetItem(self) list_item.setSizeHint(new_source.sizeHint()) self.insertItem(0, list_item) diff --git a/tests/gui/test_widgets.py b/tests/gui/test_widgets.py index 8929ad5bc..9a2a72c96 100644 --- a/tests/gui/test_widgets.py +++ b/tests/gui/test_widgets.py @@ -769,7 +769,7 @@ def test_SourceList_update_adds_new_sources(mocker): mock_sw = mocker.MagicMock() mock_lwi = mocker.MagicMock() mocker.patch('securedrop_client.gui.widgets.SourceWidget', mock_sw) - mocker.patch('securedrop_client.gui.widgets.QListWidgetItem', mock_lwi) + mocker.patch('securedrop_client.gui.widgets.SourceListWidgetItem', mock_lwi) sources = [mocker.MagicMock(), mocker.MagicMock(), mocker.MagicMock(), ] sl.update(sources) @@ -1009,7 +1009,7 @@ def test_SourceList_add_source_closure_adds_sources(mocker): mock_sw = mocker.MagicMock() mock_lwi = mocker.MagicMock() mocker.patch('securedrop_client.gui.widgets.SourceWidget', mock_sw) - mocker.patch('securedrop_client.gui.widgets.QListWidgetItem', mock_lwi) + mocker.patch('securedrop_client.gui.widgets.SourceListWidgetItem', mock_lwi) sources = [mocker.MagicMock(), mocker.MagicMock(), mocker.MagicMock(), ] mock_timer = mocker.MagicMock() with mocker.patch("securedrop_client.gui.widgets.QTimer", mock_timer): @@ -1044,7 +1044,7 @@ def test_SourceList_add_source_closure_exits_on_no_more_sources(mocker): mock_sw = mocker.MagicMock() mock_lwi = mocker.MagicMock() mocker.patch('securedrop_client.gui.widgets.SourceWidget', mock_sw) - mocker.patch('securedrop_client.gui.widgets.QListWidgetItem', mock_lwi) + mocker.patch('securedrop_client.gui.widgets.SourceListWidgetItem', mock_lwi) sources = [] mock_timer = mocker.MagicMock() with mocker.patch("securedrop_client.gui.widgets.QTimer", mock_timer):