HistoryWidget class; address history window
This commit is contained in:
parent
0a7b585b6c
commit
b8a72180c7
|
@ -0,0 +1,94 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Electrum - lightweight Bitcoin client
|
||||||
|
# Copyright (C) 2012 thomasv@gitorious
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import sys, time, datetime, re, threading
|
||||||
|
from electrum.i18n import _, set_language
|
||||||
|
from electrum.util import print_error, print_msg
|
||||||
|
import os.path, json, ast, traceback
|
||||||
|
import shutil
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import PyQt4
|
||||||
|
except Exception:
|
||||||
|
sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'")
|
||||||
|
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
import PyQt4.QtCore as QtCore
|
||||||
|
|
||||||
|
|
||||||
|
from util import *
|
||||||
|
from history_widget import HistoryWidget
|
||||||
|
|
||||||
|
class AddressDialog(QDialog):
|
||||||
|
|
||||||
|
def __init__(self, address, parent):
|
||||||
|
self.address = address
|
||||||
|
self.parent = parent
|
||||||
|
self.config = parent.config
|
||||||
|
self.wallet = parent.wallet
|
||||||
|
self.app = parent.app
|
||||||
|
self.saved = True
|
||||||
|
|
||||||
|
QDialog.__init__(self)
|
||||||
|
self.setMinimumWidth(700)
|
||||||
|
self.setWindowTitle(_("Address"))
|
||||||
|
self.setModal(1)
|
||||||
|
vbox = QVBoxLayout()
|
||||||
|
self.setLayout(vbox)
|
||||||
|
|
||||||
|
vbox.addWidget(QLabel(_("Address:")))
|
||||||
|
self.addr_e = QLineEdit()
|
||||||
|
self.addr_e.setText(self.address)
|
||||||
|
self.addr_e.setReadOnly(True)
|
||||||
|
vbox.addWidget(self.addr_e)
|
||||||
|
|
||||||
|
vbox.addWidget(QLabel(_("History")))
|
||||||
|
self.hw = HistoryWidget(self)
|
||||||
|
vbox.addWidget(self.hw)
|
||||||
|
|
||||||
|
vbox.addStretch(1)
|
||||||
|
|
||||||
|
self.close_button = b = QPushButton(_("Close"))
|
||||||
|
b.clicked.connect(self.close)
|
||||||
|
b.setDefault(True)
|
||||||
|
|
||||||
|
self.qr_button = b = QPushButton()
|
||||||
|
b.setIcon(QIcon(":icons/qrcode.png"))
|
||||||
|
b.clicked.connect(self.show_qr)
|
||||||
|
|
||||||
|
self.buttons = [self.qr_button, self.close_button]
|
||||||
|
vbox.addLayout(Buttons(*self.buttons))
|
||||||
|
self.format_amount = self.parent.format_amount
|
||||||
|
|
||||||
|
h = self.wallet.get_history([self.address])
|
||||||
|
self.hw.update(h)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def show_qr(self):
|
||||||
|
text = self.address
|
||||||
|
try:
|
||||||
|
self.parent.show_qrcode(text, 'Address')
|
||||||
|
except Exception as e:
|
||||||
|
self.show_message(str(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import re
|
||||||
import time
|
import time
|
||||||
from electrum.wallet import Wallet, WalletStorage
|
from electrum.wallet import Wallet, WalletStorage
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import history_widget
|
import history_widget_lite
|
||||||
import receiving_widget
|
import receiving_widget
|
||||||
from electrum import util
|
from electrum import util
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -200,7 +200,7 @@ class MiniWindow(QDialog):
|
||||||
|
|
||||||
self.send_button.setMaximumWidth(125)
|
self.send_button.setMaximumWidth(125)
|
||||||
|
|
||||||
self.history_list = history_widget.HistoryWidget()
|
self.history_list = history_widget_lite.HistoryWidget()
|
||||||
self.history_list.setObjectName("history")
|
self.history_list.setObjectName("history")
|
||||||
self.history_list.hide()
|
self.history_list.hide()
|
||||||
self.history_list.setAlternatingRowColors(True)
|
self.history_list.setAlternatingRowColors(True)
|
||||||
|
|
|
@ -20,7 +20,6 @@ import sys, time, re, threading
|
||||||
from electrum.i18n import _, set_language
|
from electrum.i18n import _, set_language
|
||||||
from electrum.util import print_error, print_msg
|
from electrum.util import print_error, print_msg
|
||||||
import os.path, json, ast, traceback
|
import os.path, json, ast, traceback
|
||||||
import webbrowser
|
|
||||||
import shutil
|
import shutil
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
|
@ -543,77 +542,20 @@ class ElectrumWindow(QMainWindow):
|
||||||
self.update_invoices_tab()
|
self.update_invoices_tab()
|
||||||
|
|
||||||
def create_history_tab(self):
|
def create_history_tab(self):
|
||||||
column_width = [40, 140, 350, 140, 140]
|
from history_widget import HistoryWidget
|
||||||
self.history_list = l = MyTreeWidget(self)
|
self.history_list = l = HistoryWidget(self)
|
||||||
l.setColumnCount(5)
|
|
||||||
l.header().setResizeMode(2, QHeaderView.Stretch);
|
|
||||||
l.header().setStretchLastSection(False)
|
|
||||||
for i, width in enumerate(column_width):
|
|
||||||
l.setColumnWidth(i, width)
|
|
||||||
l.setHeaderLabels( [ '', _('Date'), _('Description') , _('Amount'), _('Balance')] )
|
|
||||||
l.itemDoubleClicked.connect(self.edit_tx_label)
|
|
||||||
l.itemChanged.connect(self.tx_label_changed)
|
|
||||||
l.customContextMenuRequested.connect(self.create_history_menu)
|
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def create_history_menu(self, position):
|
def show_address(self, addr):
|
||||||
self.history_list.selectedIndexes()
|
import address_dialog
|
||||||
item = self.history_list.currentItem()
|
d = address_dialog.AddressDialog(addr, self)
|
||||||
be = self.config.get('block_explorer', 'Blockchain.info')
|
d.exec_()
|
||||||
if be == 'Blockchain.info':
|
|
||||||
block_explorer = 'https://blockchain.info/tx/'
|
|
||||||
elif be == 'Blockr.io':
|
|
||||||
block_explorer = 'https://blockr.io/tx/info/'
|
|
||||||
elif be == 'Insight.is':
|
|
||||||
block_explorer = 'http://live.insight.is/tx/'
|
|
||||||
elif be == "Blocktrail.com":
|
|
||||||
block_explorer = 'https://www.blocktrail.com/BTC/tx/'
|
|
||||||
|
|
||||||
if not item: return
|
|
||||||
tx_hash = str(item.data(0, Qt.UserRole).toString())
|
|
||||||
if not tx_hash: return
|
|
||||||
menu = QMenu()
|
|
||||||
menu.addAction(_("Copy ID to Clipboard"), lambda: self.app.clipboard().setText(tx_hash))
|
|
||||||
menu.addAction(_("Details"), lambda: self.show_transaction(self.wallet.transactions.get(tx_hash)))
|
|
||||||
menu.addAction(_("Edit description"), lambda: self.edit_tx_label(item,2))
|
|
||||||
menu.addAction(_("View on block explorer"), lambda: webbrowser.open(block_explorer + tx_hash))
|
|
||||||
menu.exec_(self.contacts_list.viewport().mapToGlobal(position))
|
|
||||||
|
|
||||||
|
|
||||||
def show_transaction(self, tx):
|
def show_transaction(self, tx):
|
||||||
import transaction_dialog
|
import transaction_dialog
|
||||||
d = transaction_dialog.TxDialog(tx, self)
|
d = transaction_dialog.TxDialog(tx, self)
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
|
||||||
def edit_tx_label(self, item, column):
|
|
||||||
if column==2 and item.isSelected():
|
|
||||||
text = unicode(item.text(column))
|
|
||||||
tx_hash = str(item.data(0, Qt.UserRole).toString())
|
|
||||||
self.is_edit = True
|
|
||||||
if text == self.wallet.get_default_label(tx_hash):
|
|
||||||
item.setText(column, '')
|
|
||||||
item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
|
|
||||||
self.history_list.editItem( item, column )
|
|
||||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
|
|
||||||
self.is_edit = False
|
|
||||||
|
|
||||||
def tx_label_changed(self, item, column):
|
|
||||||
if self.is_edit:
|
|
||||||
return
|
|
||||||
self.is_edit = True
|
|
||||||
tx_hash = str(item.data(0, Qt.UserRole).toString())
|
|
||||||
tx = self.wallet.transactions.get(tx_hash)
|
|
||||||
text = unicode(item.text(2))
|
|
||||||
self.wallet.set_label(tx_hash, text)
|
|
||||||
if text:
|
|
||||||
item.setForeground(2, QBrush(QColor('black')))
|
|
||||||
else:
|
|
||||||
text = self.wallet.get_default_label(tx_hash)
|
|
||||||
item.setText(2, text)
|
|
||||||
item.setForeground(2, QBrush(QColor('gray')))
|
|
||||||
self.is_edit = False
|
|
||||||
|
|
||||||
|
|
||||||
def edit_label(self, is_recv):
|
def edit_label(self, is_recv):
|
||||||
l = self.address_list if is_recv else self.contacts_list
|
l = self.address_list if is_recv else self.contacts_list
|
||||||
item = l.currentItem()
|
item = l.currentItem()
|
||||||
|
@ -621,8 +563,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
l.editItem( item, 1 )
|
l.editItem( item, 1 )
|
||||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
|
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def address_label_clicked(self, item, column, l, column_addr, column_label):
|
def address_label_clicked(self, item, column, l, column_addr, column_label):
|
||||||
if column == column_label and item.isSelected():
|
if column == column_label and item.isSelected():
|
||||||
is_editable = item.data(0, 32).toBool()
|
is_editable = item.data(0, 32).toBool()
|
||||||
|
@ -652,47 +592,9 @@ class ElectrumWindow(QMainWindow):
|
||||||
run_hook('current_item_changed', a)
|
run_hook('current_item_changed', a)
|
||||||
|
|
||||||
def update_history_tab(self):
|
def update_history_tab(self):
|
||||||
l = self.history_list
|
domain = self.wallet.get_account_addresses(self.current_account)
|
||||||
item = l.currentItem()
|
h = self.wallet.get_history(domain)
|
||||||
current_tx = item.data(0, Qt.UserRole).toString() if item else None
|
self.history_list.update(h)
|
||||||
l.clear()
|
|
||||||
for item in self.wallet.get_history(self.current_account):
|
|
||||||
tx_hash, conf, value, timestamp, balance = item
|
|
||||||
time_str = _("unknown")
|
|
||||||
if conf is None and timestamp is None:
|
|
||||||
continue # skip history in offline mode
|
|
||||||
if conf > 0:
|
|
||||||
time_str = format_time(timestamp)
|
|
||||||
if conf == -1:
|
|
||||||
time_str = 'unverified'
|
|
||||||
icon = QIcon(":icons/unconfirmed.png")
|
|
||||||
elif conf == 0:
|
|
||||||
time_str = 'pending'
|
|
||||||
icon = QIcon(":icons/unconfirmed.png")
|
|
||||||
elif conf < 6:
|
|
||||||
icon = QIcon(":icons/clock%d.png"%conf)
|
|
||||||
else:
|
|
||||||
icon = QIcon(":icons/confirmed.png")
|
|
||||||
v_str = self.format_amount(value, True, whitespaces=True)
|
|
||||||
balance_str = self.format_amount(balance, whitespaces=True)
|
|
||||||
label, is_default_label = self.wallet.get_label(tx_hash)
|
|
||||||
item = QTreeWidgetItem( [ '', time_str, label, v_str, balance_str] )
|
|
||||||
item.setFont(2, QFont(MONOSPACE_FONT))
|
|
||||||
item.setFont(3, QFont(MONOSPACE_FONT))
|
|
||||||
item.setFont(4, QFont(MONOSPACE_FONT))
|
|
||||||
if value < 0:
|
|
||||||
item.setForeground(3, QBrush(QColor("#BC1E1E")))
|
|
||||||
if tx_hash:
|
|
||||||
item.setData(0, Qt.UserRole, tx_hash)
|
|
||||||
if is_default_label:
|
|
||||||
item.setForeground(2, QBrush(QColor('grey')))
|
|
||||||
item.setIcon(0, icon)
|
|
||||||
l.insertTopLevelItem(0, item)
|
|
||||||
if current_tx == tx_hash:
|
|
||||||
l.setCurrentItem(item)
|
|
||||||
|
|
||||||
run_hook('history_tab_update')
|
|
||||||
|
|
||||||
|
|
||||||
def create_receive_tab(self):
|
def create_receive_tab(self):
|
||||||
w = QWidget()
|
w = QWidget()
|
||||||
|
@ -1480,7 +1382,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr))
|
menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr))
|
||||||
menu.addAction(_("Request payment"), lambda: self.receive_at(addr))
|
menu.addAction(_("Request payment"), lambda: self.receive_at(addr))
|
||||||
menu.addAction(_("Edit label"), lambda: self.edit_label(True))
|
menu.addAction(_("Edit label"), lambda: self.edit_label(True))
|
||||||
menu.addAction(_("Public keys"), lambda: self.show_public_keys(addr))
|
menu.addAction(_('History'), lambda: self.show_address(addr))
|
||||||
|
menu.addAction(_('Public Keys'), lambda: self.show_public_keys(addr))
|
||||||
if self.wallet.can_export():
|
if self.wallet.can_export():
|
||||||
menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
|
menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
|
||||||
if not self.wallet.is_watching_only():
|
if not self.wallet.is_watching_only():
|
||||||
|
|
|
@ -714,9 +714,10 @@ class Abstract_Wallet(object):
|
||||||
self.add_transaction(tx_hash, tx, tx_height)
|
self.add_transaction(tx_hash, tx, tx_height)
|
||||||
|
|
||||||
|
|
||||||
def get_history(self, account=None):
|
def get_history(self, domain=None):
|
||||||
# get domain
|
# get domain
|
||||||
domain = self.get_account_addresses(account)
|
if domain is None:
|
||||||
|
domain = self.get_account_addresses(None)
|
||||||
|
|
||||||
hh = []
|
hh = []
|
||||||
# 1. Get the history of each address in the domain
|
# 1. Get the history of each address in the domain
|
||||||
|
|
Loading…
Reference in New Issue