Add gnome-python dependency (fixes MB#11476).
[hermes] / package / src / org / maemo / hermes / gui / gtkui.py
index 37524b0..f948453 100644 (file)
@@ -3,13 +3,16 @@ import gtk, gobject
 import traceback
 import time
 import thread
-from org.maemo.hermes.gui.contactview import ContactView
 import urllib2
 import hildon
+import conic
+import webbrowser
 from org.bleb.wimpworks import WimpWorks
+from org.maemo.hermes.gui.contactview import ContactView
 from org.maemo.hermes.gui.mapcontact import MapContact
+from org.maemo.hermes.gui.accountsdialogue import AccountsDialogue
 from org.bleb.wimpworks import HildonMainScreenLayout
-#from hermes import Hermes ### FIXME This needs to be new
+from org.maemo.hermes.engine.hermes import Hermes
 
 class HermesGUI(WimpWorks):
     """Provides the GUI for Hermes, allowing the syncing of Facebook and
@@ -20,9 +23,9 @@ class HermesGUI(WimpWorks):
 
 
     # -----------------------------------------------------------------------
-    def __init__(self):
+    def __init__(self, providers = None):
         gettext.install('hermes','/opt/hermes/share/locale/')
-        WimpWorks.__init__(self, 'Hermes', version = '0.2.0', dbus_name = 'org.maemo.hermes')
+        WimpWorks.__init__(self, 'Hermes', version = '0.8.7', dbus_name = 'org.maemo.hermes')
         self.set_background('background.png')
         
         layout = HildonMainScreenLayout(offset = 0.8, container = self)
@@ -30,7 +33,13 @@ class HermesGUI(WimpWorks):
         layout.add_button('Refresh', _("Update contacts' info"))
         
         self.add_menu_action("Accounts")
+        self.add_menu_action("About")
         self.menu.show_all()
+        
+        self.providers = providers
+        self.progressnote = None
+        connection = conic.Connection()
+        gobject.timeout_add(100, connection.request_connection, conic.CONNECT_FLAG_NONE)
 
   
     # -----------------------------------------------------------------------
@@ -45,65 +54,85 @@ class HermesGUI(WimpWorks):
 
     # -----------------------------------------------------------------------
     def do_accounts(self, widget = None):
-        dialog = gtk.Dialog(_('Accounts'), self.main_window)
-        dialog.add_button(_('Save'), gtk.RESPONSE_OK)
-        
-        #pa = hildon.PannableArea()
-        #dialog.vbox.add(pa)
-        content = dialog.vbox 
-        #content = gtk.VBox()
-        #pa.add(content)
-        #pa.set_size_request(600, 380)
-        
-        use_facebook = self.new_checkbox(_('Use Facebook'), content)
-        use_facebook.set_active(self.get_use_facebook())
-        
-        indent = self.new_indent(content)
-        self.link_control(use_facebook, gtk.Label(_('Note: authentication via web page')), indent)
-        
-        fb_empty = self.link_control(use_facebook, self.new_checkbox(_('Create birthday-only contacts')), indent)
-        fb_empty.set_active(self.get_create_empty())
-        
-        use_twitter = self.new_checkbox(_('Use Twitter'), content)
-        use_twitter.set_active(self.get_use_twitter())
-        
-        indent = self.new_indent(content)
-        tw_user = self.link_control(use_twitter, self.new_input(_('Twitter username')), indent)
-        tw_user.set_text(self.get_twitter_credentials()[0])
-        
-        tw_pass = self.link_control(use_twitter, self.new_input(_('Twitter password'), password = True), indent)
-        tw_pass.set_text(self.get_twitter_credentials()[1])
-        
-        dialog.show_all()
-        result = dialog.run()
-        dialog.hide()
-        if result == gtk.RESPONSE_OK:
-            self.set_use_facebook(use_facebook.get_active())
-            self.set_create_empty(fb_empty.get_active())
-            self.set_use_twitter(use_twitter.get_active(), tw_user.get_text(), tw_pass.get_text())
+        dialog = AccountsDialogue(self.main_window, self.providers)
+        dialog.show()
+
+
+    # -----------------------------------------------------------------------
+    def do_about(self, widget):
+        """Inspired by HeAboutDialog Python port:
+           http://wiki.maemo.org/Hildon-Extras#HeAboutDialog"""
+
+        dlg = gtk.Dialog(_("About"), self.main_window)
+
+        icon = gtk.Image()
+        icon.set_from_icon_name(self.name.lower(), gtk.ICON_SIZE_DIALOG)
+        icon.set_padding(5, 5)
+
+        name = gtk.Label(self.name)
+        name.set_alignment(0, 1)
+        hildon.hildon_helper_set_logical_font(name, 'X-LargeSystemFont')
+
+        version = gtk.Label('v%s' % (self.version))
+        version.set_alignment(0, 1)
+        version.set_padding(10, 0)
+        hildon.hildon_helper_set_logical_font(version, 'LargeSystemFont')
         
-        return result
+        desc = gtk.Label(_("Enrich contacts' from social networks."))
+        desc.set_alignment(0, 0)
+
+        copy = gtk.Label("Copyright (c) 2010 Andrew Flegg, Fredrik Wendt, Tim Samoff")
+        copy.set_alignment(0, 1)
+        copy.set_padding(0, 5)
+        hildon.hildon_helper_set_logical_font(copy, 'SmallSystemFont')
+        hildon.hildon_helper_set_logical_color(copy, gtk.RC_FG, gtk.STATE_NORMAL, "SecondaryTextColor")
+
+        layout = gtk.Table(3, 3, False)
+        layout.attach(icon, 0, 1, 0, 2, 0, gtk.EXPAND, 0, 0)
+        layout.attach(name, 1, 2, 0, 1, 0, gtk.EXPAND | gtk.FILL, 0, 0)
+        layout.attach(version, 2, 3, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0)
+        layout.attach(desc, 1, 3, 1, 2, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0)
+        layout.attach(copy, 0, 3, 2, 3, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0)
+        dlg.vbox.add(layout)
+
+        dlg.add_button(_('Visit website'), gtk.RESPONSE_APPLY)
+        dlg.add_button(_('Report bug'), gtk.RESPONSE_NO)
+        dlg.show_all()
+        response = dlg.run()
+        if response == gtk.RESPONSE_APPLY:
+            webbrowser.open('http://hermes.garage.maemo.org/')
+        elif response == gtk.RESPONSE_NO:
+            webbrowser.open('https://bugs.maemo.org/enter_bug.cgi?product=Hermes')
+        dlg.hide()
    
 
     # -----------------------------------------------------------------------
     def sync(self, widget, force, main = True):
-        if main and not self.get_use_facebook() and not self.get_use_twitter():
+        enabled = []
+        for provider in self.providers:
+            if self.gconf.get_bool('/apps/maemo/hermes/use_%s' % (provider.get_id())):
+                enabled.append(provider)
+                
+        if main and len(enabled) == 0:
             saved = self.do_accounts()
             if saved == gtk.RESPONSE_DELETE_EVENT:
                 return
+            
+        print "doing sync", main
         
         if main:
             self.main_window.set_property('sensitive', False)
             thread.start_new_thread(self.sync, (widget, force, False))
         else:
             try:
-                fb2c = Hermes(self,
-                              twitter = (self.get_use_twitter() and self.get_twitter_credentials()) or None,
-                              facebook = self.get_use_facebook(),
-                              empty = self.get_create_empty())
-                fb2c.load_friends()
-                fb2c.sync_contacts(resync = force)
-                gobject.idle_add(self.open_summary, fb2c)
+                self.progress('', 0, 0)
+                services = []
+                for provider in enabled:
+                    services.append(provider.service(self))
+                    
+                hermes = Hermes(services, self.progress)
+                hermes.run(force)
+                gobject.idle_add(self.open_summary, hermes)
         
             except urllib2.HTTPError, e:
                 traceback.print_exc()
@@ -159,6 +188,7 @@ class HermesGUI(WimpWorks):
         view.connect('contact-activated', self.map_contact, fb2c)
         dialog.vbox.add(view)
         dialog.show_all()
+        dialog.vbox.add(view.get_search())
       
         dialog.run()
         dialog.hide()
@@ -167,82 +197,99 @@ class HermesGUI(WimpWorks):
     # -----------------------------------------------------------------------
     def map_contact(self, widget, contact, fb2c):
         view = MapContact(fb2c.friends, contact)
-    
+
         dialog = gtk.Dialog(contact.get_name(), self.main_window)
         dialog.add_button(_('Update'), gtk.RESPONSE_OK)
         dialog.vbox.add(view)
         dialog.show_all()
+        dialog.vbox.add(view.get_search())
       
         result = dialog.run()
         dialog.hide()
         if result == gtk.RESPONSE_OK:
             friend = view.get_selected_friend()
             if friend:
-                if 'contact' in friend and friend['contact'] == contact:
+                if friend.get_contact() == contact:
                     hildon.hildon_banner_show_information(self.main_window, '', _("Removing existing mappings is not yet supported"))
                 elif view.contact_mapped:
-                    if fb2c.update_contact(contact, friend, True):
-                        fb2c.addresses.commit_contact(contact)
+                    fb2c.update_contact(contact, friend, True, True)
+                    widget.add_mapping(friend.get_source())
                 else:
-                    if fb2c.update_contact(contact, friend, False):
-                        fb2c.addresses.commit_contact(contact)
+                    fb2c.update_contact(contact, friend, False, True)
+                    widget.add_mapping(friend.get_source())
     
-      
+                        
     # -----------------------------------------------------------------------
     def need_auth(self, main = False):
+        """Part of the GUI callback API."""
+        
         if main:
-            hildon.hildon_banner_show_information(self.main_window, '', _("Need to authenticate with Facebook"))
+            hildon.hildon_banner_show_information(self.main_window, '', _("Need to authenticate via browser"))
         else:
             gobject.idle_add(self.need_auth, True)
       
     
     # -----------------------------------------------------------------------
-    def block_for_auth(self, main = False, lock = None):
+    def block_for_auth(self, prompt = False, main = False, lock = None):
+        """Part of the GUI callback API."""
+
         if main:
-            note = gtk.Dialog(_('Facebook authorisation'), self.main_window)
+            note = gtk.Dialog(_('Service authorisation'), self.main_window)
             note.add_button(_("Validate"), gtk.RESPONSE_OK)
-            note.vbox.add(gtk.Label(_("\nPress 'Validate' once Facebook has\nbeen authenticated in web browser.\n")))
+            if prompt:
+                input = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
+                input.set_property('is-focus', False)
+                note.set_title(_("Verification code from web browser"))
+                note.vbox.add(input)
+            else:
+                note.vbox.add(gtk.Label(_("\nPress 'Validate' once account has\nbeen authorised in web browser.\n")))
     
             note.show_all()
             result = note.run()
             note.hide()
             lock.release()
+            if prompt and result == gtk.RESPONSE_OK:
+                print input.get_text()
+                return input.get_text()
+            else:
+                return None
         
         else:
             time.sleep(2)
             lock = thread.allocate_lock()
             lock.acquire()
-            gobject.idle_add(self.block_for_auth, True, lock)
+            gobject.idle_add(self.block_for_auth, prompt, True, lock)
             lock.acquire()
             lock.release()
-    
-    
+                      
+                        
     # -----------------------------------------------------------------------
-    def progress(self, i, j, main = False):
+    def progress(self, msg, i, j, main = False):
+        """Part of the GUI callback API."""
+
         if main:
             if i == 0:
                 self.progressbar = gtk.ProgressBar()
-                self.progressnote = gtk.Dialog(_("Fetching friends' info"), self.main_window)
+                self.progressnote = gtk.Dialog(_("Initialising connections"), self.main_window)
                 self.progressnote.vbox.add(self.progressbar)
                 hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 1)
                
                 self.progressnote.show_all()
               
             elif i < j:
-                if i == 1:
-                    self.progressnote.set_title(_("Updating contacts"))
-                    hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 0)
+                self.progressnote.set_title(_(msg))
+                hildon.hildon_gtk_window_set_progress_indicator(self.progressnote, 0)
                 
                 self.progressbar.set_fraction(float(i) / float(j))
               
             else:
                 self.progressnote.destroy()
               
-            print i,j
+            print msg, i,j
         else:
-            gobject.idle_add(self.progress, i, j, True)
-    
-    
+            gobject.idle_add(self.progress, msg, i, j, True)
+
+       
     # -----------------------------------------------------------------------
     def report_error(self, e, prefs = False):
         if self.progressnote:
@@ -252,33 +299,3 @@ class HermesGUI(WimpWorks):
         hildon.hildon_banner_show_information(self.main_window, '', e)
         if prefs:
             self.do_accounts()
-    
-        
-    def get_use_facebook(self):
-        return self.gconf.get_bool("/apps/maemo/hermes/use_facebook")
-    
-    
-    def set_use_facebook(self, value):
-        self.gconf.set_bool("/apps/maemo/hermes/use_facebook", value)
-    
-    def get_create_empty(self):
-        return self.gconf.get_bool("/apps/maemo/hermes/create_empty")
-    
-    
-    def set_create_empty(self, value):
-        self.gconf.set_bool("/apps/maemo/hermes/create_empty", value)
-    
-    
-    def get_use_twitter(self):
-        return self.gconf.get_bool("/apps/maemo/hermes/use_twitter")
-    
-    
-    def set_use_twitter(self, value, user, password):
-        self.gconf.set_bool("/apps/maemo/hermes/use_twitter", value)
-        self.gconf.set_string("/apps/maemo/hermes/twitter_user", user)
-        self.gconf.set_string("/apps/maemo/hermes/twitter_pwd", password)
-      
-    
-    def get_twitter_credentials(self):
-        return (self.gconf.get_string("/apps/maemo/hermes/twitter_user") or '',
-                self.gconf.get_string("/apps/maemo/hermes/twitter_pwd") or '')