Browse Source

qml: fixes and cleanup for qedaemon, qenetwork. expose many wallet properties in qewallet

patch-4
Sander van Grieken 4 years ago
parent
commit
6e482f437a
  1. 25
      electrum/gui/qml/qedaemon.py
  2. 39
      electrum/gui/qml/qenetwork.py
  3. 93
      electrum/gui/qml/qewallet.py

25
electrum/gui/qml/qedaemon.py

@ -28,15 +28,6 @@ class QEWalletListModel(QAbstractListModel):
def roleNames(self): def roleNames(self):
return self._ROLE_MAP return self._ROLE_MAP
def data(self, index, role):
role_index = role - (Qt.UserRole + 1)
value = tx[self._ROLE_NAMES[role_index]]
if isinstance(value, bool) or isinstance(value, list) or isinstance(value, int) or value is None:
return value
if isinstance(value, Satoshis):
return value.value
return str(value)
def data(self, index, role): def data(self, index, role):
(wallet_name, wallet_path, wallet) = self.wallets[index.row()] (wallet_name, wallet_path, wallet) = self.wallets[index.row()]
role_index = role - (Qt.UserRole + 1) role_index = role - (Qt.UserRole + 1)
@ -44,7 +35,7 @@ class QEWalletListModel(QAbstractListModel):
if role_name == 'name': if role_name == 'name':
return wallet_name return wallet_name
if role_name == 'path': if role_name == 'path':
return wallet_name return wallet_path
if role_name == 'active': if role_name == 'active':
return wallet != None return wallet != None
@ -72,8 +63,13 @@ class QEDaemon(QObject):
walletLoaded = pyqtSignal() walletLoaded = pyqtSignal()
walletRequiresPassword = pyqtSignal() walletRequiresPassword = pyqtSignal()
_current_wallet = None
@pyqtSlot() @pyqtSlot()
@pyqtSlot(str)
@pyqtSlot(str, str)
def load_wallet(self, path=None, password=None): def load_wallet(self, path=None, password=None):
self._logger.debug('load wallet ' + str(path))
if path == None: if path == None:
path = self.daemon.config.get('gui_last_wallet') path = self.daemon.config.get('gui_last_wallet')
wallet = self.daemon.load_wallet(path, password) wallet = self.daemon.load_wallet(path, password)
@ -91,7 +87,9 @@ class QEDaemon(QObject):
@pyqtProperty('QString',notify=walletLoaded) @pyqtProperty('QString',notify=walletLoaded)
def walletName(self): def walletName(self):
return self._current_wallet.wallet.basename() if self._current_wallet != None:
return self._current_wallet.wallet.basename()
return ''
@pyqtProperty(QEWalletListModel) @pyqtProperty(QEWalletListModel)
def activeWallets(self): def activeWallets(self):
@ -108,8 +106,5 @@ class QEDaemon(QObject):
available.append(i.path) available.append(i.path)
for path in sorted(available): for path in sorted(available):
wallet = self.daemon.get_wallet(path) wallet = self.daemon.get_wallet(path)
if wallet != None: availableListModel.add_wallet(wallet_path = path, wallet = wallet)
availableListModel.add_wallet(wallet_path = wallet.storage.path, wallet = wallet)
else:
availableListModel.add_wallet(wallet_path = path)
return availableListModel return availableListModel

39
electrum/gui/qml/qenetwork.py

@ -2,6 +2,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.util import register_callback from electrum.util import register_callback
from electrum.logging import get_logger from electrum.logging import get_logger
from electrum import constants
class QENetwork(QObject): class QENetwork(QObject):
def __init__(self, network, parent=None): def __init__(self, network, parent=None):
@ -15,11 +16,13 @@ class QENetwork(QObject):
_logger = get_logger(__name__) _logger = get_logger(__name__)
network_updated = pyqtSignal() networkUpdated = pyqtSignal()
blockchain_updated = pyqtSignal() blockchainUpdated = pyqtSignal()
default_server_changed = pyqtSignal() defaultServerChanged = pyqtSignal()
proxy_set = pyqtSignal() proxySet = pyqtSignal()
status_updated = pyqtSignal() statusUpdated = pyqtSignal()
dataChanged = pyqtSignal() # dummy to silence warnings
_num_updates = 0 _num_updates = 0
_server = "" _server = ""
@ -28,40 +31,48 @@ class QENetwork(QObject):
def on_network_updated(self, event, *args): def on_network_updated(self, event, *args):
self._num_updates = self._num_updates + 1 self._num_updates = self._num_updates + 1
self.network_updated.emit() self.networkUpdated.emit()
def on_blockchain_updated(self, event, *args): def on_blockchain_updated(self, event, *args):
self._logger.info('chainupdate: ' + str(event) + str(args)) self._logger.info('chainupdate: ' + str(event) + str(args))
self._height = self.network.get_local_height() self._height = self.network.get_local_height()
self.blockchain_updated.emit() self.blockchainUpdated.emit()
def on_default_server_changed(self, event, *args): def on_default_server_changed(self, event, *args):
netparams = self.network.get_parameters() netparams = self.network.get_parameters()
self._server = str(netparams.server) self._server = str(netparams.server)
self.default_server_changed.emit() self.defaultServerChanged.emit()
def on_proxy_set(self, event, *args): def on_proxy_set(self, event, *args):
self._logger.info('proxy set') self._logger.info('proxy set')
self.proxy_set.emit() self.proxySet.emit()
def on_status(self, event, *args): def on_status(self, event, *args):
self._logger.info('status updated') self._logger.info('status updated')
self._status = self.network.connection_status self._status = self.network.connection_status
self.status_updated.emit() self.statusUpdated.emit()
@pyqtProperty(int,notify=network_updated) @pyqtProperty(int,notify=networkUpdated)
def updates(self): def updates(self):
return self._num_updates return self._num_updates
@pyqtProperty(int,notify=blockchain_updated) @pyqtProperty(int,notify=blockchainUpdated)
def height(self): def height(self):
return self._height return self._height
@pyqtProperty('QString',notify=default_server_changed) @pyqtProperty('QString',notify=defaultServerChanged)
def server(self): def server(self):
return self._server return self._server
@pyqtProperty('QString',notify=status_updated) @pyqtProperty('QString',notify=statusUpdated)
def status(self): def status(self):
return self._status return self._status
@pyqtProperty(bool, notify=dataChanged)
def isTestNet(self):
return constants.net.TESTNET
@pyqtProperty('QString', notify=dataChanged)
def networkName(self):
return constants.net.__name__.replace('Bitcoin','')

93
electrum/gui/qml/qewallet.py

@ -4,6 +4,9 @@ from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex, QByteArray
from electrum.util import register_callback, Satoshis from electrum.util import register_callback, Satoshis
from electrum.logging import get_logger from electrum.logging import get_logger
from electrum.wallet import Wallet, Abstract_Wallet from electrum.wallet import Wallet, Abstract_Wallet
from electrum import bitcoin
from electrum.transaction import Transaction, tx_from_any, PartialTransaction, PartialTxOutput
from electrum.invoices import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED, PR_UNCONFIRMED, PR_TYPE_ONCHAIN, PR_TYPE_LN
class QETransactionsListModel(QAbstractListModel): class QETransactionsListModel(QAbstractListModel):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -13,11 +16,10 @@ class QETransactionsListModel(QAbstractListModel):
_logger = get_logger(__name__) _logger = get_logger(__name__)
# define listmodel rolemap # define listmodel rolemap
ROLES=('txid','fee_sat','height','confirmations','timestamp','monotonic_timestamp','incoming','bc_value', _ROLE_NAMES=('txid','fee_sat','height','confirmations','timestamp','monotonic_timestamp','incoming','bc_value',
'bc_balance','date','label','txpos_in_block','fee','inputs','outputs') 'bc_balance','date','label','txpos_in_block','fee','inputs','outputs')
keys = range(Qt.UserRole + 1, Qt.UserRole + 1 + len(ROLES)) _ROLE_KEYS = range(Qt.UserRole + 1, Qt.UserRole + 1 + len(_ROLE_NAMES))
ROLENAMES = [bytearray(x.encode()) for x in ROLES] _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES]))
_ROLE_MAP = dict(zip(keys, ROLENAMES))
def rowCount(self, index): def rowCount(self, index):
return len(self.tx_history) return len(self.tx_history)
@ -28,14 +30,21 @@ class QETransactionsListModel(QAbstractListModel):
def data(self, index, role): def data(self, index, role):
tx = self.tx_history[index.row()] tx = self.tx_history[index.row()]
role_index = role - (Qt.UserRole + 1) role_index = role - (Qt.UserRole + 1)
value = tx[self.ROLES[role_index]] value = tx[self._ROLE_NAMES[role_index]]
if isinstance(value, bool) or isinstance(value, list) or isinstance(value, int) or value is None: if isinstance(value, bool) or isinstance(value, list) or isinstance(value, int) or value is None:
return value return value
if isinstance(value, Satoshis): if isinstance(value, Satoshis):
return value.value return value.value
return str(value) return str(value)
def clear(self):
self.beginResetModel()
self.tx_history = []
self.endResetModel()
# initial model data
def set_history(self, history): def set_history(self, history):
self.clear()
self.beginInsertRows(QModelIndex(), 0, len(history) - 1) self.beginInsertRows(QModelIndex(), 0, len(history) - 1)
self.tx_history = history self.tx_history = history
self.tx_history.reverse() self.tx_history.reverse()
@ -45,23 +54,91 @@ class QEWallet(QObject):
def __init__(self, wallet, parent=None): def __init__(self, wallet, parent=None):
super().__init__(parent) super().__init__(parent)
self.wallet = wallet self.wallet = wallet
self._historyModel = QETransactionsListModel()
self.get_history() self.get_history()
register_callback(self.on_request_status, ['request_status'])
_logger = get_logger(__name__) _logger = get_logger(__name__)
_historyModel = QETransactionsListModel() dataChanged = pyqtSignal() # dummy to silence warnings
@pyqtProperty(QETransactionsListModel) requestStatus = pyqtSignal()
def on_request_status(self, event, *args):
self._logger.debug(str(event))
# (wallet, addr, status) = args
# self._historyModel.add_tx()
self.requestStatus.emit()
historyModelChanged = pyqtSignal()
@pyqtProperty(QETransactionsListModel, notify=historyModelChanged)
def historyModel(self): def historyModel(self):
return self._historyModel return self._historyModel
@pyqtProperty('QString', notify=dataChanged)
def txinType(self):
return self.wallet.get_txin_type(self.wallet.dummy_address())
@pyqtProperty(bool, notify=dataChanged)
def isWatchOnly(self):
return self.wallet.is_watching_only()
@pyqtProperty(bool, notify=dataChanged)
def isDeterministic(self):
return self.wallet.is_deterministic()
@pyqtProperty(bool, notify=dataChanged)
def isEncrypted(self):
return self.wallet.storage.is_encrypted()
@pyqtProperty(bool, notify=dataChanged)
def isHardware(self):
return self.wallet.storage.is_encrypted_with_hw_device()
@pyqtProperty('QString', notify=dataChanged)
def derivationPath(self):
return self.wallet.get_address_path_str(self.wallet.dummy_address())
balanceChanged = pyqtSignal()
@pyqtProperty(int, notify=balanceChanged)
def frozenBalance(self):
return self.wallet.get_frozen_balance()
@pyqtProperty(int, notify=balanceChanged)
def unconfirmedBalance(self):
return self.wallet.get_balance()[1]
@pyqtProperty(int, notify=balanceChanged)
def confirmedBalance(self):
c, u, x = self.wallet.get_balance()
self._logger.info('balance: ' + str(c) + ' ' + str(u) + ' ' + str(x) + ' ')
return c+x
# lightning feature?
isUptodateChanged = pyqtSignal()
@pyqtProperty(bool, notify=isUptodateChanged)
def isUptodate(self):
return self.wallet.is_up_to_date()
def get_history(self): def get_history(self):
history = self.wallet.get_detailed_history(show_addresses = True) history = self.wallet.get_detailed_history(show_addresses = True)
txs = history['transactions'] txs = history['transactions']
self._logger.info(txs)
# use primitives # use primitives
for tx in txs: for tx in txs:
for output in tx['outputs']: for output in tx['outputs']:
output['value'] = output['value'].value output['value'] = output['value'].value
self._historyModel.set_history(txs) self._historyModel.set_history(txs)
self.historyModelChanged.emit()
@pyqtSlot('QString', int, int, bool)
def send_onchain(self, address, amount, fee=None, rbf=False):
self._logger.info('send_onchain: ' + address + ' ' + str(amount))
coins = self.wallet.get_spendable_coins(None)
if not bitcoin.is_address(address):
self._logger.warning('Invalid Bitcoin Address: ' + address)
return False
outputs = [PartialTxOutput.from_address_and_value(address, amount)]
tx = self.wallet.make_unsigned_transaction(coins=coins,outputs=outputs)
return True

Loading…
Cancel
Save