allow offline creation/recovery within the gui
authorthomasv <thomasv@gitorious>
Tue, 20 Nov 2012 14:30:46 +0000 (15:30 +0100)
committerthomasv <thomasv@gitorious>
Tue, 20 Nov 2012 14:30:46 +0000 (15:30 +0100)
electrum
lib/gui.py
lib/gui_qt.py
lib/interface.py

index 398669d..4256d29 100755 (executable)
--- a/electrum
+++ b/electrum
@@ -197,36 +197,49 @@ if __name__ == '__main__':
         else:
             sys.exit("Error: Unknown GUI: " + pref_gui )
 
+        gui = gui.ElectrumGui(wallet, config)
+        
         interface = Interface(config, True)
+        wallet.interface = interface
         interface.start()
         interface.send([('server.peers.subscribe',[])])
 
-        wallet.interface = interface
-        
-        gui = gui.ElectrumGui(wallet, config)
+        found = config.wallet_file_exists
+        if not found:
+            a = gui.restore_or_create()
+            if not a: exit()
+
+            if a =='create':
+                wallet.new_seed(None)
+                wallet.init_mpk( wallet.seed )
+            else:
+                # ask for seed and gap.
+                if not gui.seed_dialog(): exit()
+                wallet.init_mpk( wallet.seed )
+            
+            # select a server.
+            s = gui.network_dialog()
+            if s is None:
+                gui.create_wallet()
+
+
         interface.register_callback('peers', gui.server_list_changed)
 
         verifier = WalletVerifier(interface, config)
         wallet.set_verifier(verifier)
-
         WalletSynchronizer(wallet, config).start()
-        try:
-            found = config.wallet_file_exists
-            if not found:
-                found = gui.restore_or_create()
-        except SystemExit(e):
-            exit(e)
-        except BaseException(e):
-            import traceback
-            traceback.print_exc(file=sys.stdout)
-            #gui.show_message(e.message)
-            exit(1)
 
-        if not found:
-            exit(1)
+        if not found and a == 'restore' and s is not None:
+            try:
+                ok = gui.restore_wallet()
+            except:
+                import traceback
+                traceback.print_exc(file=sys.stdout)
+                exit()
 
-        verifier.start()
+            if not ok: exit()
 
+        verifier.start()
         gui.main(url)
         wallet.save()
         sys.exit(0)
index 7d5ea4f..c4f3d6f 100644 (file)
@@ -97,58 +97,8 @@ def restore_create_dialog(wallet):
     dialog.destroy()
 
     if r==2: return False
-        
-    is_recovery = (r==1)
-
-    # ask for the server.
-    if not run_network_dialog( wallet, parent=None ): return False
-
-    if not is_recovery:
-
-        wallet.new_seed(None)
-        # generate first key
-        wallet.init_mpk( wallet.seed )
-        wallet.up_to_date_event.clear()
-        wallet.update()
+    return 'restore' if r==1 else 'create'
 
-        # run a dialog indicating the seed, ask the user to remember it
-        show_seed_dialog(wallet, None, None)
-            
-        #ask for password
-        change_password_dialog(wallet, None, None)
-    else:
-        # ask for seed and gap.
-        run_recovery_dialog( wallet )
-
-        dialog = gtk.MessageDialog(
-            parent = None,
-            flags = gtk.DIALOG_MODAL, 
-            buttons = gtk.BUTTONS_CANCEL, 
-            message_format = "Please wait..."  )
-        dialog.show()
-
-        def recover_thread( wallet, dialog ):
-            wallet.init_mpk( wallet.seed ) # not encrypted at this point
-            wallet.up_to_date_event.clear()
-            wallet.update()
-
-            if wallet.is_found():
-                # history and addressbook
-                wallet.update_tx_history()
-                wallet.fill_addressbook()
-                print "Recovery successful"
-
-            gobject.idle_add( dialog.destroy )
-
-        thread.start_new_thread( recover_thread, ( wallet, dialog ) )
-        r = dialog.run()
-        dialog.destroy()
-        if r==gtk.RESPONSE_CANCEL: return False
-        if not wallet.is_found:
-            show_message("No transactions found for this seed")
-
-    wallet.save()
-    return True
 
 
 def run_recovery_dialog(wallet):
@@ -197,12 +147,13 @@ def run_recovery_dialog(wallet):
     dialog.destroy()
 
     if r==gtk.RESPONSE_CANCEL:
-        sys.exit(1)
+        return False
+
     try:
         gap = int(gap)
     except:
         show_message("error")
-        sys.exit(1)
+        return False
 
     try:
         seed.decode('hex')
@@ -211,11 +162,12 @@ def run_recovery_dialog(wallet):
         seed = mnemonic.mn_decode( seed.split(' ') )
     if not seed:
         show_message("no seed")
-        sys.exit(1)
+        return False
         
     wallet.seed = seed
     wallet.gap_limit = gap
     wallet.save()
+    return True
 
 
 
@@ -328,7 +280,7 @@ def run_network_dialog( wallet, parent ):
             status = "Not connected"
     else:
         import random
-        status = "Please choose a server."
+        status = "Please choose a server.\nSelect cancel if you are offline."
 
     server = interface.server
     plist, servers_list = interface.get_servers_list()
@@ -575,6 +527,7 @@ class ElectrumWindow:
         self.window.set_border_width(0)
         self.window.connect('mykeypress', gtk.main_quit)
         self.window.set_default_size(720, 350)
+        self.wallet_updated = False
 
         vbox = gtk.VBox()
 
@@ -651,7 +604,6 @@ class ElectrumWindow:
         self.context_id = self.status_bar.get_context_id("statusbar")
         self.update_status_bar()
 
-        self.wallet_updated = False
         self.wallet.interface.register_callback('updated', self.update_callback)
 
 
@@ -1302,3 +1254,57 @@ class ElectrumGui():
 
     def server_list_changed(self):
         pass
+
+    def seed_dialog(self):
+        # ask for seed and gap.
+        return run_recovery_dialog( self.wallet )
+
+    def network_dialog(self):
+        return run_network_dialog( self.wallet, parent=None )
+
+    def create_wallet(self):
+        wallet = self.wallet
+        wallet.new_seed(None)
+        # generate first key
+        wallet.init_mpk( wallet.seed )
+        wallet.synchronize()
+        #wallet.up_to_date_event.clear()
+        #wallet.update()
+        # run a dialog indicating the seed, ask the user to remember it
+        show_seed_dialog(wallet, None, None)
+        #ask for password
+        change_password_dialog(wallet, None, None)
+
+    def restore_wallet(self):
+        wallet = self.wallet
+
+        dialog = gtk.MessageDialog(
+            parent = None,
+            flags = gtk.DIALOG_MODAL, 
+            buttons = gtk.BUTTONS_CANCEL, 
+            message_format = "Please wait..."  )
+        dialog.show()
+        wallet.save()
+
+        def recover_thread( wallet, dialog ):
+            wallet.init_mpk( wallet.seed ) # not encrypted at this point
+            wallet.up_to_date_event.clear()
+            wallet.update()
+
+            if wallet.is_found():
+                # history and addressbook
+                wallet.update_tx_history()
+                wallet.fill_addressbook()
+                print "Recovery successful"
+
+            gobject.idle_add( dialog.destroy )
+
+        thread.start_new_thread( recover_thread, ( wallet, dialog ) )
+        r = dialog.run()
+        dialog.destroy()
+        if r==gtk.RESPONSE_CANCEL: return False
+        if not wallet.is_found:
+            show_message("No transactions found for this seed")
+
+        wallet.save()
+        return True
index 0af1984..f765bdc 100644 (file)
@@ -1367,11 +1367,13 @@ class ElectrumWindow(QMainWindow):
                 status = _("Connected to")+" %s\n%d blocks"%(interface.host, wallet.verifier.height)
             else:
                 status = _("Not connected")
+            server = interface.server
         else:
             import random
-            status = _("Please choose a server.")
+            status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.")
+            server = None
+            interface.proxy = None
 
-        server = interface.server
         plist, servers_list = interface.get_servers_list()
 
         d = QDialog(parent)
@@ -1414,8 +1416,6 @@ class ElectrumWindow(QMainWindow):
         grid.addWidget(server_host, 0, 2)
         grid.addWidget(server_port, 0, 3)
 
-        host, port, protocol = server.split(':')
-
         def change_protocol(p):
             protocol = protocol_letters[p]
             host = unicode(server_host.text())
@@ -1465,7 +1465,10 @@ class ElectrumWindow(QMainWindow):
                     server_protocol.model().setData(j, QtCore.QVariant(0,False), QtCore.Qt.UserRole-1)
 
 
-        change_server(host,protocol)
+        if server:
+            host, port, protocol = server.split(':')
+            change_server(host,protocol)
+
         servers_list_widget.connect(servers_list_widget, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), lambda x: change_server(unicode(x.text(0))))
         grid.addWidget(servers_list_widget, 1, 1, 1, 3)
 
@@ -1541,16 +1544,30 @@ class ElectrumGui:
 
 
     def restore_or_create(self):
-
         msg = _("Wallet file not found.")+"\n"+_("Do you want to create a new wallet, or to restore an existing one?")
         r = QMessageBox.question(None, _('Message'), msg, _('Create'), _('Restore'), _('Cancel'), 0, 2)
-        if r==2: return False
+        if r==2: return None
+        return 'restore' if r==1 else 'create'
+
+    def seed_dialog(self):
+        return ElectrumWindow.seed_dialog( self.wallet )
+
+    def network_dialog(self):
+        return ElectrumWindow.network_dialog( self.wallet, parent=None )
         
-        is_recovery = (r==1)
+    def create_wallet(self):
         wallet = self.wallet
-        # ask for the server.
-        if not ElectrumWindow.network_dialog( wallet, parent=None ): return False
+        # generate the first addresses
+        wallet.synchronize()
+        # run a dialog indicating the seed, ask the user to remember it
+        ElectrumWindow.show_seed_dialog(wallet)
+        # ask for password
+        ElectrumWindow.change_password_dialog(wallet)
+        wallet.save()
 
+
+    def restore_wallet(self):
+        wallet = self.wallet
         # wait until we are connected, because the user might have selected another server
         if not wallet.interface.is_connected:
             waiting = lambda: False if wallet.interface.is_connected else "connecting...\n"
@@ -1559,32 +1576,18 @@ class ElectrumGui:
         waiting = lambda: False if wallet.up_to_date else "Please wait...\nAddresses generated: %d\nKilobytes received: %.1f"\
             %(len(wallet.all_addresses()), wallet.interface.bytes_received/1024.)
 
-        if not is_recovery:
-            wallet.new_seed(None)
-            wallet.init_mpk( wallet.seed )
-            wallet.up_to_date_event.clear()
-            wallet.up_to_date = False
-            wallet.interface.poke('synchronizer')
-            waiting_dialog(waiting)
-            # run a dialog indicating the seed, ask the user to remember it
-            ElectrumWindow.show_seed_dialog(wallet)
-            #ask for password
-            ElectrumWindow.change_password_dialog(wallet)
+        wallet.up_to_date_event.clear()
+        wallet.up_to_date = False
+        wallet.interface.poke('synchronizer')
+        waiting_dialog(waiting)
+        if wallet.is_found():
+            # history and addressbook
+            wallet.fill_addressbook()
+            print "Recovery successful"
+            wallet.save()
         else:
-            # ask for seed and gap.
-            if not ElectrumWindow.seed_dialog( wallet ): return False
-            wallet.init_mpk( wallet.seed )
-            wallet.up_to_date_event.clear()
-            wallet.up_to_date = False
-            wallet.interface.poke('synchronizer')
-            waiting_dialog(waiting)
-            if wallet.is_found():
-                # history and addressbook
-                wallet.fill_addressbook()
-                print "Recovery successful"
-                wallet.save()
-            else:
-                QMessageBox.information(None, _('Error'), _("No transactions found for this seed"), _('OK'))
+            QMessageBox.information(None, _('Error'), _("No transactions found for this seed"), _('OK'))
+            return False
 
         wallet.save()
         return True
index 43ee64f..8ca7947 100644 (file)
@@ -352,6 +352,8 @@ class Interface(threading.Thread):
 
 
     def __init__(self, config=None, loop=False):
+        self.server = None
+        self.proxy = None
 
         if config is None:
             from simple_config import SimpleConfig