URI: 
       tkivy: store contacts as invoices - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 078cabd745c031b73ff2a134ef0c5717a0ccec0a
   DIR parent f5fcae7f11e5d102b70bb76d413e428db451f1a9
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Tue,  9 Feb 2016 12:48:25 +0100
       
       kivy: store contacts as invoices
       
       Diffstat:
         M gui/kivy/main_window.py             |       2 +-
         D gui/kivy/theming/light/contact_ava… |       0 
         A gui/kivy/theming/light/save.png     |       0 
         M gui/kivy/uix/screens.py             |      92 ++++++++++++-------------------
         M gui/kivy/uix/ui_screens/send.kv     |      16 ++++++++--------
         M lib/paymentrequest.py               |      11 ++++++++---
       
       6 files changed, 51 insertions(+), 70 deletions(-)
       ---
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -258,8 +258,8 @@ class ElectrumWindow(App):
                panel.switch_to(tab)
        
            def show_request(self, addr):
       -        self.receive_screen.screen.address = addr
                self.switch_to('receive')
       +        self.receive_screen.screen.address = addr
        
            def scan_qr(self, on_complete):
                if platform != 'android':
   DIR diff --git a/gui/kivy/theming/light/contact_avatar.png b/gui/kivy/theming/light/contact_avatar.png
       Binary files differ.
   DIR diff --git a/gui/kivy/theming/light/save.png b/gui/kivy/theming/light/save.png
       Binary files differ.
   DIR diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py
       t@@ -202,12 +202,32 @@ class SendScreen(CScreen):
                    self.screen.amount = self.app.format_amount_and_units(amount)
                self.screen.message = pr.get_memo()
        
       +    def do_save(self):
       +        if not self.screen.address:
       +            return
       +        if self.payment_request:
       +            # it sould be already saved
       +            return
       +        # save address as invoice
       +        from electrum.paymentrequest import make_unsigned_request, PaymentRequest
       +        req = {'address':self.screen.address, 'memo':self.screen.message}
       +        amount = self.app.get_amount(self.screen.amount) if self.screen.amount else 0
       +        req['amount'] = amount
       +        pr = make_unsigned_request(req).SerializeToString()
       +        pr = PaymentRequest(pr)
       +        self.app.invoices.add(pr)
       +        self.app.update_tab('invoices')
       +        self.app.show_info(_("Invoice saved"))
       +
            def do_paste(self):
                contents = unicode(self.app._clipboard.paste())
       +        if not contents:
       +            self.app.show_info(_("Clipboard is empty"))
       +            return
                try:
                    uri = parse_URI(contents)
                except:
       -            self.app.show_info("Invalid URI", contents)
       +            self.app.show_info(_("Clipboard content is not a Bitcoin URI"))
                    return
                self.set_URI(uri)
        
       t@@ -324,20 +344,14 @@ class ReceiveScreen(CScreen):
                self.app._clipboard.copy(uri)
                self.app.show_info(_('Request copied to clipboard'))
        
       -    def do_save(self):
       +    def on_amount_or_message(self):
                addr = str(self.screen.address)
                amount = str(self.screen.amount)
                message = str(self.screen.message) #.ids.message_input.text)
       -        if not message and not amount:
       -            return False
                amount = self.app.get_amount(amount) if amount else 0
                req = self.app.wallet.make_payment_request(addr, amount, message, None)
                self.app.wallet.add_payment_request(req, self.app.electrum_config)
                self.app.update_tab('requests')
       -        return True
       -
       -    def on_amount_or_message(self):
       -        self.do_save()
                Clock.schedule_once(lambda dt: self.update_qr())
        
            def do_new(self):
       t@@ -345,34 +359,6 @@ class ReceiveScreen(CScreen):
                    self.app.show_info(_('Please use the existing requests first.'))
        
        
       -class ContactsScreen(CScreen):
       -    kvname = 'contacts'
       -
       -    def add_new_contact(self):
       -        dlg = Cache.get('electrum_widgets', 'NewContactDialog')
       -        if not dlg:
       -            dlg = NewContactDialog()
       -            Cache.append('electrum_widgets', 'NewContactDialog', dlg)
       -        dlg.open()
       -
       -    def update(self):
       -        contact_list = self.screen.ids.contact_container
       -        contact_list.clear_widgets()
       -        child = -1
       -        children = contact_list.children
       -        for key in sorted(self.app.contacts.keys()):
       -            _type, value = self.app.contacts[key]
       -            child += 1
       -            try:
       -                if children[child].label == value:
       -                    continue
       -            except IndexError:
       -                pass
       -            ci = Factory.ContactItem()
       -            ci.address = key
       -            ci.label = value
       -            contact_list.add_widget(ci)
       -
        
        pr_text = {
            PR_UNPAID:_('Pending'),
       t@@ -401,11 +387,16 @@ class InvoicesScreen(CScreen):
                    ci = Factory.InvoiceItem()
                    ci.key = pr.get_id()
                    ci.requestor = pr.get_requestor()
       -            ci.memo = pr.memo
       -            ci.amount = self.app.format_amount_and_units(pr.get_amount())
       -            status = self.app.invoices.get_status(ci.key)
       -            ci.status = pr_text[status]
       -            ci.icon = pr_icon[status]
       +            ci.memo = pr.get_memo()
       +            amount = pr.get_amount()
       +            if amount:
       +                ci.amount = self.app.format_amount_and_units(amount)
       +                status = self.app.invoices.get_status(ci.key)
       +                ci.status = pr_text[status]
       +                ci.icon = pr_icon[status]
       +            else:
       +                ci.amount = _('No Amount')
       +                ci.status = ''
                    exp = pr.get_expiration_date()
                    ci.date = format_time(exp) if exp else _('Never')
                    ci.screen = self
       t@@ -444,8 +435,9 @@ class RequestsScreen(CScreen):
                    expiration = req.get('exp', None)
                    status = req.get('status')
                    signature = req.get('sig')
       +
                    ci = Factory.RequestItem()
       -            ci.address = req['address']
       +            ci.address = address
                    ci.memo = self.app.wallet.get_label(address)
                    if amount:
                        status = req.get('status')
       t@@ -476,22 +468,6 @@ class RequestsScreen(CScreen):
                d.open()
        
        
       -class CSpinner(Factory.Spinner):
       -    '''CustomDropDown that allows fading out the dropdown
       -    '''
       -
       -    def _update_dropdown(self, *largs):
       -        dp = self._dropdown
       -        cls = self.option_cls
       -        if isinstance(cls, string_types):
       -            cls = Factory.get(cls)
       -        dp.clear_widgets()
       -        def do_release(option):
       -            Clock.schedule_once(lambda dt: dp.select(option.text), .25)
       -        for value in self.values:
       -            item = cls(text=value)
       -            item.bind(on_release=do_release)
       -            dp.add_widget(item)
        
        
        class TabbedCarousel(Factory.TabbedPanel):
   DIR diff --git a/gui/kivy/uix/ui_screens/send.kv b/gui/kivy/uix/ui_screens/send.kv
       t@@ -75,27 +75,27 @@ SendScreen:
                    height: '48dp'
                    IconButton:
                        id: qr
       -                size_hint: 0.5, 1
       +                size_hint: 0.6, 1
                        on_release: app.scan_qr(on_complete=app.set_URI)
                        icon: 'atlas://gui/kivy/theming/light/camera'
                    Button:
       -                id: paste_button
                        text: _('Paste')
                        on_release: s.parent.do_paste()
                    Button:
                        text: _('Clear')
       -                size_hint: 1, None
       -                height: '48dp'
                        on_release: s.parent.do_clear()
       +            IconButton:
       +                size_hint: 0.6, 1
       +                on_release: s.parent.do_save()
       +                icon: 'atlas://gui/kivy/theming/light/save'
                BoxLayout:
                    size_hint: 1, None
                    height: '48dp'
                    Widget:
       -                size_hint: 1, 1
       +                size_hint: 2, 1
                    Button:
       -                text: _('Send')
       -                size_hint: 1, None
       -                height: '48dp'
       +                text: _('Pay')
       +                size_hint: 1, 1
                        on_release: s.parent.do_send()
                Widget:
                    size_hint: 1, 1
   DIR diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py
       t@@ -186,8 +186,13 @@ class PaymentRequest:
            def get_amount(self):
                return sum(map(lambda x:x[2], self.outputs))
        
       +    def get_address(self):
       +        o = self.outputs[0]
       +        assert o[0] == TYPE_ADDRESS
       +        return o[1]
       +
            def get_requestor(self):
       -        return self.requestor if self.requestor else 'unknown'
       +        return self.requestor if self.requestor else self.get_address()
        
            def get_verify_status(self):
                return self.error
       t@@ -196,7 +201,7 @@ class PaymentRequest:
                return self.memo
        
            def get_id(self):
       -        return self.id
       +        return self.id if self.requestor else self.get_address()
        
            def get_outputs(self):
                return self.outputs[:]
       t@@ -421,7 +426,7 @@ class InvoiceStore(object):
                for k, pr in self.invoices.items():
                    l[k] = {
                        'hex': str(pr).encode('hex'),
       -                'requestor': pr.get_requestor(), 
       +                'requestor': pr.requestor,
                        'txid': pr.tx
                    }
                path = os.path.join(self.config.path, 'invoices')