electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit d2711ac757c142253718b117d48a2f93afa1c0c7
parent 60bac7257e04a05b8afbbd9e8db083bd2d284924
Author: thomasv <thomasv@gitorious>
Date:   Tue, 30 Oct 2012 14:56:16 +0100

popup windows, selectors

Diffstat:
Mlib/gui_text.py | 222++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 169 insertions(+), 53 deletions(-)

diff --git a/lib/gui_text.py b/lib/gui_text.py @@ -1,8 +1,11 @@ import curses, datetime from decimal import Decimal +_ = lambda x:x +#from i18n import _ from util import format_satoshis, set_verbosity -WIDTH=150 + +EMPTY = " "*15 class ElectrumGui: @@ -10,14 +13,35 @@ class ElectrumGui: self.wallet = wallet self.config = config self.stdscr = curses.initscr() + + #c = self.stdscr.getch() + #print c + curses.noecho() curses.cbreak() - curses.start_color() + #curses.start_color() self.stdscr.keypad(1) self.stdscr.border(0) self.maxy, self.maxx = self.stdscr.getmaxyx() set_verbosity(False) self.tab = 0 + self.pos = 0 + self.popup_pos = 0 + self.w = None + self.is_popup = False + + self.str_recipient = EMPTY + self.str_description = EMPTY + self.str_amount = EMPTY + self.str_fee = EMPTY + + self.wallet.interface.register_callback('updated', self.refresh) + self.wallet.interface.register_callback('connected', self.refresh) + self.wallet.interface.register_callback('disconnected', self.refresh) + self.wallet.interface.register_callback('disconnecting', self.refresh) + self.tab_names = [_("History"), _("Send"), _("Receive"), _("Contacts"), _("Wall")] + self.num_tabs = len(self.tab_names) + curses.curs_set(0) def server_list_changed(self): pass @@ -26,38 +50,50 @@ class ElectrumGui: pass def print_history(self): + width = [20, 40, 14, 14] + delta = (self.maxx - sum(width) - 4)/3 + format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" + b = 0 messages = [] - for line in self.wallet.get_tx_history(): - v = line['value'] + for tx in self.wallet.get_tx_history(): + v = tx['value'] b += v try: - time_str = str( datetime.datetime.fromtimestamp( line['timestamp'])) + time_str = str( datetime.datetime.fromtimestamp( tx['timestamp'])) except: - print line['timestamp'] + print tx['timestamp'] time_str = 'pending' - label = line.get('label') - if not label: label = line['tx_hash'] - else: label = label + ' '*(64 - len(label) ) - messages.append( time_str + " " + label + " " + format_satoshis(v)+ " "+ format_satoshis(b) ) + tx_hash = tx['tx_hash'] - self.print_list(messages, "%19s %64s %14s %10s"%("Date", "Description", "Amount", "Balance")) + label = self.wallet.labels.get(tx_hash) + is_default_label = (label == '') or (label is None) + if is_default_label: label = tx['default_label'] + + #label += ' '*(40 - len(label) ) + messages.append( format_str%( time_str, label, format_satoshis(v), format_satoshis(b) ) ) + + self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance"))) def print_balance(self): - c, u = self.wallet.get_balance() - msg = "Balance: %f"%(Decimal( c ) / 100000000) - if u: - msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000) - self.stdscr.addstr( self.maxy -3, 2, msg) - - tab_names = ["History", "Send", "Receive", "Contacts"] - for i in range(4): - self.stdscr.addstr( 0, 2+9*i, tab_names[i], curses.A_BOLD if self.tab == i else 0) + if self.wallet.interface and self.wallet.interface.is_connected: + if not self.wallet.up_to_date: + msg = _( "Synchronizing..." ) + else: + c, u = self.wallet.get_balance() + msg = _("Balance")+": %f "%(Decimal( c ) / 100000000) + if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000) + else: + msg = _( "Not connected" ) - self.stdscr.addstr( self.maxy -1, self.maxx-30, " Settings Network Quit ") + self.stdscr.addstr( self.maxy -1, 3, msg) + + for i in range(self.num_tabs): + self.stdscr.addstr( 0, 2 + 2*i + len(''.join(self.tab_names[0:i])), self.tab_names[i], curses.A_BOLD if self.tab == i else 0) + + self.stdscr.addstr( self.maxy -1, self.maxx-30, ' '.join([_("Settings"), _("Network"), _("Quit")])) - def print_contacts(self): messages = map(lambda addr: "%30s %30s "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addressbook) @@ -69,28 +105,52 @@ class ElectrumGui: def print_send_dialog(self): self.stdscr.clear() - self.stdscr.addstr( 3, 2, "Pay to") - self.stdscr.addstr( 5, 2, "Description") - self.stdscr.addstr( 7, 2, "Amount") - self.stdscr.addstr( 9, 2, "Fee") - return - - while True: - curses.echo() - s = self.stdscr.getstr(3, 15) - curses.noecho() + self.stdscr.addstr( 3, 2, _("Pay to")) + self.stdscr.addstr( 3, 15, self.str_recipient, curses.A_REVERSE if self.pos%5==0 else 0) - if s: break - pass + self.stdscr.addstr( 5, 2, _("Description")) + self.stdscr.addstr( 5, 15, self.str_description, curses.A_REVERSE if self.pos%5==1 else 0) + + self.stdscr.addstr( 7, 2, _("Amount")) + self.stdscr.addstr( 7, 15, self.str_amount, curses.A_REVERSE if self.pos%5==2 else 0) + self.stdscr.addstr( 9, 2, _("Fee")) + self.stdscr.addstr( 9, 15, self.str_fee, curses.A_REVERSE if self.pos%5==3 else 0) + + self.stdscr.addstr( 11, 15, _("Send"), curses.A_REVERSE if self.pos%5==4 else 0) + + def exec_send(self): + curses.curs_set(1) + curses.echo() + if self.pos%5==0: + s = self.stdscr.getstr(3, 15) + if s: self.str_recipient = s + elif self.pos%5==1: + s = self.stdscr.getstr(5, 15) + if s: self.str_description = s + elif self.pos%5==2: + s = self.stdscr.getstr(7, 15) + if s: self.str_amount = s + elif self.pos%5==3: + s = self.stdscr.getstr(9, 15) + if s: self.str_fee = s + else: + pass + curses.noecho() + curses.curs_set(0) + self.print_send_dialog() + + def print_banner(self): + self.stdscr.clear() + self.stdscr.addstr( 1, 1, self.wallet.banner ) def print_list(self, list, firstline): firstline += " "*(self.maxx -2 - len(firstline)) self.stdscr.addstr( 1, 1, firstline ) - for i in range(self.maxy-6): + for i in range(self.maxy-4): msg = list[i] if i < len(list) else "" - msg += " "*(self.maxx -2 - len(msg)) - self.stdscr.addstr( i+2, 1, msg[0:self.maxx - 2]) + msg += " "*(self.maxx - 2 - len(msg)) + self.stdscr.addstr( i+2, 1, msg[0:self.maxx - 2], curses.A_REVERSE if i == (self.pos % len(list)) else 0) def refresh(self): self.stdscr.border(0) @@ -101,25 +161,61 @@ class ElectrumGui: self.print_history() self.refresh() + self.is_popup = False while 1: c = self.stdscr.getch() - if c == curses.KEY_RIGHT: self.tab = (self.tab + 1)%4 - if c == curses.KEY_LEFT: self.tab = (self.tab - 1)%4 - elif c == ord('h'): self.tab = 0 - elif c == ord('s'): self.tab = 1 - elif c == ord('r'): self.tab = 2 - elif c == ord('c'): self.tab = 3 - elif c == ord('q'): break - elif c == curses.KEY_HOME: x = y = 0 - - if self.tab == 0: - self.print_history() - elif self.tab == 1: - self.print_send_dialog() - elif self.tab == 2: - self.print_receive() + + if not self.is_popup: + if c == curses.KEY_RIGHT: self.tab = (self.tab + 1)%self.num_tabs + elif c == curses.KEY_LEFT: self.tab = (self.tab - 1)%self.num_tabs + elif c == ord('h'): self.tab = 0 + elif c == ord('s'): self.tab = 1 + elif c == ord('r'): self.tab = 2 + elif c == ord('c'): self.tab = 3 + + elif c == curses.KEY_DOWN: self.pos +=1 + elif c == curses.KEY_UP: self.pos -= 1 + elif c == 9: self.pos +=1 # tab + + elif c in [27, ord('q')]: break + elif c == 10: self.is_popup = True + + elif c == ord('n'): self.network_dialog() + elif c == ord('s'): self.settings_dialog() + else: - self.print_contacts() + if c == 10: self.is_popup = False + elif c == 27: self.is_popup = False + elif c == curses.KEY_UP: self.popup_pos -= 1 + elif c == curses.KEY_DOWN: self.popup_pos +=1 + #else: raise BaseException("zz %d"%c) + + if self.is_popup: + if self.tab == 0: + self.context_popup('',["blah","foo"]) + elif self.tab == 1 and self.pos%5==4: + self.context_popup('Pay?',["Pay","Cancel"]) + elif self.tab == 2: + self.context_popup('', ["blah"]) + elif self.tab == 3: + self.context_popup('', ["Pay to"]) + else: + self.exec_send() + self.is_popup = False + #self.print_send_dialog() + + else: + if self.tab == 0: + self.print_history() + elif self.tab == 1: + self.print_send_dialog() + elif self.tab == 2: + self.print_receive() + elif self.tab == 3: + self.print_contacts() + else: + self.print_banner() + self.refresh() curses.nocbreak(); @@ -127,3 +223,23 @@ class ElectrumGui: curses.echo() curses.endwin() + def context_popup(self, text, items): + if not self.w: self.w = curses.newwin(10, 30, 5, 5) + w = self.w + w.clear() + w.border(0) + + w.addstr( 2,2,text) + + for i in range(len(items)): + item = items[i] + w.addstr( 4 + 2*i, 2, item, curses.A_REVERSE if self.popup_pos%(len(items))==i else 0) + + + w.refresh() + + def network_dialog(self): + pass + + def settings_dialog(self): + pass