don't show gap limit in GUI
[electrum-nvc.git] / gui / gui_classic / installwizard.py
1 from PyQt4.QtGui import *
2 from PyQt4.QtCore import *
3 import PyQt4.QtCore as QtCore
4
5 from electrum.i18n import _
6 from electrum import Wallet, mnemonic
7
8 from seed_dialog import SeedDialog
9 from network_dialog import NetworkDialog
10 from qt_util import *
11 from amountedit import AmountEdit
12
13 import sys
14
15 class InstallWizard(QDialog):
16
17     def __init__(self, config, network, storage):
18         QDialog.__init__(self)
19         self.config = config
20         self.network = network
21         self.storage = storage
22
23
24     def restore_or_create(self):
25
26         d = QDialog()
27         d.setModal(1)
28
29         grid = QGridLayout()
30         grid.setSpacing(5)
31
32         msg = _("Wallet file not found.")+"\n"+_("Do you want to create a new wallet, or to restore an existing one?")
33         label = QLabel(msg)
34         label.setWordWrap(True)
35         grid.addWidget(label, 0, 0)
36
37         gb = QGroupBox()
38
39         b1 = QRadioButton(gb)
40         b1.setText(_("Create new wallet"))
41         b1.setChecked(True)
42
43         b2 = QRadioButton(gb)
44         b2.setText(_("Restore wallet from seed"))
45
46         b3 = QRadioButton(gb)
47         b3.setText(_("Restore wallet from master public key"))
48
49         grid.addWidget(b1,1,0)
50         grid.addWidget(b2,2,0)
51         grid.addWidget(b3,3,0)
52
53         vbox = QVBoxLayout()
54         vbox.addLayout(grid)
55         vbox.addLayout(ok_cancel_buttons(d, _('Next')))
56         d.setLayout(vbox) 
57
58         if not d.exec_():
59             return
60         
61         if b1.isChecked():
62             return 'create'
63         elif b2.isChecked():
64             return 'restore'
65         else:
66             return 'watching'
67
68
69
70     def verify_seed(self, wallet):
71         r = self.seed_dialog(False)
72         if not r:
73             return
74
75         if r != wallet.seed:
76             QMessageBox.warning(None, _('Error'), 'incorrect seed', 'OK')
77             return False
78         else:
79             return True
80
81
82     def seed_dialog(self, is_restore=True):
83         d = QDialog()
84         d.setModal(1)
85
86         vbox = QVBoxLayout()
87         if is_restore:
88             msg = _("Please enter your wallet seed (or your master public key if you want to create a watching-only wallet)." + ' ')
89         else:
90             msg = _("Your seed is important! To make sure that you have properly saved your seed, please type it here." + ' ')
91
92         msg += _("Your seed can be entered as a sequence of words, or as a hexadecimal string."+ '\n')
93         
94         label=QLabel(msg)
95         label.setWordWrap(True)
96         vbox.addWidget(label)
97
98         seed_e = QTextEdit()
99         seed_e.setMaximumHeight(100)
100         vbox.addWidget(seed_e)
101
102         vbox.addLayout(ok_cancel_buttons(d, _('Next')))
103         d.setLayout(vbox) 
104
105         if not d.exec_(): return
106
107         try:
108             seed = str(seed_e.toPlainText())
109             seed.decode('hex')
110         except:
111             try:
112                 seed = mnemonic.mn_decode( seed.split() )
113             except:
114                 QMessageBox.warning(None, _('Error'), _('I cannot decode this'), _('OK'))
115                 return
116
117         if not seed:
118             QMessageBox.warning(None, _('Error'), _('No seed'), _('OK'))
119             return
120
121         return seed
122
123
124
125     def mpk_dialog(self):
126         d = QDialog()
127         d.setModal(1)
128
129         vbox = QVBoxLayout()
130         msg = _("Please enter your master public key.")
131
132         label=QLabel(msg)
133         label.setWordWrap(True)
134         vbox.addWidget(label)
135
136         mpk_e = QTextEdit()
137         mpk_e.setMaximumHeight(100)
138         vbox.addWidget(mpk_e)
139
140         grid = QGridLayout()
141         grid.setSpacing(8)
142         vbox.addLayout(grid)
143
144         vbox.addLayout(ok_cancel_buttons(d, _('Next')))
145         d.setLayout(vbox) 
146
147         if not d.exec_(): return
148
149         mpk = str(mpk_e.toPlainText())
150         return mpk
151
152
153     def network_dialog(self):
154         
155         d = QDialog()
156         d.setModal(1)
157
158         grid = QGridLayout()
159         grid.setSpacing(5)
160
161         label = QLabel(_("Network") + ":")
162         grid.addWidget(label, 0, 0)
163
164         gb = QGroupBox()
165
166         b1 = QRadioButton(gb)
167         b1.setText(_("Auto connect"))
168         b1.setChecked(True)
169
170         b2 = QRadioButton(gb)
171         b2.setText(_("Select server manually"))
172
173         b3 = QRadioButton(gb)
174         b3.setText(_("Stay offline"))
175
176         grid.addWidget(b1,1,0)
177         grid.addWidget(b2,2,0)
178         grid.addWidget(b3,3,0)
179
180         vbox = QVBoxLayout()
181         vbox.addLayout(grid)
182         vbox.addLayout(ok_cancel_buttons(d, _('Next')))
183         d.setLayout(vbox) 
184
185         if not d.exec_():
186             return
187         
188         if b2.isChecked():
189             return NetworkDialog(self.network, self.config, None).do_exec()
190
191         elif b1.isChecked():
192             self.config.set_key('auto_cycle', True, True)
193             return
194
195         else:
196             self.config.set_key("server", None, True)
197             self.config.set_key('auto_cycle', False, True)
198             return
199         
200         
201
202     def show_seed(self, wallet):
203         d = SeedDialog()
204         d.show_seed(wallet.seed, wallet.imported_keys)
205
206
207     def password_dialog(self, wallet):
208         from password_dialog import PasswordDialog
209         d = PasswordDialog(wallet)
210         d.run()
211
212
213     def restore_wallet(self, wallet):
214
215         # wait until we are connected, because the user might have selected another server
216         if not self.network.interface.is_connected:
217             waiting = lambda: False if self.network.interface.is_connected else "%s \n" % (_("Connecting..."))
218             waiting_dialog(waiting)
219
220         waiting = lambda: False if wallet.is_up_to_date() else "%s\n%s %d\n%s %.1f"\
221             %(_("Please wait..."),_("Addresses generated:"),len(wallet.addresses(True)),_("Kilobytes received:"), self.network.interface.bytes_received/1024.)
222
223         # try to restore old account
224         wallet.create_old_account()
225         wallet.set_up_to_date(False)
226         waiting_dialog(waiting)
227
228         if wallet.is_found():
229             wallet.seed_version = 4
230             wallet.storage.put('seed_version', wallet.seed_version, True)
231         else:
232             wallet.accounts.pop(0)
233             wallet.create_accounts()
234             wallet.set_up_to_date(False)
235             waiting_dialog(waiting)
236
237         if wallet.is_found():
238             QMessageBox.information(None, _('Information'), _("Recovery successful"), _('OK'))
239         else:
240             QMessageBox.information(None, _('Information'), _("No transactions found for this seed"), _('OK'))
241
242         return True
243
244
245     def run(self):
246
247         action = self.restore_or_create()
248         if not action: exit()
249
250         wallet = Wallet(self.storage)
251         gap = self.config.get('gap_limit',5)
252         if gap !=5:
253             wallet.gap_limit = gap
254             wallet.storage.put('gap_limit', gap,True)
255
256         if action == 'create':
257             wallet.init_seed(None)
258             self.show_seed(wallet)
259             if self.verify_seed(wallet):
260                 wallet.save_seed()
261                 wallet.create_accounts()
262                 # generate first addresses offline
263                 wallet.synchronize()
264             else:
265                 return
266                 
267         elif action == 'restore':
268             # ask for seed and gap.
269             seed = self.seed_dialog()
270             if not seed:
271                 return
272             wallet.init_seed(str(seed))
273             wallet.save_seed()
274
275         elif action == 'watching':
276             # ask for seed and gap.
277             mpk = self.mpk_dialog()
278             if not mpk:
279                 return
280             wallet.seed = ''
281
282             print eval(mpk)
283             try:
284                 c0, K0 = eval(mpk)
285             except:
286                 QMessageBox.warning(None, _('Error'), _('error'), _('OK'))
287                 return
288             wallet.create_watching_only_wallet(c0,K0)
289
290
291         else: raise
292                 
293         #if not self.config.get('server'):
294         self.network_dialog()
295
296         # start wallet threads
297         wallet.start_threads(self.network)
298
299         if action == 'restore':
300             try:
301                 keep_it = self.restore_wallet(wallet)
302                 wallet.fill_addressbook()
303             except:
304                 import traceback
305                 traceback.print_exc(file=sys.stdout)
306                 exit()
307
308             if not keep_it: return
309
310         self.password_dialog(wallet)
311         
312         return wallet