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'