[hamster-applet] trying to minimize tree refresh flicker



commit 41c4b8a8f02f0fd15307c33c187b7f3026a0ad97
Author: Toms Bauģis <toms baugis gmail com>
Date:   Thu Jan 21 01:04:01 2010 +0000

    trying to minimize tree refresh flicker

 hamster/applet.py              |    3 +-
 hamster/overview_activities.py |   24 +++++++++++++---
 hamster/widgets/facttree.py    |   57 +++++++++++++++++++++++++++------------
 3 files changed, 60 insertions(+), 24 deletions(-)
---
diff --git a/hamster/applet.py b/hamster/applet.py
index 5006bf8..f8541f1 100755
--- a/hamster/applet.py
+++ b/hamster/applet.py
@@ -347,10 +347,11 @@ class HamsterApplet(object):
         """sets up today's tree and fills it with records
            returns information about last activity"""
 
+        facts = runtime.storage.get_todays_facts()
+
         self.treeview.detach_model()
         self.treeview.clear()
 
-        facts = runtime.storage.get_todays_facts()
         if facts and facts[-1]["end_time"] == None:
             self.last_activity = facts[-1]
         else:
diff --git a/hamster/overview_activities.py b/hamster/overview_activities.py
index 057729c..83b3755 100644
--- a/hamster/overview_activities.py
+++ b/hamster/overview_activities.py
@@ -61,8 +61,14 @@ class OverviewBox(gtk.VBox):
         scroll.add(self.fact_tree)
         self.add(scroll)
 
+        self.ignore_next_refresh = False
+
 
     def search(self, start_date, end_date, facts):
+        if self.ignore_next_refresh: # avoid reloading when we are operating with the data
+            self.ignore_next_refresh = False
+            return
+
         self.start_date = start_date
         self.end_date = end_date
         self.facts = facts
@@ -70,10 +76,6 @@ class OverviewBox(gtk.VBox):
 
 
     def fill_facts_tree(self):
-        # remember any selection - will try to match by
-        self.fact_tree.detach_model()
-        self.fact_tree.clear()
-
         #create list of all required dates
         dates = [(self.start_date + dt.timedelta(i), [])
                     for i in range((self.end_date - self.start_date).days  + 1)]
@@ -82,7 +84,12 @@ class OverviewBox(gtk.VBox):
         for date, facts in groupby(self.facts, lambda fact: fact["date"]):
             dates[dates.index((date, []))] = (date, list(facts))
 
-        # push them in tree
+
+        # detach model to trigger selection memory and speeding up
+        self.fact_tree.detach_model()
+        self.fact_tree.clear()
+
+        # push facts in tree
         for date, facts in dates:
             fact_date = date.strftime(C_("overview list", "%A, %b %d"))
             self.fact_tree.add_group(fact_date, date, facts)
@@ -95,6 +102,13 @@ class OverviewBox(gtk.VBox):
         if not fact or isinstance(fact, dt.date):
             return
 
+        self.ignore_next_refresh = True
+
+        selection = self.fact_tree.get_selection()
+        (model, iter) = selection.get_selected()
+        self.fact_tree.select_next()
+
+        model.remove(iter)
         runtime.storage.remove_fact(fact['id'])
 
     def copy_selected(self):
diff --git a/hamster/widgets/facttree.py b/hamster/widgets/facttree.py
index 94beb5e..10e38a2 100644
--- a/hamster/widgets/facttree.py
+++ b/hamster/widgets/facttree.py
@@ -147,31 +147,28 @@ class FactTree(gtk.TreeView):
         self.expand_all()
 
 
-    def _id_or_label(self, model, path):
-        """returns id or date, id if it is a fact row or date if it is a group row"""
-
+    def get_row(self, path):
+        """checks if the path is valid and if so, returns the model row"""
         try: # see if path is still valid
-            iter = model.get_iter(path)
+            iter = self.store_model.get_iter(path)
+            return self.store_model[path]
         except:
             return None
 
-        if model[path][0]:
-            return model[path][0]['id']
+    def _id_or_label(self, model, path):
+        """returns id or date, id if it is a fact row or date if it is a group row"""
+        row = self.get_row(path)
+        if not row: return None
+
+        if row[0]:
+            return row[0]['id']
         else:
-            return model[path][1]['label']
+            return row[1]['label']
 
     def detach_model(self):
         # ooh, somebody is going for refresh!
         # let's save selection too - maybe it will come handy
-        selection = self.get_selection()
-        model, iter = selection.get_selected()
-
-        if iter:
-            path = model.get_path(iter)[0]
-            prev, cur, next = path - 1, path, path + 1
-            self.stored_selection = ((prev, self._id_or_label(model, prev)),
-                                     (cur, self._id_or_label(model, cur)),
-                                     (next, self._id_or_label(model, next)))
+        self.store_selection()
 
         # and now do what we were asked to
         self.set_model()
@@ -183,10 +180,22 @@ class FactTree(gtk.TreeView):
         self.expand_all()
 
         if self.stored_selection:
-            self._restore_selection()
+            self.restore_selection()
 
 
-    def _restore_selection(self):
+    def store_selection(self):
+        selection = self.get_selection()
+        model, iter = selection.get_selected()
+
+        if iter:
+            path = model.get_path(iter)[0]
+            prev, cur, next = path - 1, path, path + 1
+            self.stored_selection = ((prev, self._id_or_label(model, prev)),
+                                     (cur, self._id_or_label(model, cur)),
+                                     (next, self._id_or_label(model, next)))
+
+
+    def restore_selection(self):
         """the code is quite hairy, but works with all kinds of deletes
            and does not select row when it should not.
            TODO - it might be worth replacing this with something much simpler"""
@@ -221,6 +230,18 @@ class FactTree(gtk.TreeView):
 
             self.scroll_to_cell(path)
 
+    def select_next(self):
+        selection = self.get_selection()
+        model, iter = selection.get_selected()
+
+        path = 0
+        if iter:
+            path = model.get_path(iter)[0]
+            if self.get_row(path+1):
+                path = path + 1
+
+        selection.select_path(path)
+
 
     def get_selected_fact(self):
         selection = self.get_selection()



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