commit 93250b10417299e8b8c6681df8cb5b4120d0f582
parent b8a72180c7a5d3198b2f8d299d9247b8eabda952
Author: ThomasV <thomasv@gitorious>
Date: Sat, 4 Apr 2015 20:59:57 +0200
gui simplification
Diffstat:
3 files changed, 159 insertions(+), 90 deletions(-)
diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+# Electrum - lightweight Bitcoin client
+# Copyright (C) 2015 Thomas Voegtlin
+#
+# 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 webbrowser
+
+from util import *
+from electrum.i18n import _
+from electrum.util import format_satoshis, format_time
+from electrum.plugins import run_hook
+
+
+class HistoryWidget(MyTreeWidget):
+
+ def __init__(self, parent=None):
+ MyTreeWidget.__init__(self, parent, self.create_menu, [ '', _('Date'), _('Description') , _('Amount'), _('Balance')], [40, 140, None, 140, 140])
+ self.config = self.parent.config
+
+ def update(self, h):
+ self.wallet = self.parent.wallet
+ item = self.currentItem()
+ current_tx = item.data(0, Qt.UserRole).toString() if item else None
+ self.clear()
+ for item in h:
+ 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.parent.format_amount(value, True, whitespaces=True)
+ balance_str = self.parent.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)
+ self.insertTopLevelItem(0, item)
+ if current_tx == tx_hash:
+ self.setCurrentItem(item)
+
+ run_hook('history_tab_update')
+
+
+ def create_menu(self, position):
+ self.selectedIndexes()
+ item = self.currentItem()
+ be = self.config.get('block_explorer', 'Blockchain.info')
+ 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.parent.app.clipboard().setText(tx_hash))
+ menu.addAction(_("Details"), lambda: self.parent.show_transaction(self.wallet.transactions.get(tx_hash)))
+ menu.addAction(_("Edit description"), lambda: self.edit_label(item, 2))
+ menu.addAction(_("View on block explorer"), lambda: webbrowser.open(block_explorer + tx_hash))
+ menu.exec_(self.viewport().mapToGlobal(position))
+
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -556,41 +556,6 @@ class ElectrumWindow(QMainWindow):
d = transaction_dialog.TxDialog(tx, self)
d.exec_()
- def edit_label(self, is_recv):
- l = self.address_list if is_recv else self.contacts_list
- item = l.currentItem()
- item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
- l.editItem( item, 1 )
- item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
-
- def address_label_clicked(self, item, column, l, column_addr, column_label):
- if column == column_label and item.isSelected():
- is_editable = item.data(0, 32).toBool()
- if not is_editable:
- return
- addr = unicode( item.text(column_addr) )
- label = unicode( item.text(column_label) )
- item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
- l.editItem( item, column )
- item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
-
- def address_label_changed(self, item, column, l, column_addr, column_label):
- if column == column_label:
- addr = unicode( item.text(column_addr) )
- text = unicode( item.text(column_label) )
- is_editable = item.data(0, 32).toBool()
- if not is_editable:
- return
- changed = self.wallet.set_label(addr, text)
- if changed:
- self.update_history_tab()
- self.update_completions()
- self.current_item_changed(item)
- run_hook('item_changed', item, column)
-
- def current_item_changed(self, a):
- run_hook('current_item_changed', a)
-
def update_history_tab(self):
domain = self.wallet.get_account_addresses(self.current_account)
h = self.wallet.get_history(domain)
@@ -645,11 +610,9 @@ class ElectrumWindow(QMainWindow):
grid.setRowStretch(6, 1)
self.receive_requests_label = QLabel(_('Saved Requests'))
- self.receive_list = MyTreeWidget(self)
- self.receive_list.customContextMenuRequested.connect(self.receive_list_menu)
+ self.receive_list = MyTreeWidget(self, self.receive_list_menu, [_('Date'), _('Account'), _('Address'), _('Message'), _('Amount')], [])
self.receive_list.currentItemChanged.connect(self.receive_item_changed)
self.receive_list.itemClicked.connect(self.receive_item_changed)
- self.receive_list.setHeaderLabels( [_('Date'), _('Account'), _('Address'), _('Message'), _('Amount')] )
self.receive_list.setSortingEnabled(True)
self.receive_list.setColumnWidth(0, 180)
self.receive_list.hideColumn(1) # the update will show it if necessary
@@ -843,14 +806,9 @@ class ElectrumWindow(QMainWindow):
self.from_label = QLabel(_('From'))
grid.addWidget(self.from_label, 3, 0)
- self.from_list = MyTreeWidget(self)
- self.from_list.setColumnCount(2)
- self.from_list.setColumnWidth(0, 350)
- self.from_list.setColumnWidth(1, 50)
+ self.from_list = MyTreeWidget(self, self.from_list_menu, ['',''], [350, 50])
self.from_list.setHeaderHidden(True)
self.from_list.setMaximumHeight(80)
- self.from_list.setContextMenuPolicy(Qt.CustomContextMenu)
- self.from_list.customContextMenuRequested.connect(self.from_list_menu)
grid.addWidget(self.from_list, 3, 1, 1, 3)
self.set_pay_from([])
@@ -1242,13 +1200,7 @@ class ElectrumWindow(QMainWindow):
self.wallet.freeze(addr)
self.update_address_tab()
-
-
- def create_list_tab(self, headers):
- "generic tab creation method"
- l = MyTreeWidget(self)
- l.setColumnCount( len(headers) )
- l.setHeaderLabels( headers )
+ def create_list_tab(self, l):
w = QWidget()
vbox = QVBoxLayout()
w.setLayout(vbox)
@@ -1257,52 +1209,23 @@ class ElectrumWindow(QMainWindow):
vbox.addWidget(l)
buttons = QWidget()
vbox.addWidget(buttons)
- return l, w
+ return w
def create_addresses_tab(self):
- column_width = [370, 200, 130]
- l, w = self.create_list_tab([ _('Address'), _('Label'), _('Balance'), _('Tx')])
- l.header().setResizeMode(1, QHeaderView.Stretch);
- l.header().setStretchLastSection(False)
- for i,width in enumerate(column_width):
- l.setColumnWidth(i, width)
- l.setContextMenuPolicy(Qt.CustomContextMenu)
- l.customContextMenuRequested.connect(self.create_receive_menu)
+ l = MyTreeWidget(self, self.create_receive_menu, [ _('Address'), _('Label'), _('Balance'), _('Tx')], [370, None, 130])
l.setSelectionMode(QAbstractItemView.ExtendedSelection)
- l.itemDoubleClicked.connect(lambda a, b: self.address_label_clicked(a,b,l,0,1))
- l.itemChanged.connect(lambda a,b: self.address_label_changed(a,b,l,0,1))
- l.currentItemChanged.connect(lambda a,b: self.current_item_changed(a))
self.address_list = l
- return w
+ return self.create_list_tab(l)
def create_contacts_tab(self):
- column_width = [350,330]
- l, w = self.create_list_tab([_('Address'), _('Label'), _('Tx')])
- l.header().setResizeMode(1, QHeaderView.Stretch);
- l.header().setStretchLastSection(False)
- l.setContextMenuPolicy(Qt.CustomContextMenu)
- l.customContextMenuRequested.connect(self.create_contact_menu)
- for i,width in enumerate(column_width):
- l.setColumnWidth(i, width)
- l.itemDoubleClicked.connect(lambda a, b: self.address_label_clicked(a,b,l,0,1))
- l.itemChanged.connect(lambda a,b: self.address_label_changed(a,b,l,0,1))
+ l = MyTreeWidget(self, self.create_contact_menu, [_('Address'), _('Label'), _('Tx')], [350, None])
self.contacts_list = l
- return w
-
+ return self.create_list_tab(l)
def create_invoices_tab(self):
- l, w = self.create_list_tab([_('Date'), _('Requestor'), _('Memo'), _('Amount'), _('Status')])
- l.setColumnWidth(0, 150)
- l.setColumnWidth(1, 150)
- l.setColumnWidth(3, 150)
- l.setColumnWidth(4, 40)
- h = l.header()
- h.setStretchLastSection(False)
- h.setResizeMode(2, QHeaderView.Stretch)
- l.setContextMenuPolicy(Qt.CustomContextMenu)
- l.customContextMenuRequested.connect(self.create_invoice_menu)
+ l = MyTreeWidget(self, self.create_invoice_menu, [_('Date'), _('Requestor'), _('Memo'), _('Amount'), _('Status')], [150, 150, None, 150, 40])
self.invoices_list = l
- return w
+ return self.create_list_tab(l)
def update_invoices_tab(self):
invoices = self.wallet.storage.get('invoices', {})
diff --git a/gui/qt/util.py b/gui/qt/util.py
@@ -253,16 +253,34 @@ def filename_field(parent, config, defaultname, select_msg):
class MyTreeWidget(QTreeWidget):
- def __init__(self, parent):
+ def __init__(self, parent, create_menu, headers, column_width):
QTreeWidget.__init__(self, parent)
+ self.parent = parent
+ self.setColumnCount(len(headers))
+ self.setHeaderLabels(headers)
+ self.header().setStretchLastSection(False)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.itemActivated.connect(self.on_activated)
+ self.customContextMenuRequested.connect(create_menu)
# extend the syntax for consistency
self.addChild = self.addTopLevelItem
self.insertChild = self.insertTopLevelItem
+ # editable column
+ self.is_edit = False
+ self.edit_column = None
+ self.itemDoubleClicked.connect(self.edit_label)
+ self.itemChanged.connect(self.label_changed)
+ # set column width
+ for i, width in enumerate(column_width):
+ if width is None:
+ self.header().setResizeMode(i, QHeaderView.Stretch)
+ self.edit_column = i
+ else:
+ self.setColumnWidth(i, width)
def on_activated(self, item):
- if not item: return
+ if not item:
+ return
for i in range(0,self.viewport().height()/5):
if self.itemAt(QPoint(0,i*5)) == item:
break
@@ -273,7 +291,35 @@ class MyTreeWidget(QTreeWidget):
break
self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), QPoint(50, i*5 + j - 1))
-
+ def edit_label(self, item, column):
+ if column==self.edit_column and item.isSelected():
+ text = unicode(item.text(column))
+ tx_hash = str(item.data(0, Qt.UserRole).toString())
+ self.is_edit = True
+ if text == self.parent.wallet.get_default_label(tx_hash):
+ item.setText(column, '')
+ item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
+ self.editItem(item, column)
+ item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
+ self.is_edit = False
+
+ def label_changed(self, item, column):
+ if self.is_edit:
+ return
+ self.is_edit = True
+ key = str(item.data(0, Qt.UserRole).toString())
+ text = unicode(item.text(self.edit_column))
+ changed = self.parent.wallet.set_label(key, text)
+ if text:
+ item.setForeground(self.edit_column, QBrush(QColor('black')))
+ else:
+ text = self.wallet.get_default_label(key)
+ item.setText(self.edit_column, text)
+ item.setForeground(self.edit_column, QBrush(QColor('gray')))
+ self.is_edit = False
+ if changed:
+ self.parent.update_history_tab()
+ self.parent.update_completions()
if __name__ == "__main__":