Browse Source

qt: show addresses and utxos in separate tabs

283
ThomasV 8 years ago
parent
commit
7af5d42324
  1. 15
      gui/qt/address_list.py
  2. 44
      gui/qt/main_window.py
  3. 66
      gui/qt/utxo_list.py
  4. 7
      lib/wallet.py

15
gui/qt/address_list.py

@ -84,15 +84,6 @@ class AddressList(MyTreeWidget):
seq_item.addChild(address_item) seq_item.addChild(address_item)
if address == current_address: if address == current_address:
self.setCurrentItem(address_item) 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): def create_menu(self, position):
from electrum.wallet import Multisig_Wallet from electrum.wallet import Multisig_Wallet
@ -110,11 +101,7 @@ class AddressList(MyTreeWidget):
return return
addr = addrs[0] addr = addrs[0]
if not is_address(addr): if not is_address(addr):
k = str(item.data(0,32).toString()) item.setExpanded(not item.isExpanded())
if k:
self.create_account_menu(position, k, item)
else:
item.setExpanded(not item.isExpanded())
return return
menu = QMenu() menu = QMenu()

44
gui/qt/main_window.py

@ -129,6 +129,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.addresses_tab = self.create_addresses_tab() self.addresses_tab = self.create_addresses_tab()
if self.config.get('show_addresses_tab', False): if self.config.get('show_addresses_tab', False):
tabs.addTab(self.addresses_tab, _('Addresses')) 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_contacts_tab(), _('Contacts') )
tabs.addTab(self.create_console_tab(), _('Console') ) tabs.addTab(self.create_console_tab(), _('Console') )
tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
@ -198,14 +201,23 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.history_list.update() self.history_list.update()
def toggle_addresses_tab(self): def toggle_addresses_tab(self):
show_addr = not self.config.get('show_addresses_tab', False) show = not self.config.get('show_addresses_tab', False)
self.config.set_key('show_addresses_tab', show_addr) self.config.set_key('show_addresses_tab', show)
if show_addr: if show:
self.tabs.insertTab(3, self.addresses_tab, _('Addresses')) self.tabs.insertTab(3, self.addresses_tab, _('Addresses'))
else: else:
i = self.tabs.indexOf(self.addresses_tab) i = self.tabs.indexOf(self.addresses_tab)
self.tabs.removeTab(i) 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): def push_top_level_window(self, window):
'''Used for e.g. tx dialog box to ensure new dialogs are appropriately '''Used for e.g. tx dialog box to ensure new dialogs are appropriately
parented. This used to be done by explicitly providing the parent 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(_("Find"), self.toggle_search).setShortcut(QKeySequence("Ctrl+F"))
wallet_menu.addAction(_("Addresses"), self.toggle_addresses_tab).setShortcut(QKeySequence("Ctrl+A")) 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")) tools_menu = menubar.addMenu(_("&Tools"))
@ -660,6 +673,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.history_list.update() self.history_list.update()
self.request_list.update() self.request_list.update()
self.address_list.update() self.address_list.update()
self.utxo_list.update()
self.contact_list.update() self.contact_list.update()
self.invoice_list.update() self.invoice_list.update()
self.update_completions() self.update_completions()
@ -1059,6 +1073,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
vbox.addWidget(self.invoices_label) vbox.addWidget(self.invoices_label)
vbox.addWidget(self.invoice_list) vbox.addWidget(self.invoice_list)
vbox.setStretchFactor(self.invoice_list, 1000) vbox.setStretchFactor(self.invoice_list, 1000)
# Defer this until grid is parented to avoid ugly flash during startup # Defer this until grid is parented to avoid ugly flash during startup
run_hook('create_send_tab', grid) run_hook('create_send_tab', grid)
return w return w
@ -1122,8 +1137,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
menu.addAction(_("Remove"), lambda: self.from_list_delete(item)) menu.addAction(_("Remove"), lambda: self.from_list_delete(item))
menu.exec_(self.from_list.viewport().mapToGlobal(position)) menu.exec_(self.from_list.viewport().mapToGlobal(position))
def set_pay_from(self, domain = None): def set_pay_from(self, coins):
self.pay_from = [] if domain == [] else self.wallet.get_spendable_coins(domain) self.pay_from = coins
self.redraw_from_list() self.redraw_from_list()
def redraw_from_list(self): def redraw_from_list(self):
@ -1133,7 +1148,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def format(x): def format(x):
h = x.get('prevout_hash') 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: for item in self.pay_from:
self.from_list.addTopLevelItem(QTreeWidgetItem( [format(item), self.format_amount(item['value']) ])) 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) self.address_list = l = AddressList(self)
return self.create_list_tab(l) 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): def create_contacts_tab(self):
from contact_list import ContactList from contact_list import ContactList
self.contact_list = l = ContactList(self) self.contact_list = l = ContactList(self)
@ -1480,13 +1500,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.address_list.update() self.address_list.update()
self.history_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): def get_coins(self):
if self.pay_from: if self.pay_from:
return self.pay_from return self.pay_from
@ -1494,9 +1507,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
domain = self.wallet.get_addresses() domain = self.wallet.get_addresses()
return self.wallet.get_spendable_coins(domain) return self.wallet.get_spendable_coins(domain)
def spend_coins(self, coins):
def send_from_addresses(self, addrs): self.set_pay_from(coins)
self.set_pay_from(addrs)
self.tabs.setCurrentIndex(1) self.tabs.setCurrentIndex(1)
self.update_fee() self.update_fee()

66
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))

7
lib/wallet.py

@ -532,7 +532,10 @@ class Abstract_Wallet(PrintError):
u -= v u -= v
return c, u, x 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 = [] coins = []
if domain is None: if domain is None:
domain = self.get_addresses() domain = self.get_addresses()
@ -541,7 +544,7 @@ class Abstract_Wallet(PrintError):
for addr in domain: for addr in domain:
utxos = self.get_addr_utxo(addr) utxos = self.get_addr_utxo(addr)
for x in utxos: 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 continue
coins.append(x) coins.append(x)
continue continue

Loading…
Cancel
Save