Always give the Listbox items.
[matthijs/upstream/mobilegtd.git] / src / gui / gui.py
index a981b61111d5c44bd7daadbe7360cb9154294729..50c6d3138205afa063b40c753a808496bc1b5160 100644 (file)
@@ -137,12 +137,13 @@ class View(object):
         appuifw.app.body=self.view
         appuifw.app.exit_key_handler=self.exit
         try:
         appuifw.app.body=self.view
         appuifw.app.exit_key_handler=self.exit
         try:
-            self.lock.wait()
             while not self.exit_flag:
                 self.refresh()
                 self.lock.wait()
         except:
             while not self.exit_flag:
                 self.refresh()
                 self.lock.wait()
         except:
-            pass
+            # TODO: Find out which exceptions to catch here. Catching
+            # and silencing all exceptions is not a good idea.
+            raise
         restore_gui(self)
 
     def exit(self):
         restore_gui(self)
 
     def exit(self):
@@ -162,7 +163,7 @@ class View(object):
         Called when the current view must be updated. Never call
         directly. Subclasses should extend this method, not update.
         """
         Called when the current view must be updated. Never call
         directly. Subclasses should extend this method, not update.
         """
-        pass
+        self.refresh_menu()
 
     def refresh_menu(self):
         """
 
     def refresh_menu(self):
         """
@@ -172,7 +173,10 @@ class View(object):
         # Two helper functions
         def shortcut_prefix(key_name):
             short = key_shortname(key_name)
         # Two helper functions
         def shortcut_prefix(key_name):
             short = key_shortname(key_name)
-            return '[%s]' % short if short else '   '
+            if short:
+                return '[%s]' % short
+            else:
+                return '   '
 
         def do_entry((text, callback, key_name)):
             key = get_key(key_name)
 
         def do_entry((text, callback, key_name)):
             key = get_key(key_name)
@@ -203,7 +207,8 @@ class ListView(View):
     def __init__(self):
         super(ListView, self).__init__()
         self.current_index = None
     def __init__(self):
         super(ListView, self).__init__()
         self.current_index = None
-        self.set_view(appuifw.Listbox(self.items(),self.entry_selected))
+        self.items_cache = self.items()
+        self.set_view(appuifw.Listbox(self.items_cache, self.entry_selected))
         self.view.bind(EKeyUpArrow,lambda: self.arrow_key_pressed(-1))
         self.view.bind(EKeyDownArrow,lambda: self.arrow_key_pressed(1))
 
         self.view.bind(EKeyUpArrow,lambda: self.arrow_key_pressed(-1))
         self.view.bind(EKeyDownArrow,lambda: self.arrow_key_pressed(1))
 
@@ -221,6 +226,27 @@ class ListView(View):
         self.index_changed()
         self.current_index = None
 
         self.index_changed()
         self.current_index = None
 
+    def refresh(self):
+        self.refresh_list()
+        super(ListView, self).refresh()
+    
+    def refresh_list(self):
+        """ Reload the list items. Calls items() again. """
+        # Remember which item was selected
+        selected = self.selected_item()
+        # Refresh the list
+        self.items_cache = self.items()
+        try:
+            # Try to find the selected item in the new list (based on
+            # the display text).
+            selected_index = self.items_cache.index(selected)
+        except ValueError:
+            # If the selected item is no longer present, just keep the
+            # index the same (but be careful not to fall off the end).
+            selected_index = self.clip_index(self.selected_index())
+        # Update the items in the view
+        self.view.set_list(self.items_cache, selected_index)
+
     def run(self):
         self.index_changed()
         super(ListView, self).run()
     def run(self):
         self.index_changed()
         super(ListView, self).run()
@@ -247,7 +273,14 @@ class ListView(View):
 
     def set_index(self,index):
         """ Changes the currently selected item to index. """
 
     def set_index(self,index):
         """ Changes the currently selected item to index. """
-        self.view.set_list(self.items(),index % len(self.items()))
+        self.view.set_list(self.items_cache, self.clip_index(index))
+
+    def selected_item(self):
+        """ Returns the (title of the) currently selected list item. """
+        if not self.items_cache:
+            return None # No items, so none is selected.
+        return self.items_cache[self.selected_index()]
+
 
     def selected_index(self):
         """ Returns the currently selected index. """
 
     def selected_index(self):
         """ Returns the currently selected index. """
@@ -294,16 +327,19 @@ class WidgetBasedListView(ListView):
         self.refresh()
 
     def refresh(self):
         self.refresh()
 
     def refresh(self):
-        self.widgets = self.generate_widgets()
-        self.redisplay_widgets()
+        self.refresh_widgets()
         super(WidgetBasedListView,self).refresh()
         super(WidgetBasedListView,self).refresh()
+    
+    def refresh_widgets(self):
+        """ Refresh the widget list. Calls generate_widgets(). """
+        self.widgets = self.generate_widgets()
 
     def redisplay_widgets(self):
         """
         Redisplay the widgets. Should be called if the widgets
         themselves have changed, does not call generate_widgets again.
         """
 
     def redisplay_widgets(self):
         """
         Redisplay the widgets. Should be called if the widgets
         themselves have changed, does not call generate_widgets again.
         """
-        self.set_index(self.selected_index())
+        self.refresh_list()
 
     def items(self):
         # Let ListView show each widget's text.
 
     def items(self):
         # Let ListView show each widget's text.