tkivy: invoices and requests handlers - electrum - Electrum Bitcoin wallet (HTM) git clone https://git.parazyd.org/electrum (DIR) Log (DIR) Files (DIR) Refs (DIR) Submodules --- (DIR) commit eef62112a83345d268cb7e7fd955e73c26429c5e (DIR) parent 6bd37723d3ddf89e9e34236ee07324c02ef1df14 (HTM) Author: ThomasV <thomasv@electrum.org> Date: Sat, 12 Dec 2015 23:23:58 +0100 kivy: invoices and requests handlers Diffstat: M gui/kivy/main_window.py | 99 ++++++++++--------------------- M gui/kivy/uix/context_menu.py | 2 +- M gui/kivy/uix/screens.py | 39 +++++++++++++++++++------------ M gui/kivy/uix/ui_screens/history.kv | 2 +- M gui/kivy/uix/ui_screens/invoices.kv | 5 +---- M gui/kivy/uix/ui_screens/receive.kv | 2 +- M gui/kivy/uix/ui_screens/requests.kv | 5 +---- 7 files changed, 61 insertions(+), 93 deletions(-) --- (DIR) diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py t@@ -13,6 +13,7 @@ from electrum.paymentrequest import InvoiceStore from electrum.util import profiler, InvalidPassword from electrum.plugins import run_hook from electrum.util import format_satoshis, format_satoshis_plain +from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED from kivy.app import App from kivy.core.window import Window t@@ -164,6 +165,9 @@ class ElectrumWindow(App): self.nfcscanner = None self.tabs = None + self.receive_address = None + self.current_invoice = None + super(ElectrumWindow, self).__init__(**kwargs) title = _('Electrum App') t@@ -191,19 +195,31 @@ class ElectrumWindow(App): self._trigger_notify_transactions = \ Clock.create_trigger(self.notify_transactions, 5) + def get_receive_address(self): + return self.receive_address if self.receive_address else self.wallet.get_unused_address(None) + + def do_pay(self, obj): + pr = self.invoices.get(obj.key) + self.on_pr(pr) + def on_pr(self, pr): - from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED if pr.verify(self.contacts): key = self.invoices.add(pr) status = self.invoices.get_status(key) #self.invoices_screen.update() if status == PR_PAID: - self.show_message("invoice already paid") + self.show_error("invoice already paid") self.send_screen.do_clear() else: - self.send_screen.set_request(pr) + if pr.has_expired(): + self.show_error(_('Payment request has expired')) + else: + self.current_pr = pr + self.update_screen('send') + send_tab = self.tabs.ids.send_tab + self.tabs.ids.panel.switch_to(send_tab) else: - self.show_message("invoice error:" + pr.error) + self.show_error("invoice error:" + pr.error) self.send_screen.do_clear() def set_URI(self, url): t@@ -214,6 +230,17 @@ class ElectrumWindow(App): return self.send_screen.set_URI(url) + def update_screen(self, name): + s = getattr(self, name + '_screen', None) + if s: + s.update() + + def show_request(self, addr): + self.receive_address = addr + self.update_screen('receive') + receive_tab = self.tabs.ids.receive_tab + self.tabs.ids.panel.switch_to(receive_tab) + req = self.wallet.receive_requests.get(addr) def scan_qr(self, on_complete): from jnius import autoclass t@@ -412,6 +439,7 @@ class ElectrumWindow(App): self.network.register_callback(self.on_network, interests) self.wallet = None + self.tabs = self.root.ids['tabs'] def on_network(self, event, *args): if event == 'updated': t@@ -603,64 +631,10 @@ class ElectrumWindow(App): else: self.show_error(_('Invalid Address')) - def send_payment(self, address, amount=0, label='', message=''): - tabs = self.tabs - screen_send = tabs.ids.screen_send - - if label and self.wallet.labels.get(address) != label: - #if self.question('Give label "%s" to address %s ?'%(label,address)): - if address not in self.wallet.addressbook and not self.wallet. is_mine(address): - self.wallet.addressbook.append(address) - self.wallet.set_label(address, label) - - # switch_to the send screen - tabs.ids.panel.switch_to(tabs.ids.tab_send) - - label = self.wallet.labels.get(address) - m_addr = label + ' <'+ address +'>' if label else address - - # populate - def set_address(*l): - content = screen_send.ids - content.payto_e.text = m_addr - content.message_e.text = message - if amount: - content.amount_e.text = amount - - # wait for screen to load - Clock.schedule_once(set_address, .5) def set_send(self, address, amount, label, message): self.send_payment(address, amount=amount, label=label, message=message) - def prepare_for_payment_request(self): - tabs = self.tabs - screen_send = tabs.ids.screen_send - - # switch_to the send screen - tabs.ids.panel.switch_to(tabs.ids.tab_send) - - content = screen_send.ids - if content: - self.set_frozen(content, False) - screen_send.screen_label.text = _("please wait...") - return True - - def payment_request_ok(self): - tabs = self.tabs - screen_send = tabs.ids.screen_send - - # switch_to the send screen - tabs.ids.panel.switch_to(tabs.ids.tab_send) - - self.set_frozen(content, True) - - screen_send.ids.payto_e.text = self.gui_object.payment_request.domain - screen_send.ids.amount_e.text = self.format_amount(self.gui_object.payment_request.get_amount()) - screen_send.ids.message_e.text = self.gui_object.payment_request.memo - - # wait for screen to load - Clock.schedule_once(set_address, .5) def set_frozen(self, entry, frozen): if frozen: t@@ -670,15 +644,6 @@ class ElectrumWindow(App): entry.disabled = False Factory.Animation(opacity=1).start(content) - def payment_request_error(self): - tabs = self.tabs - screen_send = tabs.ids.screen_send - - # switch_to the send screen - tabs.ids.panel.switch_to(tabs.ids.tab_send) - - self.do_clear() - self.show_info(self.gui_object.payment_request.error) def show_error(self, error, width='200dp', pos=None, arrow_pos=None, exit=False, icon='atlas://gui/kivy/theming/light/error', duration=0, (DIR) diff --git a/gui/kivy/uix/context_menu.py b/gui/kivy/uix/context_menu.py t@@ -39,5 +39,5 @@ class ContextMenu(Bubble): for k, v in action_list: l = MenuItem() l.text = k - l.on_release = lambda: v(obj) + l.on_release = lambda f=v: f(obj) self.ids.buttons.add_widget(l) (DIR) diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py t@@ -208,6 +208,10 @@ class SendScreen(CScreen): amount_str = str( Decimal(amount) / pow(10, self.app.decimal_point())) self.screen.amount = amount_str + ' ' + self.app.base_unit + def update(self): + if self.app.current_invoice: + self.set_request(self.app.current_invoice) + def do_clear(self): self.screen.amount = '' self.screen.message = '' t@@ -215,9 +219,6 @@ class SendScreen(CScreen): self.payment_request = None def set_request(self, pr): - if pr.has_expired(): - self.app.show_error(_('Payment request has expired')) - return self.payment_request = pr self.screen.address = pr.get_requestor() self.screen.amount = self.app.format_amount(pr.get_amount()) t@@ -283,7 +284,13 @@ class ReceiveScreen(CScreen): kvname = 'receive' def update(self): - self.screen.address = self.app.wallet.get_unused_address(None) + addr = self.app.get_receive_address() + self.screen.address = addr + req = self.app.wallet.receive_requests.get(addr) + if req: + self.screen.message = req.get('memo') + self.screen.amount = self.app.format_amount(req.get('amount')) + ' ' + self.app.base_unit + def amount_callback(self, popup): amount_label = self.screen.ids.get('amount') t@@ -320,8 +327,10 @@ class ReceiveScreen(CScreen): req = self.app.wallet.make_payment_request(addr, amount, message, None) self.app.wallet.add_payment_request(req, self.app.electrum_config) self.app.show_error(_('Request saved')) + self.app.update_screen('requests') def do_clear(self): + self.app.receive_address = None self.screen.amount = '' self.screen.message = '' self.update() t@@ -376,18 +385,19 @@ class InvoicesScreen(CScreen): ci.screen = self invoices_list.add_widget(ci) - def do_pay(self, x): - pass + def do_pay(self, obj): + self.app.do_pay(obj) - def do_delete(self, x): - pass + def do_delete(self, obj): + self.app.invoices.remove(obj.key) + self.app.update_screen('invoices') class RequestsScreen(CScreen): kvname = 'requests' def update(self): - self.menu_actions = [(_('View'), self.do_view), (_('Delete'), self.do_delete)] + self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)] requests_list = self.screen.ids.requests_container requests_list.clear_widgets() t@@ -408,13 +418,12 @@ class RequestsScreen(CScreen): ci.screen = self requests_list.add_widget(ci) + def do_show(self, obj): + self.app.show_request(obj.address) - def do_view(self, o): - print o - - def do_delete(self, o): - print o - + def do_delete(self, obj): + self.app.wallet.remove_payment_request(obj.address, self.app.electrum_config) + self.update() class CSpinner(Factory.Spinner): (DIR) diff --git a/gui/kivy/uix/ui_screens/history.kv b/gui/kivy/uix/ui_screens/history.kv t@@ -99,4 +99,4 @@ HistoryScreen: size_hint: 1, None height: self.minimum_height padding: '12dp' - spacing: '12dp' + spacing: '2dp' (DIR) diff --git a/gui/kivy/uix/ui_screens/invoices.kv b/gui/kivy/uix/ui_screens/invoices.kv t@@ -19,9 +19,6 @@ InvoicesScreen: name: 'invoices' - on_activate: - if not self.action_view:\ - self.action_view = app.root.main_screen.ids.tabs.ids.screen_dashboard.action_view BoxLayout: orientation: 'vertical' spacing: '1dp' t@@ -37,5 +34,5 @@ InvoicesScreen: id: invoices_container size_hint: 1, None height: self.minimum_height - spacing: '1dp' + spacing: '2dp' padding: '12dp' (DIR) diff --git a/gui/kivy/uix/ui_screens/receive.kv b/gui/kivy/uix/ui_screens/receive.kv t@@ -89,7 +89,7 @@ ReceiveScreen: height: '48dp' on_release: s.parent.do_copy() Button: - text: _('Clear') + text: _('New') size_hint: 1, None height: '48dp' on_release: s.parent.do_clear() (DIR) diff --git a/gui/kivy/uix/ui_screens/requests.kv b/gui/kivy/uix/ui_screens/requests.kv t@@ -23,9 +23,6 @@ RequestsScreen: name: 'requests' - on_activate: - if not self.action_view:\ - self.action_view = app.root.main_screen.ids.tabs.ids.screen_dashboard.action_view BoxLayout: orientation: 'vertical' spacing: '1dp' t@@ -41,5 +38,5 @@ RequestsScreen: id: requests_container size_hint_y: None height: self.minimum_height - spacing: '1dp' + spacing: '2dp' padding: '12dp'