electrum

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

commit 5156b60769b365522b263220dfefcca12fea4e97
parent 568afd7a1757078127599d1905ff13dc2fdf037c
Author: ThomasV <thomasv@electrum.org>
Date:   Sat, 11 Nov 2017 11:33:36 +0100

kivy addresses tab: simplify, separate actions from display updates

Diffstat:
Mgui/kivy/main.kv | 2+-
Mgui/kivy/uix/screens.py | 200+++++++++++++++++++------------------------------------------------------------
Mgui/kivy/uix/ui_screens/address.kv | 133+++++++++++++++++++++++++++++++++----------------------------------------------
3 files changed, 104 insertions(+), 231 deletions(-)

diff --git a/gui/kivy/main.kv b/gui/kivy/main.kv @@ -405,7 +405,7 @@ slide: 3 CleanHeader: id: address_tab - text: _('Address') + text: _('Addresses') slide: 4 diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py @@ -487,83 +487,63 @@ class AddressScreen(CScreen): kvname = 'address' cards = {} - def get_card(self, addr, search): + def get_card(self, addr, balance, is_used, label): ci = self.cards.get(addr) if ci is None: - ci = Factory.RequestItem() + ci = Factory.AddressItem() ci.screen = self ci.address = addr - ci.status = search self.cards[addr] = ci - else: - ci.status = search - - ci.memo = self.app.wallet.get_label(addr) - if search == 'Pending' or search == 'Paid': - req = self.app.wallet.get_payment_request(addr, self.app.electrum_config) - timestamp = req.get('time', 0) - amount = req.get('amount') - ci.icon = address_icon[search] - ci.amount = self.app.format_amount_and_units(amount) if amount else _('No Amount') - ci.date = format_time(timestamp) - else: - c, u, x = self.app.wallet.get_addr_balance(addr) - balance = c + u + x - ci.icon = '' - ci.amount = self.app.format_amount_and_units(balance) if balance else _('No Amount') - ci.date = '' - return ci - - def generic_search(self): - _list = self.ext_search(self.screen.message) - search_list = self.screen.ids.search_container - search_list.clear_widgets() - for req in _list: - status, conf = self.app.wallet.get_request_status(req) + ci.memo = label + ci.amount = self.app.format_amount_and_units(balance) + request = self.app.wallet.get_payment_request(addr, self.app.electrum_config) + if is_used: + ci.status = _('Used') + elif request: + status, conf = self.app.wallet.get_request_status(addr) + requested_amount = request.get('amount') + # make sure that requested amount is > 0 if status == PR_PAID: - search = "Paid" + s = _('Request paid') elif status == PR_UNPAID: - search = "Pending" + s = _('Request pending') + elif status == PR_EXPIRED: + s = _('Request expired') else: - search = "" - card = self.get_card(req, search) - search_list.add_widget(card) - if not _list: - msg = _('No address matching your search') - search_list.add_widget(EmptyLabel(text=msg)) - - def search(self, req): - - if req == 0: - self.screen.addr_type = 'Change' if self.screen.addr_type == 'Receiving' else 'Receiving' - - if req == 1: - status = { 'New' : 'Funded', 'Funded' : 'Unused', 'Unused' : 'New' } - for s in status: - if s == self.screen.addr_status: - self.screen.addr_status = status[s] - break - if req == 2: - pr_status = { 'Pending' : 'Paid', 'Paid' : 'Pending' } - for s in pr_status: - if s == self.screen.pr_status: - self.screen.pr_status = pr_status[s] - break - - search = self.screen.addr_type if req == 0 else (self.screen.addr_status if req == 1 else self.screen.pr_status) - _list = self.addr_search(search) - - search_list = self.screen.ids.search_container - search_list.clear_widgets() - if _list is None: - return - for addr in _list: - card = self.get_card(addr, search) - search_list.add_widget(card) + s = '' + ci.status = s + ': ' + self.app.format_amount_and_units(requested_amount) + else: + ci.status = _('Funded') if balance>0 else _('Unused') + return ci + def update(self): self.menu_actions = [('Receive', self.do_show), ('Details', self.do_view)] + wallet = self.app.wallet + _list = wallet.change_addresses if self.screen.show_change else wallet.receiving_addresses + search = self.screen.message + container = self.screen.ids.search_container + container.clear_widgets() + n = 0 + for address in _list: + label = wallet.labels.get(address, '') + balance = sum(wallet.get_addr_balance(address)) + is_used = wallet.is_used(address) + if self.screen.show_used == 1 and (balance or is_used): + continue + if self.screen.show_used == 2 and balance == 0: + continue + if self.screen.show_used == 3 and not is_used: + continue + card = self.get_card(address, balance, is_used, label) + if search and not self.ext_search(card, search): + continue + container.add_widget(card) + n += 1 + if not n: + msg = _('No address matching your search') + container.add_widget(EmptyLabel(text=msg)) def do_show(self, obj): self.app.show_request(obj.address) @@ -604,94 +584,10 @@ class AddressScreen(CScreen): d = Question(_('Delete request?'), cb) d.open() - def addr_search(self, search): - - def get_addr_receiving(self): - return self.app.wallet.receiving_addresses - - def get_addr_change(self): - return self.app.wallet.change_addresses - - def get_addr_new(self): - _list = list() - for addr in self.app.wallet.receiving_addresses: - if not self.app.wallet.is_used(addr) and self.app.wallet.is_empty(addr) and addr not in self.app.wallet.receive_requests: - _list.append(addr) - for addr in self.app.wallet.change_addresses: - if not self.app.wallet.is_used(addr) and self.app.wallet.is_empty(addr): - _list.append(addr) - return _list - - def get_addr_unused(self): - _list = list() - for addr in self.app.wallet.receiving_addresses: - if self.app.wallet.is_used(addr): - _list.append(addr) - for addr in self.app.wallet.change_addresses: - if self.app.wallet.is_used(addr): - _list.append(addr) - return _list - - def get_addr_funded(self): - _list = list() - for addr in self.app.wallet.receiving_addresses: - c, u, x = self.app.wallet.get_addr_balance(addr) - balance = c + u + x - if balance > 0: - _list.append(addr) - for addr in self.app.wallet.change_addresses: - c, u, x = self.app.wallet.get_addr_balance(addr) - balance = c + u + x - if balance > 0: - _list.append(addr) - return _list - - def get_addr_pending(self): - _list = list() - for addr in self.app.wallet.receive_requests: - status, conf = self.app.wallet.get_request_status(addr) - if status == PR_UNPAID or status == PR_EXPIRED: - _list.append(addr) - return _list - - def get_addr_paid(self): - _list = list() - for addr in self.app.wallet.receive_requests: - status, conf = self.app.wallet.get_request_status(addr) - if status == PR_PAID: - _list.append(addr) - return _list - - addr_search = { 'Receiving' : get_addr_receiving, 'Change' : get_addr_change, - 'New' : get_addr_new, 'Unused' : get_addr_unused, 'Funded' : get_addr_funded, - 'Pending' : get_addr_pending, 'Paid' : get_addr_paid } - - for s in addr_search: - if search == s: - _list = addr_search[s](self) - return _list + def ext_search(self, card, search): + return card.memo.find(search) >= 0 or card.amount.find(search) >= 0 + - - def ext_search(self, search): - - def to_btc(amount): - return str(amount / 100000000) - - def to_mbtc(amount): - return str(amount / 100000) - - def to_time(time): - from time import gmtime, strftime - return strftime("%Y-%m-%d %M:%S", gmtime(time)) - - _list = [] - for addr in self.app.wallet.receive_requests: - r = self.app.wallet.receive_requests.get(addr) - if r['memo'].find(search) >= 0 or to_btc(r['amount']).find(search) >= 0 \ - or to_mbtc(r['amount']).find(search) >= 0 or to_time(r['time']).find(search) >= 0: - _list.append(addr) - - return _list class TabbedCarousel(Factory.TabbedPanel): diff --git a/gui/kivy/uix/ui_screens/address.kv b/gui/kivy/uix/ui_screens/address.kv @@ -4,36 +4,27 @@ #:set mbtc_symbol chr(187) #:set font_light 'gui/kivy/data/fonts/Roboto-Condensed.ttf' -<RequestLabel@Label> +<AddressLabel@Label> text_size: self.width, None halign: 'left' valign: 'top' -<RequestItem@CardItem> +<AddressItem@CardItem> address: '' memo: '' amount: '' status: '' - date: '' - icon: '' - color: .699, .699, .699, 1 - Image: - id: icon - source: root.icon - size_hint: None, 1 - width: self.height *.54 if root.icon else 0 - mipmap: True BoxLayout: spacing: '8dp' height: '32dp' orientation: 'vertical' Widget - RequestLabel: + AddressLabel: text: root.address shorten: True Widget - RequestLabel: - text: root.date + " " + root.memo + AddressLabel: + text: root.memo color: .699, .699, .699, 1 font_size: '13sp' shorten: True @@ -43,12 +34,12 @@ height: '32dp' orientation: 'vertical' Widget - RequestLabel: + AddressLabel: text: root.amount halign: 'right' font_size: '15sp' Widget - RequestLabel: + AddressLabel: text: root.status halign: 'right' font_size: '13sp' @@ -58,72 +49,58 @@ AddressScreen: id: addr_screen name: 'address' message: '' - addr_type: 'Receiving' - addr_status: 'New' pr_status: 'Pending' - + show_change: False + show_used: 0 on_message: - self.parent.generic_search() - - + self.parent.update() BoxLayout padding: '12dp', '70dp', '12dp', '12dp' spacing: '12dp' orientation: 'vertical' size_hint: 1, 1.1 - - BoxLayout: - spacing: '6dp' - size_hint: 1, None - orientation: 'horizontal' - AddressFilter: - id: blue_bottom - opacity: 1 - size_hint: 1, None - height: self.minimum_height - spacing: '5dp' - AddressButton: - id: search - text: addr_screen.addr_type - on_release: Clock.schedule_once(lambda dt: app.address_screen.search(0)) - AddressFilter: - id: blue_bottom - opacity: 1 - size_hint: 1, None - height: self.minimum_height - spacing: '5dp' - AddressButton: - id: search - text: addr_screen.addr_status - on_release: Clock.schedule_once(lambda dt: app.address_screen.search(1)) - AddressFilter: - id: blue_bottom - opacity: 1 - size_hint: 1, None - height: self.minimum_height - spacing: '5dp' - AddressButton: - id: pending - text: addr_screen.pr_status - on_release: Clock.schedule_once(lambda dt: app.address_screen.search(2)) - AddressFilter: - id: blue_bottom - opacity: 1 - size_hint: 1, None - height: self.minimum_height - spacing: '5dp' - canvas.before: - Color: - rgba: 0.9, 0.9, 0.9, 1 - AddressButton: - id: change - text: addr_screen.message if addr_screen.message else _('Search') - on_release: Clock.schedule_once(lambda dt: app.description_dialog(addr_screen)) - - ScrollView: - GridLayout: - cols: 1 - id: search_container - size_hint_y: None - height: self.minimum_height - spacing: '2dp' + BoxLayout: + spacing: '6dp' + size_hint: 1, None + orientation: 'horizontal' + AddressFilter: + opacity: 1 + size_hint: 1, None + height: self.minimum_height + spacing: '5dp' + AddressButton: + id: search + text: _('Change') if root.show_change else _('Receiving') + on_release: + root.show_change = not root.show_change + Clock.schedule_once(lambda dt: app.address_screen.update()) + AddressFilter: + opacity: 1 + size_hint: 1, None + height: self.minimum_height + spacing: '5dp' + AddressButton: + id: search + text: {0:_('All'), 1:_('Unused'), 2:_('Funded'), 3:_('Used')}[root.show_used] + on_release: + root.show_used = (root.show_used + 1) % 4 + Clock.schedule_once(lambda dt: app.address_screen.update()) + AddressFilter: + opacity: 1 + size_hint: 1, None + height: self.minimum_height + spacing: '5dp' + canvas.before: + Color: + rgba: 0.9, 0.9, 0.9, 1 + AddressButton: + id: change + text: root.message if root.message else _('Search') + on_release: Clock.schedule_once(lambda dt: app.description_dialog(addr_screen)) + ScrollView: + GridLayout: + cols: 1 + id: search_container + size_hint_y: None + height: self.minimum_height + spacing: '2dp'