mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-03 20:35:13 +00:00
QAbstractItemModel: fix sorting, QAbstractItemDelegate usage, QVariant usage
This commit is contained in:
parent
4eb4b341db
commit
3960070a50
5 changed files with 44 additions and 57 deletions
|
@ -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)
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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…
Add table
Reference in a new issue