From 2e13b35a64870348221b8890e9f9196006fb5a46 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sun, 11 Jul 2021 13:10:24 -0700 Subject: [PATCH] models: emit a notification with model contents The deferred nature of Qt notifications causes the about_to_update signal to get handled *after* the model contents have been updated. This makes it difficult to implement the selection restoration behavior in the Status widget because we need access to the original state. Emit a notification with the original state so that we can store and use it in the Status widget. Related-to: #1130 #1131 Signed-off-by: David Aguilar --- cola/models/main.py | 8 ++++++++ cola/widgets/status.py | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cola/models/main.py b/cola/models/main.py index bd8ba838..b99d07d1 100644 --- a/cola/models/main.py +++ b/cola/models/main.py @@ -27,6 +27,7 @@ class MainModel(Observable): # Observable messages message_about_to_update = 'about_to_update' + message_previous_contents = 'previous_contents' message_commit_message_changed = 'commit_message_changed' message_diff_text_changed = 'diff_text_changed' message_diff_text_updated = 'diff_text_updated' @@ -231,6 +232,13 @@ class MainModel(Observable): self.update_file_status() def emit_about_to_update(self): + self.notify_observers( + self.message_previous_contents, + self.staged, + self.unmerged, + self.modified, + self.untracked + ) self.notify_observers(self.message_about_to_update) def emit_updated(self): diff --git a/cola/widgets/status.py b/cola/widgets/status.py index 7c055ce3..26f2c51b 100644 --- a/cola/widgets/status.py +++ b/cola/widgets/status.py @@ -110,6 +110,7 @@ class StatusWidget(QtWidgets.QFrame): class StatusTreeWidget(QtWidgets.QTreeWidget): # Signals about_to_update = Signal() + set_previous_contents = Signal(list, list, list, list) updated = Signal() diff_text_changed = Signal() @@ -148,6 +149,7 @@ class StatusTreeWidget(QtWidgets.QTreeWidget): self.old_selection = None self.old_contents = None self.old_current_item = None + self.previous_contents = None self.was_visible = True self.expanded_items = set() @@ -289,15 +291,24 @@ class StatusTreeWidget(QtWidgets.QTreeWidget): ) self.delete_untracked_files_action.setIcon(icons.discard()) - about_to_update = self._about_to_update - self.about_to_update.connect(about_to_update, type=Qt.QueuedConnection) + self.about_to_update.connect(self._about_to_update, type=Qt.QueuedConnection) + self.set_previous_contents.connect( + self._set_previous_contents, type=Qt.QueuedConnection) self.updated.connect(self.refresh, type=Qt.QueuedConnection) self.diff_text_changed.connect( self._make_current_item_visible, type=Qt.QueuedConnection ) + # The model is stored as self.m because self.model() is a + # QTreeWidgetItem method that returns a QAbstractItemModel. self.m = context.model + # Forward the previous_contents notification through self.set_previous_contents. + self.m.add_observer( + self.m.message_previous_contents, self.set_previous_contents.emit + ) + # Forward the about_to_update notification through self.about_to_udpate. self.m.add_observer(self.m.message_about_to_update, self.about_to_update.emit) + # Foward the updated notification through self.updated. self.m.add_observer(self.m.message_updated, self.updated.emit) self.m.add_observer( self.m.message_diff_text_changed, self.diff_text_changed.emit @@ -520,6 +531,10 @@ class StatusTreeWidget(QtWidgets.QTreeWidget): parent = self.topLevelItem(idx) return parent.child(itemidx) + def _set_previous_contents(self, staged, unmerged, modified, untracked): + """Callback triggered right before the model changes its contents""" + self.previous_contents = selection.State(staged, unmerged, modified, untracked) + def _about_to_update(self): self._save_scrollbars() self._save_selection() -- 2.11.4.GIT