[meld] dirdiff: Identify in-progress scans on tree parent row (#620)



commit 4e617f5d8cbf6ddcee8447650641960e874d121e
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Jan 9 09:35:43 2022 +1000

    dirdiff: Identify in-progress scans on tree parent row (#620)
    
    This is a supplement to our toolbar spinner, since the latter is not
    that obvious and also indicates ongoing tasks anywhere in the
    application, rather than just the current pane.
    
    It would possibly be nicer to have this presented as a spinner cell
    renderer, but since we're only using this for one row (currently) that
    seems like huge overkill in terms of additional cell data and renderers
    for large trees. In the future if we move to more granular progress on
    a per-file basis, per-cell spinners might make more sense.

 meld/dirdiff.py | 32 +++++++++++++++++++++++++++++++-
 meld/tree.py    |  3 +++
 meld/vc/_vc.py  |  3 ++-
 3 files changed, 36 insertions(+), 2 deletions(-)
---
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 4bc7da25..9bf7a11e 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -818,6 +818,28 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
             uris = []
         return RecentType.Folder, uris
 
+    def mark_in_progress_row(self, it: Gtk.TreeIter) -> None:
+        """Mark a tree row as having a scan in progress
+
+        After the scan is finished, `_update_item_state()` must be
+        called on the row to restore its actual state.
+        """
+
+        for pane in range(self.model.ntree):
+            path = self.model.get_value(
+                it, self.model.column_index(tree.COL_PATH, pane))
+            filename = GLib.markup_escape_text(os.path.basename(path))
+            label = _(f"{filename} (scanning…)")
+
+            self.model.set_state(it, pane, tree.STATE_SPINNER, label, True)
+            self.model.unsafe_set(it, pane, {
+                COL_EMBLEM: None,
+                COL_EMBLEM_SECONDARY: None,
+                COL_TIME: MISSING_TIMESTAMP,
+                COL_SIZE: -1,
+                COL_PERMS: -1
+            })
+
     def recursively_update(self, path):
         """Recursively update from tree path 'path'.
         """
@@ -826,7 +848,11 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
         while child:
             self.model.remove(child)
             child = self.model.iter_children(it)
-        self._update_item_state(it)
+        if self._scan_in_progress == 0:
+            # Starting a scan, so set up progress indicator
+            self.mark_in_progress_row(it)
+        else:
+            self._update_item_state(it)
         self._scan_in_progress += 1
         self.scheduler.add_task(self._search_recursively_iter(path))
 
@@ -1002,6 +1028,10 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
         yield _('[{label}] Done').format(label=self.label_text)
 
         self._scan_in_progress -= 1
+        if self._scan_in_progress == 0:
+            # Finishing a scan, so remove progress indicator
+            self._update_item_state(self.model.get_iter(rootpath))
+
         self.force_cursor_recalculate = True
         self.treeview[0].set_cursor(Gtk.TreePath.new_first())
 
diff --git a/meld/tree.py b/meld/tree.py
index b78a4eb7..af9eee75 100644
--- a/meld/tree.py
+++ b/meld/tree.py
@@ -41,6 +41,7 @@ from meld.vc._vc import (  # noqa: F401
     STATE_NONEXIST,
     STATE_NORMAL,
     STATE_REMOVED,
+    STATE_SPINNER,
 )
 
 _GIGtk = None
@@ -102,6 +103,7 @@ class DiffTreeStore(SearchableTreeStore):
             (del_fg, roman,  bold,   True),  # STATE_REMOVED
             (del_fg, roman,  bold,   True),  # STATE_MISSING
             (unk_fg, roman,  normal, True),  # STATE_NONEXIST
+            (None,   italic, normal, None),  # STATE_SPINNER
         ]
 
         self.icon_details = [
@@ -119,6 +121,7 @@ class DiffTreeStore(SearchableTreeStore):
             ("text-x-generic", "folder", del_fg, None),    # REMOVED
             ("text-x-generic", "folder", unk_fg, unk_fg),  # MISSING
             ("text-x-generic", "folder", unk_fg, unk_fg),  # NONEXIST
+            ("text-x-generic", "folder", None,   None),    # SPINNER
         ]
 
         assert len(self.icon_details) == len(self.text_attributes) == STATE_MAX
diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index 18b13777..08c904cf 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -42,7 +42,7 @@ from meld.conf import _
 (STATE_IGNORED, STATE_NONE, STATE_NORMAL, STATE_NOCHANGE,
     STATE_ERROR, STATE_EMPTY, STATE_NEW,
     STATE_MODIFIED, STATE_RENAMED, STATE_CONFLICT, STATE_REMOVED,
-    STATE_MISSING, STATE_NONEXIST, STATE_MAX) = list(range(14))
+    STATE_MISSING, STATE_NONEXIST, STATE_SPINNER, STATE_MAX) = list(range(15))
 
 # VC conflict types
 (CONFLICT_MERGED, CONFLICT_BASE, CONFLICT_LOCAL,
@@ -79,6 +79,7 @@ class Entry:
         STATE_REMOVED: _("Removed"),
         STATE_MISSING: _("Missing"),
         STATE_NONEXIST: _("Not present"),
+        STATE_SPINNER: _("Scanning…"),
     }
 
     def __init__(self, path, name, state, isdir, options=None):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]