Adding persisting of credentials
[doneit] / src / doneit_glade.py
index 132155c..eef0c6f 100755 (executable)
@@ -9,6 +9,7 @@ import gc
 import os
 import threading
 import warnings
+import ConfigParser
 
 import gtk
 import gtk.glade
@@ -38,11 +39,13 @@ class DoneIt(object):
        _user_settings = "%s/settings.ini" % _user_data
 
        def __init__(self):
-               self._todoUIs = []
+               self._todoUIs = {}
                self._todoUI = None
                self._osso = None
                self._deviceIsOnline = True
                self._connection = None
+               self._fallbackUIName = ""
+               self._defaultUIName = ""
 
                for path in self._glade_files:
                        if os.path.isfile(path):
@@ -104,13 +107,12 @@ class DoneIt(object):
        def _idle_setup(self):
                # Barebones UI handlers
                import gtk_null
-               gtk.gdk.threads_enter()
-               try:
-                       self._todoUIs = [
-                               gtk_null.GtkNull(self._widgetTree),
-                       ]
-               finally:
-                       gtk.gdk.threads_leave()
+               with gtk_toolbox.gtk_lock():
+                       nullView = gtk_null.GtkNull(self._widgetTree)
+                       self._todoUIs[nullView.name()] = nullView
+                       self._todoUI = nullView
+                       self._todoUI.enable()
+                       self._fallbackUIName = nullView.name()
 
                # Setup maemo specifics
                try:
@@ -139,17 +141,20 @@ class DoneIt(object):
 
                # Setup costly backends
                import gtk_rtmilk
-               gtk.gdk.threads_enter()
-               try:
-                       self._todoUIs.extend([
-                               gtk_rtmilk.GtkRtMilk(self._widgetTree),
-                       ])
-                       self._todoUI = self._todoUIs[1]
-                       self._todoUI.enable()
-               finally:
-                       gtk.gdk.threads_leave()
+               with gtk_toolbox.gtk_lock():
+                       rtmView = gtk_rtmilk.GtkRtMilk(self._widgetTree)
+               self._todoUIs[rtmView.name()] = rtmView
+               self._defaultUIName = rtmView.name()
+
+               config = ConfigParser.SafeConfigParser()
+               config.read(self._user_settings)
+               with gtk_toolbox.gtk_lock():
+                       self.load_settings(config)
 
        def display_error_message(self, msg):
+               """
+               @note UI Thread
+               """
                error_dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, msg)
 
                def close(dialog, response, editor):
@@ -158,6 +163,75 @@ class DoneIt(object):
                error_dialog.connect("response", close, self)
                error_dialog.run()
 
+       def load_settings(self, config):
+               """
+               @note UI Thread
+               """
+               for todoUI in self._todoUIs.itervalues():
+                       try:
+                               todoUI.load_settings(config)
+                       except ConfigParser.NoSectionError, e:
+                               warnings.warn(
+                                       "Settings file %s is missing section %s" % (
+                                               self._user_settings,
+                                               e.section,
+                                       ),
+                                       stacklevel=2
+                               )
+
+               try:
+                       activeUIName = config.get(self.__pretty_app_name__, "active")
+               except ConfigParser.NoSectionError, e:
+                       activeUIName = ""
+                       warnings.warn(
+                               "Settings file %s is missing section %s" % (
+                                       self._user_settings,
+                                       e.section,
+                               ),
+                               stacklevel=2
+                       )
+
+               try:
+                       self._switch_ui(activeUIName)
+               except KeyError, e:
+                       self._switch_ui(self._defaultUIName)
+
+       def save_settings(self, config):
+               """
+               @note Thread Agnostic
+               """
+               config.add_section(self.__pretty_app_name__)
+               config.set(self.__pretty_app_name__, "active", self._todoUI.name())
+
+               for todoUI in self._todoUIs.itervalues():
+                       todoUI.save_settings(config)
+
+       def _switch_ui(self, uiName):
+               """
+               @note UI Thread
+               """
+               newActiveUI = self._todoUIs[uiName]
+               try:
+                       newActiveUI.login()
+               except RuntimeError:
+                       return # User cancelled the operation
+
+               self._todoUI.disable()
+               self._todoUI = newActiveUI
+               self._todoUI.enable()
+
+               if uiName != self._fallbackUIName:
+                       self._defaultUIName = uiName
+
+       def _save_settings(self):
+               """
+               @note Thread Agnostic
+               """
+               config = ConfigParser.SafeConfigParser()
+               self.save_settings(config)
+               with open(self._user_settings, "wb") as configFile:
+                       config.write(configFile)
+
        def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
                """
                For system_inactivity, we have no background tasks to pause
@@ -168,7 +242,7 @@ class DoneIt(object):
                        gc.collect()
 
                if save_unsaved_data or shutdown:
-                       pass
+                       self._save_settings()
 
        def _on_connection_change(self, connection, event, magicIdentifier):
                """
@@ -183,8 +257,10 @@ class DoneIt(object):
 
                if status == conic.STATUS_CONNECTED:
                        self._deviceIsOnline = True
+                       self._switch_ui(self._defaultUIName)
                elif status == conic.STATUS_DISCONNECTED:
                        self._deviceIsOnline = False
+                       self._switch_ui(self._fallbackUIName)
 
        def _on_window_state_change(self, widget, event, *args):
                """
@@ -196,11 +272,11 @@ class DoneIt(object):
                        self._isFullScreen = False
 
        def _on_close(self, *args, **kwds):
-               if self._osso is not None:
-                       self._osso.close()
-
                try:
-                       pass
+                       if self._osso is not None:
+                               self._osso.close()
+
+                       self._save_settings()
                finally:
                        gtk.main_quit()
 
@@ -217,6 +293,10 @@ class DoneIt(object):
                        else:
                                self.__window.fullscreen()
 
+       def _on_logout(self, *args):
+               self._todoUI.logout()
+               self._switch_ui(self._fallbackUIName)
+
        def _on_about_activate(self, *args):
                dlg = gtk.AboutDialog()
                dlg.set_name(self.__pretty_app_name__)