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:
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