electrum

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

commit 7af5d42324041204967b7d9c0865ddb8c2eb2712
parent 1358bebd37a1784b40d4459d6f535e29b7c78fa0
Author: ThomasV <thomasv@electrum.org>
Date:   Sun,  8 Jan 2017 13:00:57 +0100

qt: show addresses and utxos in separate tabs

Diffstat:
Mgui/qt/address_list.py | 15+--------------
Mgui/qt/main_window.py | 44++++++++++++++++++++++++++++----------------
Agui/qt/utxo_list.py | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/wallet.py | 7+++++--
4 files changed, 100 insertions(+), 32 deletions(-)

diff --git a/gui/qt/address_list.py b/gui/qt/address_list.py @@ -84,15 +84,6 @@ class AddressList(MyTreeWidget): seq_item.addChild(address_item) if address == current_address: self.setCurrentItem(address_item) - # add utxos - utxos = self.wallet.get_addr_utxo(address) - for x in utxos: - h = x.get('prevout_hash') - s = h + ":%d"%x.get('prevout_n') - label = self.wallet.get_label(h) - utxo_item = QTreeWidgetItem([s, label, self.parent.format_amount(x['value'])]) - utxo_item.setFont(0, QFont(MONOSPACE_FONT)) - address_item.addChild(utxo_item) def create_menu(self, position): from electrum.wallet import Multisig_Wallet @@ -110,11 +101,7 @@ class AddressList(MyTreeWidget): return addr = addrs[0] if not is_address(addr): - k = str(item.data(0,32).toString()) - if k: - self.create_account_menu(position, k, item) - else: - item.setExpanded(not item.isExpanded()) + item.setExpanded(not item.isExpanded()) return menu = QMenu() diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -129,6 +129,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.addresses_tab = self.create_addresses_tab() if self.config.get('show_addresses_tab', False): tabs.addTab(self.addresses_tab, _('Addresses')) + self.utxo_tab = self.create_utxo_tab() + if self.config.get('show_utxo_tab', False): + tabs.addTab(self.utxo_tab, _('Coins')) tabs.addTab(self.create_contacts_tab(), _('Contacts') ) tabs.addTab(self.create_console_tab(), _('Console') ) tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) @@ -198,14 +201,23 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.history_list.update() def toggle_addresses_tab(self): - show_addr = not self.config.get('show_addresses_tab', False) - self.config.set_key('show_addresses_tab', show_addr) - if show_addr: + show = not self.config.get('show_addresses_tab', False) + self.config.set_key('show_addresses_tab', show) + if show: self.tabs.insertTab(3, self.addresses_tab, _('Addresses')) else: i = self.tabs.indexOf(self.addresses_tab) self.tabs.removeTab(i) + def toggle_utxo_tab(self): + show = not self.config.get('show_utxo_tab', False) + self.config.set_key('show_utxo_tab', show) + if show: + self.tabs.insertTab(3, self.utxo_tab, _('Coins')) + else: + i = self.tabs.indexOf(self.utxo_tab) + self.tabs.removeTab(i) + def push_top_level_window(self, window): '''Used for e.g. tx dialog box to ensure new dialogs are appropriately parented. This used to be done by explicitly providing the parent @@ -436,6 +448,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): wallet_menu.addAction(_("Find"), self.toggle_search).setShortcut(QKeySequence("Ctrl+F")) wallet_menu.addAction(_("Addresses"), self.toggle_addresses_tab).setShortcut(QKeySequence("Ctrl+A")) + wallet_menu.addAction(_("Coins"), self.toggle_utxo_tab).setShortcut(QKeySequence("Ctrl+C")) tools_menu = menubar.addMenu(_("&Tools")) @@ -660,6 +673,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.history_list.update() self.request_list.update() self.address_list.update() + self.utxo_list.update() self.contact_list.update() self.invoice_list.update() self.update_completions() @@ -1059,6 +1073,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): vbox.addWidget(self.invoices_label) vbox.addWidget(self.invoice_list) vbox.setStretchFactor(self.invoice_list, 1000) + # Defer this until grid is parented to avoid ugly flash during startup run_hook('create_send_tab', grid) return w @@ -1122,8 +1137,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): menu.addAction(_("Remove"), lambda: self.from_list_delete(item)) menu.exec_(self.from_list.viewport().mapToGlobal(position)) - def set_pay_from(self, domain = None): - self.pay_from = [] if domain == [] else self.wallet.get_spendable_coins(domain) + def set_pay_from(self, coins): + self.pay_from = coins self.redraw_from_list() def redraw_from_list(self): @@ -1133,7 +1148,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): def format(x): h = x.get('prevout_hash') - return h[0:8] + '...' + h[-8:] + ":%d"%x.get('prevout_n') + u'\t' + "%s"%x.get('address') + return h[0:10] + '...' + h[-10:] + ":%d"%x.get('prevout_n') + u'\t' + "%s"%x.get('address') for item in self.pay_from: self.from_list.addTopLevelItem(QTreeWidgetItem( [format(item), self.format_amount(item['value']) ])) @@ -1469,6 +1484,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.address_list = l = AddressList(self) return self.create_list_tab(l) + def create_utxo_tab(self): + from utxo_list import UTXOList + self.utxo_list = l = UTXOList(self) + return self.create_list_tab(l) + def create_contacts_tab(self): from contact_list import ContactList self.contact_list = l = ContactList(self) @@ -1480,13 +1500,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.address_list.update() self.history_list.update() - def edit_account_label(self, k): - text, ok = QInputDialog.getText(self, _('Rename account'), _('Name') + ':', text = self.wallet.labels.get(k,'')) - if ok: - label = unicode(text) - self.wallet.set_label(k,label) - self.address_list.update() - def get_coins(self): if self.pay_from: return self.pay_from @@ -1494,9 +1507,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): domain = self.wallet.get_addresses() return self.wallet.get_spendable_coins(domain) - - def send_from_addresses(self, addrs): - self.set_pay_from(addrs) + def spend_coins(self, coins): + self.set_pay_from(coins) self.tabs.setCurrentIndex(1) self.update_fee() diff --git a/gui/qt/utxo_list.py b/gui/qt/utxo_list.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2015 Thomas Voegtlin +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from util import * +from electrum.i18n import _ + + +class UTXOList(MyTreeWidget): + + def __init__(self, parent=None): + MyTreeWidget.__init__(self, parent, self.create_menu, [ _('Output'), _('Address'), _('Label'), _('Amount'), ''], 2) + self.setSelectionMode(QAbstractItemView.ExtendedSelection) + + def get_name(self, x): + return x.get('prevout_hash') + ":%d"%x.get('prevout_n') + + def on_update(self): + self.wallet = self.parent.wallet + item = self.currentItem() + self.clear() + self.utxos = self.wallet.get_utxos() + for x in self.utxos: + address = x.get('address') + name = self.get_name(x) + label = self.wallet.get_label(x.get('prevout_hash')) + amount = self.parent.format_amount(x['value']) + utxo_item = QTreeWidgetItem([name[0:10]+'...'+name[-10:], address, label, amount]) + utxo_item.setFont(0, QFont(MONOSPACE_FONT)) + utxo_item.setFont(1, QFont(MONOSPACE_FONT)) + utxo_item.setData(0, Qt.UserRole, name) + if self.wallet.is_frozen(address): + utxo_item.setBackgroundColor(0, QColor('lightblue')) + self.addChild(utxo_item) + + def create_menu(self, position): + from electrum.wallet import Multisig_Wallet + selected = [ x.data(0, Qt.UserRole).toString() for x in self.selectedItems()] + if not selected: + return + coins = filter(lambda x: self.get_name(x) in selected, self.utxos) + menu = QMenu() + menu.addAction(_("Spend"), lambda: self.parent.spend_coins(coins)) + menu.exec_(self.viewport().mapToGlobal(position)) + diff --git a/lib/wallet.py b/lib/wallet.py @@ -532,7 +532,10 @@ class Abstract_Wallet(PrintError): u -= v return c, u, x - def get_spendable_coins(self, domain = None, exclude_frozen = True): + def get_spendable_coins(self, domain = None): + return self.get_utxos(self, domain, exclude_frozen=True, mature=True) + + def get_utxos(self, domain = None, exclude_frozen = False, mature = False): coins = [] if domain is None: domain = self.get_addresses() @@ -541,7 +544,7 @@ class Abstract_Wallet(PrintError): for addr in domain: utxos = self.get_addr_utxo(addr) for x in utxos: - if x['coinbase'] and x['height'] + COINBASE_MATURITY > self.get_local_height(): + if mature and x['coinbase'] and x['height'] + COINBASE_MATURITY > self.get_local_height(): continue coins.append(x) continue