Browse Source

QAbstractItemModel: fix sorting, QAbstractItemDelegate usage, QVariant usage

3.3.3.1
Janus 6 years ago
committed by SomberNight
parent
commit
3960070a50
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/gui/qt/contact_list.py
  2. 27
      electrum/gui/qt/history_list.py
  3. 62
      electrum/gui/qt/util.py
  4. 2
      electrum/gui/qt/utxo_list.py
  5. 2
      electrum/wallet.py

8
electrum/gui/qt/contact_list.py

@ -49,12 +49,8 @@ class ContactList(MyTreeView):
def on_edited(self, idx, user_role, text):
_type, prior_name = self.parent.contacts.pop(user_role)
# TODO when min Qt >= 5.11, use siblingAtColumn
col_1_sibling = idx.sibling(idx.row(), 1)
col_1_item = self.model().itemFromIndex(col_1_sibling)
self.parent.set_contact(text, col_1_item.text())
self.parent.set_contact(text, user_role)
self.update()
def import_contacts(self):
import_meta_gui(self.parent, _('contacts'), self.parent.contacts.import_file, self.update)

27
electrum/gui/qt/history_list.py

@ -67,9 +67,6 @@ class HistorySortModel(QSortFilterProxyModel):
return False
return item1.value() < item2.value()
# requires PyQt5 5.11
indexIsValid = QAbstractItemModel.CheckIndexOptions(QAbstractItemModel.CheckIndexOption.IndexIsValid.value)
class HistoryModel(QAbstractItemModel):
def __init__(self, parent):
super().__init__(parent)
@ -80,14 +77,15 @@ class HistoryModel(QAbstractItemModel):
return 8
def rowCount(self, parent: QModelIndex):
l = len(self.transactions)
return l
return len(self.transactions)
def index(self, row: int, column: int, parent : QModelIndex):
return self.createIndex(row,column)
def data(self, index: QModelIndex, role: Qt.ItemDataRole):
assert self.checkIndex(index, indexIsValid)
# requires PyQt5 5.11
# indexIsValid = QAbstractItemModel.CheckIndexOptions(QAbstractItemModel.CheckIndexOption.IndexIsValid.value)
# assert self.checkIndex(index, indexIsValid)
assert index.isValid()
tx_item = self.transactions[index.row()]
tx_hash = tx_item['txid']
@ -169,6 +167,10 @@ class HistoryModel(QAbstractItemModel):
return self.parent.wallet.get_addresses()
def refresh(self, reason: str):
selected = self.parent.history_list.selectionModel().currentIndex()
selected_row = None
if selected:
selected_row = selected.row()
fx = self.parent.fx
if fx: fx.history_used_spot = False
r = self.parent.wallet.get_full_history(domain=self.get_domain(), from_timestamp=None, to_timestamp=None, fx=fx)
@ -182,6 +184,8 @@ class HistoryModel(QAbstractItemModel):
self.beginInsertRows(QModelIndex(), 0, len(r['transactions'])-1)
self.transactions = r['transactions']
self.endInsertRows()
if selected_row:
self.parent.history_list.selectionModel().select(self.createIndex(selected_row, 0), QItemSelectionModel.Rows | QItemSelectionModel.SelectCurrent)
f = self.parent.history_list.current_filter
if f:
self.parent.history_list.filter(f)
@ -279,7 +283,6 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
self.proxy.setSourceModel(model)
self.setModel(self.proxy)
self.summary = {}
self.config = parent.config
AcceptFileDragDrop.__init__(self, ".txn")
self.setSortingEnabled(True)
@ -374,7 +377,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
return datetime.datetime(date.year, date.month, date.day)
def show_summary(self):
h = self.summary
h = self.model().sourceModel().summary
if not h:
self.parent.show_message(_("Nothing to summarize."))
return
@ -425,7 +428,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
self.parent.show_message(str(e))
def on_edited(self, index, user_role, text):
print("on_edited")
index = self.model().mapToSource(index)
row, column = index.row(), index.column()
tx_item = self.hm.transactions[row]
key = tx_item['txid']
@ -438,7 +441,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
self.wallet.set_fiat_value(key, self.parent.fx.ccy, text, self.parent.fx, tx_item['value'].value)
value = tx_item['value'].value
if value is not None:
self.hm.update_fiat(row, self.model().mapToSource(index))
self.hm.update_fiat(row, index)
else:
assert False
@ -472,7 +475,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
column_data = tx_item['txid']
else:
column_title = self.hm.headerData(column, Qt.Horizontal, Qt.DisplayRole)
column_data = str(self.hm.data(idx, Qt.DisplayRole))
column_data = self.hm.data(idx, Qt.DisplayRole).value()
tx_hash = tx_item['txid']
tx = self.wallet.transactions[tx_hash]
tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
@ -595,4 +598,4 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
def text_txid_from_coordinate(self, row, col):
idx = self.model().mapToSource(self.model().index(row, col))
tx_item = self.hm.transactions[idx.row()]
return str(self.hm.data(idx, Qt.DisplayRole)), tx_item['txid']
return self.hm.data(idx, Qt.DisplayRole).value(), tx_item['txid']

62
electrum/gui/qt/util.py

@ -398,8 +398,23 @@ def filename_field(parent, config, defaultname, select_msg):
return vbox, filename_e, b1
class ElectrumItemDelegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
return self.parent().createEditor(parent, option, index)
def __init__(self, tv):
super().__init__(tv)
self.tv = tv
self.opened = None
def on_closeEditor(editor: QLineEdit, hint):
self.opened = None
def on_commitData(editor: QLineEdit):
new_text = editor.text()
idx = QModelIndex(self.opened)
_prior_text, user_role = self.tv.text_txid_from_coordinate(idx.row(), idx.column())
self.tv.on_edited(idx, user_role, new_text)
self.closeEditor.connect(on_closeEditor)
self.commitData.connect(on_commitData)
def createEditor(self, parent, option, idx):
self.opened = QPersistentModelIndex(idx)
return super().createEditor(parent, option, idx)
class MyTreeView(QTreeView):
@ -415,8 +430,6 @@ class MyTreeView(QTreeView):
self.icon_cache = IconCache()
# Control which columns are editable
self.editor = None
self.pending_update = False
if editable_columns is None:
editable_columns = {stretch_column}
else:
@ -458,7 +471,9 @@ class MyTreeView(QTreeView):
self.header().setSectionResizeMode(col, sm)
def keyPressEvent(self, event):
if event.key() in [ Qt.Key_F2, Qt.Key_Return ] and self.editor is None:
if self.itemDelegate().opened:
return
if event.key() in [ Qt.Key_F2, Qt.Key_Return ]:
self.on_activated(self.selectionModel().currentIndex())
return
super().keyPressEvent(event)
@ -469,36 +484,6 @@ class MyTreeView(QTreeView):
pt.setX(50)
self.customContextMenuRequested.emit(pt)
def createEditor(self, parent, option, idx):
self.editor = QStyledItemDelegate.createEditor(self.itemDelegate(),
parent, option, idx)
prior_text, user_role = self.text_txid_from_coordinate(idx.row(), idx.column())
def editing_finished():
print("editing finished")
# Long-time QT bug - pressing Enter to finish editing signals
# editingFinished twice. If the item changed the sequence is
# Enter key: editingFinished, on_change, editingFinished
# Mouse: on_change, editingFinished
# This mess is the cleanest way to ensure we make the
# on_edited callback with the updated item
if self.editor is None:
return
if self.editor.text() == prior_text:
print("unchanged ignore any 2nd call")
self.editor = None # Unchanged - ignore any 2nd call
return
if not idx.isValid():
print("idx not valid")
return
new_text, _ = self.text_txid_from_coordinate(idx.row(), idx.column())
if new_text == prior_text:
print("buggy first call", new_text, prior_text)
return # Buggy first call on Enter key, item not yet updated
self.on_edited(idx, user_role, self.editor.text())
self.editor = None
self.editor.editingFinished.connect(editing_finished)
return self.editor
def edit(self, idx, trigger=QAbstractItemView.AllEditTriggers, event=None):
"""
this is to prevent:
@ -509,7 +494,7 @@ class MyTreeView(QTreeView):
def on_edited(self, idx: QModelIndex, user_role, text):
self.parent.wallet.set_label(user_role, text)
self.parent.history_list.update_labels()
self.parent.history_model.refresh('on_edited in MyTreeView')
self.parent.update_completions()
def should_hide(self, row):
@ -523,7 +508,10 @@ class MyTreeView(QTreeView):
assert not isinstance(self.model(), QSortFilterProxyModel)
idx = self.model().index(row_num, column)
item = self.model().itemFromIndex(idx)
return item.text(), item.data(Qt.UserRole)
user_role = item.data(Qt.UserRole)
# check that we didn't forget to set UserRole on an editable field
assert user_role is not None, (row_num, column)
return item.text(), user_role
def hide_row(self, row_num):
"""

2
electrum/gui/qt/utxo_list.py

@ -33,7 +33,7 @@ class UTXOList(MyTreeView):
filter_columns = [0, 1] # Address, Label
def __init__(self, parent=None):
super().__init__(parent, self.create_menu, 1)
super().__init__(parent, self.create_menu, 1, editable_columns=[])
self.setModel(QStandardItemModel(self))
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setSortingEnabled(True)

2
electrum/wallet.py

@ -239,7 +239,7 @@ class Abstract_Wallet(AddressSynchronizer):
self.labels[name] = text
changed = True
else:
if old_text:
if old_text is not None:
self.labels.pop(name)
changed = True
if changed:

Loading…
Cancel
Save