qt: MyTreeView: disambiguate "parent" and "main_window"
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
import enum
|
||||
from enum import IntEnum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import Qt, QPersistentModelIndex, QModelIndex
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QFont
|
||||
@@ -38,6 +39,9 @@ from electrum.wallet import InternalAddressCorruption
|
||||
|
||||
from .util import MyTreeView, MONOSPACE_FONT, ColorScheme, webopen, MySortModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
class AddressUsageStateFilter(IntEnum):
|
||||
ALL = 0
|
||||
@@ -85,12 +89,13 @@ class AddressList(MyTreeView):
|
||||
ROLE_ADDRESS_STR = Qt.UserRole + 1001
|
||||
key_role = ROLE_ADDRESS_STR
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent, self.create_menu,
|
||||
stretch_column=self.Columns.LABEL,
|
||||
editable_columns=[self.Columns.LABEL])
|
||||
self.main_window = parent
|
||||
self.wallet = self.parent.wallet
|
||||
def __init__(self, main_window: 'ElectrumWindow'):
|
||||
super().__init__(
|
||||
main_window=main_window,
|
||||
stretch_column=self.Columns.LABEL,
|
||||
editable_columns=[self.Columns.LABEL],
|
||||
)
|
||||
self.wallet = self.main_window.wallet
|
||||
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.setSortingEnabled(True)
|
||||
self.show_change = AddressTypeFilter.ALL # type: AddressTypeFilter
|
||||
@@ -120,7 +125,7 @@ class AddressList(MyTreeView):
|
||||
return toolbar
|
||||
|
||||
def should_show_fiat(self):
|
||||
return self.parent.fx and self.parent.fx.is_enabled() and self.config.get('fiat_address', False)
|
||||
return self.main_window.fx and self.main_window.fx.is_enabled() and self.config.get('fiat_address', False)
|
||||
|
||||
def get_toolbar_buttons(self):
|
||||
return self.change_button, self.used_button
|
||||
@@ -132,7 +137,7 @@ class AddressList(MyTreeView):
|
||||
|
||||
def refresh_headers(self):
|
||||
if self.should_show_fiat():
|
||||
ccy = self.parent.fx.get_currency()
|
||||
ccy = self.main_window.fx.get_currency()
|
||||
else:
|
||||
ccy = _('Fiat')
|
||||
headers = {
|
||||
@@ -171,7 +176,7 @@ class AddressList(MyTreeView):
|
||||
self.proxy.setDynamicSortFilter(False) # temp. disable re-sorting after every change
|
||||
self.std_model.clear()
|
||||
self.refresh_headers()
|
||||
fx = self.parent.fx
|
||||
fx = self.main_window.fx
|
||||
set_address = None
|
||||
num_shown = 0
|
||||
self.addresses_beyond_gap_limit = self.wallet.get_all_known_addresses_beyond_gap_limit()
|
||||
@@ -236,9 +241,9 @@ class AddressList(MyTreeView):
|
||||
num = self.wallet.adb.get_address_history_len(address)
|
||||
c, u, x = self.wallet.get_addr_balance(address)
|
||||
balance = c + u + x
|
||||
balance_text = self.parent.format_amount(balance, whitespaces=True)
|
||||
balance_text = self.main_window.format_amount(balance, whitespaces=True)
|
||||
# create item
|
||||
fx = self.parent.fx
|
||||
fx = self.main_window.fx
|
||||
if self.should_show_fiat():
|
||||
rate = fx.exchange_rate()
|
||||
fiat_balance_str = fx.value_str(balance, rate)
|
||||
@@ -276,37 +281,37 @@ class AddressList(MyTreeView):
|
||||
addr_column_title = self.std_model.horizontalHeaderItem(self.Columns.LABEL).text()
|
||||
addr_idx = idx.sibling(idx.row(), self.Columns.LABEL)
|
||||
self.add_copy_menu(menu, idx)
|
||||
menu.addAction(_('Details'), lambda: self.parent.show_address(addr))
|
||||
menu.addAction(_('Details'), lambda: self.main_window.show_address(addr))
|
||||
persistent = QPersistentModelIndex(addr_idx)
|
||||
menu.addAction(_("Edit {}").format(addr_column_title), lambda p=persistent: self.edit(QModelIndex(p)))
|
||||
#menu.addAction(_("Request payment"), lambda: self.parent.receive_at(addr))
|
||||
#menu.addAction(_("Request payment"), lambda: self.main_window.receive_at(addr))
|
||||
if self.wallet.can_export():
|
||||
menu.addAction(_("Private key"), lambda: self.parent.show_private_key(addr))
|
||||
menu.addAction(_("Private key"), lambda: self.main_window.show_private_key(addr))
|
||||
if not is_multisig and not self.wallet.is_watching_only():
|
||||
menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr))
|
||||
menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr))
|
||||
menu.addAction(_("Sign/verify message"), lambda: self.main_window.sign_verify_message(addr))
|
||||
menu.addAction(_("Encrypt/decrypt message"), lambda: self.main_window.encrypt_message(addr))
|
||||
if can_delete:
|
||||
menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr))
|
||||
menu.addAction(_("Remove from wallet"), lambda: self.main_window.remove_address(addr))
|
||||
addr_URL = block_explorer_URL(self.config, 'addr', addr)
|
||||
if addr_URL:
|
||||
menu.addAction(_("View on block explorer"), lambda: webopen(addr_URL))
|
||||
|
||||
if not self.wallet.is_frozen_address(addr):
|
||||
menu.addAction(_("Freeze"), lambda: self.parent.set_frozen_state_of_addresses([addr], True))
|
||||
menu.addAction(_("Freeze"), lambda: self.main_window.set_frozen_state_of_addresses([addr], True))
|
||||
else:
|
||||
menu.addAction(_("Unfreeze"), lambda: self.parent.set_frozen_state_of_addresses([addr], False))
|
||||
menu.addAction(_("Unfreeze"), lambda: self.main_window.set_frozen_state_of_addresses([addr], False))
|
||||
|
||||
else:
|
||||
# multiple items selected
|
||||
menu.addAction(_("Freeze"), lambda: self.parent.set_frozen_state_of_addresses(addrs, True))
|
||||
menu.addAction(_("Unfreeze"), lambda: self.parent.set_frozen_state_of_addresses(addrs, False))
|
||||
menu.addAction(_("Freeze"), lambda: self.main_window.set_frozen_state_of_addresses(addrs, True))
|
||||
menu.addAction(_("Unfreeze"), lambda: self.main_window.set_frozen_state_of_addresses(addrs, False))
|
||||
|
||||
coins = self.wallet.get_spendable_coins(addrs)
|
||||
if coins:
|
||||
if self.parent.utxo_list.are_in_coincontrol(coins):
|
||||
menu.addAction(_("Remove from coin control"), lambda: self.parent.utxo_list.remove_from_coincontrol(coins))
|
||||
if self.main_window.utxo_list.are_in_coincontrol(coins):
|
||||
menu.addAction(_("Remove from coin control"), lambda: self.main_window.utxo_list.remove_from_coincontrol(coins))
|
||||
else:
|
||||
menu.addAction(_("Add to coin control"), lambda: self.parent.utxo_list.add_to_coincontrol(coins))
|
||||
menu.addAction(_("Add to coin control"), lambda: self.main_window.utxo_list.add_to_coincontrol(coins))
|
||||
|
||||
run_hook('receive_menu', menu, addrs, self.wallet)
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
@@ -316,7 +321,7 @@ class AddressList(MyTreeView):
|
||||
try:
|
||||
self.wallet.check_address_for_corruption(text)
|
||||
except InternalAddressCorruption as e:
|
||||
self.parent.show_error(str(e))
|
||||
self.main_window.show_error(str(e))
|
||||
raise
|
||||
super().place_text_on_clipboard(text, title=title)
|
||||
|
||||
@@ -326,7 +331,7 @@ class AddressList(MyTreeView):
|
||||
return self.get_role_data_from_coordinate(row, 0, role=self.ROLE_ADDRESS_STR)
|
||||
|
||||
def on_edited(self, idx, edit_key, *, text):
|
||||
self.parent.wallet.set_label(edit_key, text)
|
||||
self.parent.history_model.refresh('address label edited')
|
||||
self.parent.utxo_list.update()
|
||||
self.parent.update_completions()
|
||||
self.wallet.set_label(edit_key, text)
|
||||
self.main_window.history_model.refresh('address label edited')
|
||||
self.main_window.utxo_list.update()
|
||||
self.main_window.update_completions()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import traceback
|
||||
import enum
|
||||
from typing import Sequence, Optional, Dict
|
||||
from typing import Sequence, Optional, Dict, TYPE_CHECKING
|
||||
from abc import abstractmethod, ABC
|
||||
|
||||
from PyQt5 import QtCore, QtGui
|
||||
@@ -24,6 +24,9 @@ from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButto
|
||||
from .amountedit import BTCAmountEdit, FreezableLineEdit
|
||||
from .util import read_QIcon, font_height
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
ROLE_CHANNEL_ID = Qt.UserRole
|
||||
|
||||
@@ -63,16 +66,18 @@ class ChannelsList(MyTreeView):
|
||||
|
||||
_default_item_bg_brush = None # type: Optional[QBrush]
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent, self.create_menu, stretch_column=self.Columns.NODE_ALIAS)
|
||||
def __init__(self, main_window: 'ElectrumWindow'):
|
||||
super().__init__(
|
||||
main_window=main_window,
|
||||
stretch_column=self.Columns.NODE_ALIAS,
|
||||
)
|
||||
self.setModel(QtGui.QStandardItemModel(self))
|
||||
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.main_window = parent
|
||||
self.gossip_db_loaded.connect(self.on_gossip_db)
|
||||
self.update_rows.connect(self.do_update_rows)
|
||||
self.update_single_row.connect(self.do_update_single_row)
|
||||
self.network = self.parent.network
|
||||
self.wallet = self.parent.wallet
|
||||
self.network = self.main_window.network
|
||||
self.wallet = self.main_window.wallet
|
||||
self.setSortingEnabled(True)
|
||||
|
||||
@property
|
||||
@@ -85,12 +90,12 @@ class ChannelsList(MyTreeView):
|
||||
for subject in (REMOTE, LOCAL):
|
||||
if isinstance(chan, Channel):
|
||||
can_send = chan.available_to_spend(subject) / 1000
|
||||
label = self.parent.format_amount(can_send, whitespaces=True)
|
||||
label = self.main_window.format_amount(can_send, whitespaces=True)
|
||||
other = subject.inverted()
|
||||
bal_other = chan.balance(other)//1000
|
||||
bal_minus_htlcs_other = chan.balance_minus_outgoing_htlcs(other)//1000
|
||||
if bal_other != bal_minus_htlcs_other:
|
||||
label += ' (+' + self.parent.format_amount(bal_other - bal_minus_htlcs_other, whitespaces=False) + ')'
|
||||
label += ' (+' + self.main_window.format_amount(bal_other - bal_minus_htlcs_other, whitespaces=False) + ')'
|
||||
else:
|
||||
assert isinstance(chan, ChannelBackup)
|
||||
label = ''
|
||||
@@ -98,7 +103,7 @@ class ChannelsList(MyTreeView):
|
||||
status = chan.get_state_for_GUI()
|
||||
closed = chan.is_closed()
|
||||
node_alias = self.lnworker.get_node_alias(chan.node_id) or chan.node_id.hex()
|
||||
capacity_str = self.parent.format_amount(chan.get_capacity(), whitespaces=True)
|
||||
capacity_str = self.main_window.format_amount(chan.get_capacity(), whitespaces=True)
|
||||
return {
|
||||
self.Columns.SHORT_CHANID: chan.short_id_for_GUI(),
|
||||
self.Columns.LONG_CHANID: chan.channel_id.hex(),
|
||||
@@ -125,7 +130,7 @@ class ChannelsList(MyTreeView):
|
||||
self.is_force_close = False
|
||||
msg = _('Cooperative close?')
|
||||
msg += '\n' + _(messages.MSG_COOPERATIVE_CLOSE)
|
||||
if not self.parent.question(msg):
|
||||
if not self.main_window.question(msg):
|
||||
return
|
||||
coro = self.lnworker.close_channel(channel_id)
|
||||
on_success = self.on_channel_closed
|
||||
@@ -147,10 +152,10 @@ class ChannelsList(MyTreeView):
|
||||
+ '<u>' + _('Please create a backup of your wallet file!') + '</u> '\
|
||||
+ '<p>' + _('Funds in this channel will not be recoverable from seed until they are swept back into your wallet, and might be lost if you lose your wallet file.') + ' '\
|
||||
+ _('To prevent that, you should save a backup of your wallet on another device.') + '</p>'
|
||||
if not self.parent.question(msg, title=_('Force-close channel'), rich_text=True, checkbox=backup_cb):
|
||||
if not self.main_window.question(msg, title=_('Force-close channel'), rich_text=True, checkbox=backup_cb):
|
||||
return
|
||||
if self.save_backup:
|
||||
if not self.parent.backup_wallet():
|
||||
if not self.main_window.backup_wallet():
|
||||
return
|
||||
def task():
|
||||
coro = self.lnworker.force_close_channel(channel_id)
|
||||
@@ -178,7 +183,7 @@ class ChannelsList(MyTreeView):
|
||||
def request_force_close(self, channel_id):
|
||||
msg = _('Request force-close from remote peer?')
|
||||
msg += '\n' + _(messages.MSG_REQUEST_FORCE_CLOSE)
|
||||
if not self.parent.question(msg):
|
||||
if not self.main_window.question(msg):
|
||||
return
|
||||
def task():
|
||||
coro = self.lnworker.request_force_close(channel_id)
|
||||
@@ -208,9 +213,9 @@ class ChannelsList(MyTreeView):
|
||||
def on_rebalance(self):
|
||||
chan1, chan2 = self.get_rebalance_pair()
|
||||
if chan1 is None:
|
||||
self.parent.show_error("Select two active channels to rebalance.")
|
||||
self.main_window.show_error("Select two active channels to rebalance.")
|
||||
return
|
||||
self.parent.rebalance_dialog(chan1, chan2)
|
||||
self.main_window.rebalance_dialog(chan1, chan2)
|
||||
|
||||
def create_menu(self, position):
|
||||
menu = QMenu()
|
||||
@@ -222,7 +227,7 @@ class ChannelsList(MyTreeView):
|
||||
if len(selected) == 2:
|
||||
chan1, chan2 = self.get_rebalance_pair()
|
||||
if chan1 and chan2:
|
||||
menu.addAction(_("Rebalance channels"), lambda: self.parent.rebalance_dialog(chan1, chan2))
|
||||
menu.addAction(_("Rebalance channels"), lambda: self.main_window.rebalance_dialog(chan1, chan2))
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
return
|
||||
elif len(selected) > 2:
|
||||
@@ -235,7 +240,7 @@ class ChannelsList(MyTreeView):
|
||||
return
|
||||
channel_id = idx.sibling(idx.row(), self.Columns.NODE_ALIAS).data(ROLE_CHANNEL_ID)
|
||||
chan = self.lnworker.get_channel_by_id(channel_id) or self.lnworker.channel_backups[channel_id]
|
||||
menu.addAction(_("Details..."), lambda: self.parent.show_channel_details(chan))
|
||||
menu.addAction(_("Details..."), lambda: self.main_window.show_channel_details(chan))
|
||||
menu.addSeparator()
|
||||
cc = self.add_copy_menu(menu, idx)
|
||||
cc.addAction(_("Node ID"), lambda: self.place_text_on_clipboard(
|
||||
@@ -272,7 +277,7 @@ class ChannelsList(MyTreeView):
|
||||
|
||||
@QtCore.pyqtSlot(Abstract_Wallet, AbstractChannel)
|
||||
def do_update_single_row(self, wallet: Abstract_Wallet, chan: AbstractChannel):
|
||||
if wallet != self.parent.wallet:
|
||||
if wallet != self.wallet:
|
||||
return
|
||||
for row in range(self.model().rowCount()):
|
||||
item = self.model().item(row, self.Columns.NODE_ALIAS)
|
||||
@@ -287,11 +292,11 @@ class ChannelsList(MyTreeView):
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_gossip_db(self):
|
||||
self.do_update_rows(self.parent.wallet)
|
||||
self.do_update_rows(self.wallet)
|
||||
|
||||
@QtCore.pyqtSlot(Abstract_Wallet)
|
||||
def do_update_rows(self, wallet):
|
||||
if wallet != self.parent.wallet:
|
||||
if wallet != self.wallet:
|
||||
return
|
||||
self.model().clear()
|
||||
self.update_headers(self.headers)
|
||||
@@ -337,29 +342,29 @@ class ChannelsList(MyTreeView):
|
||||
item.setToolTip("")
|
||||
|
||||
def update_can_send(self, lnworker: LNWallet):
|
||||
msg = _('Can send') + ' ' + self.parent.format_amount(lnworker.num_sats_can_send())\
|
||||
+ ' ' + self.parent.base_unit() + '; '\
|
||||
+ _('can receive') + ' ' + self.parent.format_amount(lnworker.num_sats_can_receive())\
|
||||
+ ' ' + self.parent.base_unit()
|
||||
msg = _('Can send') + ' ' + self.main_window.format_amount(lnworker.num_sats_can_send())\
|
||||
+ ' ' + self.main_window.base_unit() + '; '\
|
||||
+ _('can receive') + ' ' + self.main_window.format_amount(lnworker.num_sats_can_receive())\
|
||||
+ ' ' + self.main_window.base_unit()
|
||||
self.can_send_label.setText(msg)
|
||||
|
||||
def create_toolbar(self, config):
|
||||
toolbar, menu = self.create_toolbar_with_menu('')
|
||||
self.can_send_label = toolbar.itemAt(0).widget()
|
||||
menu.addAction(_('Rebalance channels'), lambda: self.on_rebalance())
|
||||
menu.addAction(_('Submarine swap'), lambda: self.parent.run_swap_dialog())
|
||||
menu.addAction(_('Submarine swap'), lambda: self.main_window.run_swap_dialog())
|
||||
menu.addSeparator()
|
||||
menu.addAction(_("Import channel backup"), lambda: self.parent.do_process_from_text_channel_backup())
|
||||
menu.addAction(_("Import channel backup"), lambda: self.main_window.do_process_from_text_channel_backup())
|
||||
self.new_channel_button = EnterButton(_('New Channel'), self.new_channel_with_warning)
|
||||
self.new_channel_button.setEnabled(self.parent.wallet.has_lightning())
|
||||
self.new_channel_button.setEnabled(self.wallet.has_lightning())
|
||||
toolbar.insertWidget(2, self.new_channel_button)
|
||||
return toolbar
|
||||
|
||||
def new_channel_with_warning(self):
|
||||
lnworker = self.parent.wallet.lnworker
|
||||
lnworker = self.wallet.lnworker
|
||||
if not lnworker.channels and not lnworker.channel_backups:
|
||||
warning = _(messages.MSG_LIGHTNING_WARNING)
|
||||
answer = self.parent.question(
|
||||
answer = self.main_window.question(
|
||||
_('Do you want to create your first channel?') + '\n\n' + warning)
|
||||
if answer:
|
||||
self.new_channel_dialog()
|
||||
@@ -367,9 +372,9 @@ class ChannelsList(MyTreeView):
|
||||
self.new_channel_dialog()
|
||||
|
||||
def statistics_dialog(self):
|
||||
channel_db = self.parent.network.channel_db
|
||||
capacity = self.parent.format_amount(channel_db.capacity()) + ' '+ self.parent.base_unit()
|
||||
d = WindowModalDialog(self.parent, _('Lightning Network Statistics'))
|
||||
channel_db = self.network.channel_db
|
||||
capacity = self.main_window.format_amount(channel_db.capacity()) + ' '+ self.main_window.base_unit()
|
||||
d = WindowModalDialog(self.main_window, _('Lightning Network Statistics'))
|
||||
d.setMinimumWidth(400)
|
||||
vbox = QVBoxLayout(d)
|
||||
h = QGridLayout()
|
||||
@@ -385,7 +390,7 @@ class ChannelsList(MyTreeView):
|
||||
|
||||
def new_channel_dialog(self, *, amount_sat=None, min_amount_sat=None):
|
||||
from .new_channel_dialog import NewChannelDialog
|
||||
d = NewChannelDialog(self.parent, amount_sat, min_amount_sat)
|
||||
d = NewChannelDialog(self.main_window, amount_sat, min_amount_sat)
|
||||
return d.run()
|
||||
|
||||
def set_visibility_of_columns(self):
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# SOFTWARE.
|
||||
|
||||
import enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||
from PyQt5.QtCore import Qt, QPersistentModelIndex, QModelIndex
|
||||
@@ -36,6 +37,9 @@ from electrum.plugin import run_hook
|
||||
|
||||
from .util import MyTreeView, webopen
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
class ContactList(MyTreeView):
|
||||
|
||||
@@ -52,10 +56,12 @@ class ContactList(MyTreeView):
|
||||
ROLE_CONTACT_KEY = Qt.UserRole + 1000
|
||||
key_role = ROLE_CONTACT_KEY
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent, self.create_menu,
|
||||
stretch_column=self.Columns.NAME,
|
||||
editable_columns=[self.Columns.NAME])
|
||||
def __init__(self, main_window: 'ElectrumWindow'):
|
||||
super().__init__(
|
||||
main_window=main_window,
|
||||
stretch_column=self.Columns.NAME,
|
||||
editable_columns=[self.Columns.NAME],
|
||||
)
|
||||
self.setModel(QStandardItemModel(self))
|
||||
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
self.setSortingEnabled(True)
|
||||
@@ -63,8 +69,8 @@ class ContactList(MyTreeView):
|
||||
self.update()
|
||||
|
||||
def on_edited(self, idx, edit_key, *, text):
|
||||
_type, prior_name = self.parent.contacts.pop(edit_key)
|
||||
self.parent.set_contact(text, edit_key)
|
||||
_type, prior_name = self.main_window.contacts.pop(edit_key)
|
||||
self.main_window.set_contact(text, edit_key)
|
||||
self.update()
|
||||
|
||||
def create_menu(self, position):
|
||||
@@ -86,8 +92,8 @@ class ContactList(MyTreeView):
|
||||
# would not be editable if openalias
|
||||
persistent = QPersistentModelIndex(idx)
|
||||
menu.addAction(_("Edit {}").format(column_title), lambda p=persistent: self.edit(QModelIndex(p)))
|
||||
menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(selected_keys))
|
||||
menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(selected_keys))
|
||||
menu.addAction(_("Pay to"), lambda: self.main_window.payto_contacts(selected_keys))
|
||||
menu.addAction(_("Delete"), lambda: self.main_window.delete_contacts(selected_keys))
|
||||
URLs = [block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, selected_keys)]
|
||||
if URLs:
|
||||
menu.addAction(_("View on block explorer"), lambda: [webopen(u) for u in URLs])
|
||||
@@ -102,8 +108,8 @@ class ContactList(MyTreeView):
|
||||
self.model().clear()
|
||||
self.update_headers(self.__class__.headers)
|
||||
set_current = None
|
||||
for key in sorted(self.parent.contacts.keys()):
|
||||
contact_type, name = self.parent.contacts[key]
|
||||
for key in sorted(self.main_window.contacts.keys()):
|
||||
contact_type, name = self.main_window.contacts[key]
|
||||
items = [QStandardItem(x) for x in (name, key)]
|
||||
items[self.Columns.NAME].setEditable(contact_type != 'openalias')
|
||||
items[self.Columns.ADDRESS].setEditable(False)
|
||||
@@ -130,7 +136,7 @@ class ContactList(MyTreeView):
|
||||
|
||||
def create_toolbar(self, config):
|
||||
toolbar, menu = self.create_toolbar_with_menu('')
|
||||
menu.addAction(_("&New contact"), self.parent.new_contact_dialog)
|
||||
menu.addAction(_("Import"), lambda: self.parent.import_contacts())
|
||||
menu.addAction(_("Export"), lambda: self.parent.export_contacts())
|
||||
menu.addAction(_("&New contact"), self.main_window.new_contact_dialog)
|
||||
menu.addAction(_("Import"), lambda: self.main_window.import_contacts())
|
||||
menu.addAction(_("Export"), lambda: self.main_window.export_contacts())
|
||||
return toolbar
|
||||
|
||||
@@ -486,12 +486,12 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
return True
|
||||
return False
|
||||
|
||||
def __init__(self, parent, model: HistoryModel):
|
||||
super().__init__(parent, self.create_menu,
|
||||
stretch_column=HistoryColumns.DESCRIPTION,
|
||||
editable_columns=[HistoryColumns.DESCRIPTION, HistoryColumns.FIAT_VALUE])
|
||||
self.main_window = parent
|
||||
self.config = parent.config
|
||||
def __init__(self, main_window: 'ElectrumWindow', model: HistoryModel):
|
||||
super().__init__(
|
||||
main_window=main_window,
|
||||
stretch_column=HistoryColumns.DESCRIPTION,
|
||||
editable_columns=[HistoryColumns.DESCRIPTION, HistoryColumns.FIAT_VALUE],
|
||||
)
|
||||
self.hm = model
|
||||
self.proxy = HistorySortModel(self)
|
||||
self.proxy.setSourceModel(model)
|
||||
@@ -510,7 +510,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
self.end_button.setEnabled(False)
|
||||
self.period_combo.addItems([_('All'), _('Custom')])
|
||||
self.period_combo.activated.connect(self.on_combo)
|
||||
self.wallet = self.parent.wallet # type: Abstract_Wallet
|
||||
self.wallet = self.main_window.wallet # type: Abstract_Wallet
|
||||
self.sortByColumn(HistoryColumns.STATUS, Qt.AscendingOrder)
|
||||
self.setRootIsDecorated(True)
|
||||
self.header().setStretchLastSection(False)
|
||||
@@ -603,24 +603,24 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
|
||||
def show_summary(self):
|
||||
if not self.hm.should_show_fiat():
|
||||
self.parent.show_message(_("Enable fiat exchange rate with history."))
|
||||
self.main_window.show_message(_("Enable fiat exchange rate with history."))
|
||||
return
|
||||
fx = self.parent.fx
|
||||
fx = self.main_window.fx
|
||||
h = self.wallet.get_detailed_history(
|
||||
from_timestamp = time.mktime(self.start_date.timetuple()) if self.start_date else None,
|
||||
to_timestamp = time.mktime(self.end_date.timetuple()) if self.end_date else None,
|
||||
fx=fx)
|
||||
summary = h['summary']
|
||||
if not summary:
|
||||
self.parent.show_message(_("Nothing to summarize."))
|
||||
self.main_window.show_message(_("Nothing to summarize."))
|
||||
return
|
||||
start = summary['begin']
|
||||
end = summary['end']
|
||||
flow = summary['flow']
|
||||
start_date = start.get('date')
|
||||
end_date = end.get('date')
|
||||
format_amount = lambda x: self.parent.format_amount(x.value) + ' ' + self.parent.base_unit()
|
||||
format_fiat = lambda x: str(x) + ' ' + self.parent.fx.ccy
|
||||
format_amount = lambda x: self.main_window.format_amount(x.value) + ' ' + self.main_window.base_unit()
|
||||
format_fiat = lambda x: str(x) + ' ' + self.main_window.fx.ccy
|
||||
|
||||
d = WindowModalDialog(self, _("Summary"))
|
||||
d.setMinimumSize(600, 150)
|
||||
@@ -679,7 +679,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
from electrum.plot import plot_history, NothingToPlotException
|
||||
except Exception as e:
|
||||
_logger.error(f"could not import electrum.plot. This feature needs matplotlib to be installed. exc={e!r}")
|
||||
self.parent.show_message(
|
||||
self.main_window.show_message(
|
||||
_("Can't plot history.") + '\n' +
|
||||
_("Perhaps some dependencies are missing...") + " (matplotlib?)" + '\n' +
|
||||
f"Error: {e!r}"
|
||||
@@ -689,7 +689,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
plt = plot_history(list(self.hm.transactions.values()))
|
||||
plt.show()
|
||||
except NothingToPlotException as e:
|
||||
self.parent.show_message(str(e))
|
||||
self.main_window.show_message(str(e))
|
||||
|
||||
def on_edited(self, idx, edit_key, *, text):
|
||||
index = self.model().mapToSource(idx)
|
||||
@@ -699,9 +699,9 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
if column == HistoryColumns.DESCRIPTION:
|
||||
if self.wallet.set_label(key, text): #changed
|
||||
self.hm.update_label(index)
|
||||
self.parent.update_completions()
|
||||
self.main_window.update_completions()
|
||||
elif column == HistoryColumns.FIAT_VALUE:
|
||||
self.wallet.set_fiat_value(key, self.parent.fx.ccy, text, self.parent.fx, tx_item['value'].value)
|
||||
self.wallet.set_fiat_value(key, self.main_window.fx.ccy, text, self.main_window.fx, tx_item['value'].value)
|
||||
value = tx_item['value'].value
|
||||
if value is not None:
|
||||
self.hm.update_fiat(index)
|
||||
@@ -720,13 +720,13 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
else:
|
||||
if tx_item.get('lightning'):
|
||||
if tx_item['type'] == 'payment':
|
||||
self.parent.show_lightning_transaction(tx_item)
|
||||
self.main_window.show_lightning_transaction(tx_item)
|
||||
return
|
||||
tx_hash = tx_item['txid']
|
||||
tx = self.wallet.adb.get_transaction(tx_hash)
|
||||
if not tx:
|
||||
return
|
||||
self.parent.show_transaction(tx)
|
||||
self.main_window.show_transaction(tx)
|
||||
|
||||
def add_copy_menu(self, menu, idx):
|
||||
cc = menu.addMenu(_("Copy"))
|
||||
@@ -751,14 +751,14 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
tx_item = idx.internalPointer().get_data()
|
||||
if tx_item.get('lightning') and tx_item['type'] == 'payment':
|
||||
menu = QMenu()
|
||||
menu.addAction(_("View Payment"), lambda: self.parent.show_lightning_transaction(tx_item))
|
||||
menu.addAction(_("View Payment"), lambda: self.main_window.show_lightning_transaction(tx_item))
|
||||
cc = self.add_copy_menu(menu, idx)
|
||||
cc.addAction(_("Payment Hash"), lambda: self.place_text_on_clipboard(tx_item['payment_hash'], title="Payment Hash"))
|
||||
cc.addAction(_("Preimage"), lambda: self.place_text_on_clipboard(tx_item['preimage'], title="Preimage"))
|
||||
key = tx_item['payment_hash']
|
||||
log = self.wallet.lnworker.logs.get(key)
|
||||
if log:
|
||||
menu.addAction(_("View log"), lambda: self.parent.send_tab.invoice_list.show_log(key, log))
|
||||
menu.addAction(_("View log"), lambda: self.main_window.send_tab.invoice_list.show_log(key, log))
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
return
|
||||
tx_hash = tx_item['txid']
|
||||
@@ -780,25 +780,25 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
# TODO use siblingAtColumn when min Qt version is >=5.11
|
||||
persistent = QPersistentModelIndex(org_idx.sibling(org_idx.row(), c))
|
||||
menu_edit.addAction(_("{}").format(label), lambda p=persistent: self.edit(QModelIndex(p)))
|
||||
menu.addAction(_("View Transaction"), lambda: self.parent.show_transaction(tx))
|
||||
menu.addAction(_("View Transaction"), lambda: self.main_window.show_transaction(tx))
|
||||
channel_id = tx_item.get('channel_id')
|
||||
if channel_id and self.wallet.lnworker and (chan := self.wallet.lnworker.get_channel_by_id(bytes.fromhex(channel_id))):
|
||||
menu.addAction(_("View Channel"), lambda: self.parent.show_channel_details(chan))
|
||||
menu.addAction(_("View Channel"), lambda: self.main_window.show_channel_details(chan))
|
||||
if is_unconfirmed and tx:
|
||||
if tx_details.can_bump:
|
||||
menu.addAction(_("Increase fee"), lambda: self.parent.bump_fee_dialog(tx))
|
||||
menu.addAction(_("Increase fee"), lambda: self.main_window.bump_fee_dialog(tx))
|
||||
else:
|
||||
if tx_details.can_cpfp:
|
||||
menu.addAction(_("Child pays for parent"), lambda: self.parent.cpfp_dialog(tx))
|
||||
menu.addAction(_("Child pays for parent"), lambda: self.main_window.cpfp_dialog(tx))
|
||||
if tx_details.can_dscancel:
|
||||
menu.addAction(_("Cancel (double-spend)"), lambda: self.parent.dscancel_dialog(tx))
|
||||
menu.addAction(_("Cancel (double-spend)"), lambda: self.main_window.dscancel_dialog(tx))
|
||||
invoices = self.wallet.get_relevant_invoices_for_tx(tx_hash)
|
||||
if len(invoices) == 1:
|
||||
menu.addAction(_("View invoice"), lambda inv=invoices[0]: self.parent.show_onchain_invoice(inv))
|
||||
menu.addAction(_("View invoice"), lambda inv=invoices[0]: self.main_window.show_onchain_invoice(inv))
|
||||
elif len(invoices) > 1:
|
||||
menu_invs = menu.addMenu(_("Related invoices"))
|
||||
for inv in invoices:
|
||||
menu_invs.addAction(_("View invoice"), lambda inv=inv: self.parent.show_onchain_invoice(inv))
|
||||
menu_invs.addAction(_("View invoice"), lambda inv=inv: self.main_window.show_onchain_invoice(inv))
|
||||
if tx_URL:
|
||||
menu.addAction(_("View on block explorer"), lambda: webopen(tx_URL))
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
@@ -809,24 +809,24 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
if num_child_txs > 0:
|
||||
question = (_("Are you sure you want to remove this transaction and {} child transactions?")
|
||||
.format(num_child_txs))
|
||||
if not self.parent.question(msg=question,
|
||||
if not self.main_window.question(msg=question,
|
||||
title=_("Please confirm")):
|
||||
return
|
||||
self.wallet.adb.remove_transaction(tx_hash)
|
||||
self.wallet.save_db()
|
||||
# need to update at least: history_list, utxo_list, address_list
|
||||
self.parent.need_update.set()
|
||||
self.main_window.need_update.set()
|
||||
|
||||
def onFileAdded(self, fn):
|
||||
try:
|
||||
with open(fn) as f:
|
||||
tx = self.parent.tx_from_text(f.read())
|
||||
tx = self.main_window.tx_from_text(f.read())
|
||||
except IOError as e:
|
||||
self.parent.show_error(e)
|
||||
self.main_window.show_error(e)
|
||||
return
|
||||
if not tx:
|
||||
return
|
||||
self.parent.save_transaction_into_wallet(tx)
|
||||
self.main_window.save_transaction_into_wallet(tx)
|
||||
|
||||
def export_history_dialog(self):
|
||||
d = WindowModalDialog(self, _('Export History'))
|
||||
@@ -850,12 +850,12 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
|
||||
self.do_export_history(filename, csv_button.isChecked())
|
||||
except (IOError, os.error) as reason:
|
||||
export_error_label = _("Electrum was unable to produce a transaction export.")
|
||||
self.parent.show_critical(export_error_label + "\n" + str(reason), title=_("Unable to export history"))
|
||||
self.main_window.show_critical(export_error_label + "\n" + str(reason), title=_("Unable to export history"))
|
||||
return
|
||||
self.parent.show_message(_("Your wallet history has been successfully exported."))
|
||||
self.main_window.show_message(_("Your wallet history has been successfully exported."))
|
||||
|
||||
def do_export_history(self, file_name, is_csv):
|
||||
hist = self.wallet.get_detailed_history(fx=self.parent.fx)
|
||||
hist = self.wallet.get_detailed_history(fx=self.main_window.fx)
|
||||
txns = hist['transactions']
|
||||
lines = []
|
||||
if is_csv:
|
||||
|
||||
@@ -69,8 +69,10 @@ class InvoiceList(MyTreeView):
|
||||
|
||||
def __init__(self, send_tab: 'SendTab'):
|
||||
window = send_tab.window
|
||||
super().__init__(window, self.create_menu,
|
||||
stretch_column=self.Columns.DESCRIPTION)
|
||||
super().__init__(
|
||||
main_window=window,
|
||||
stretch_column=self.Columns.DESCRIPTION,
|
||||
)
|
||||
self.wallet = window.wallet
|
||||
self.send_tab = send_tab
|
||||
self.std_model = QStandardItemModel(self)
|
||||
@@ -115,7 +117,7 @@ class InvoiceList(MyTreeView):
|
||||
labels = [""] * len(self.Columns)
|
||||
labels[self.Columns.DATE] = format_time(timestamp) if timestamp else _('Unknown')
|
||||
labels[self.Columns.DESCRIPTION] = item.message
|
||||
labels[self.Columns.AMOUNT] = self.parent.format_amount(amount, whitespaces=True)
|
||||
labels[self.Columns.AMOUNT] = self.main_window.format_amount(amount, whitespaces=True)
|
||||
labels[self.Columns.STATUS] = item.get_status_str(status)
|
||||
items = [QStandardItem(e) for e in labels]
|
||||
self.set_editability(items)
|
||||
@@ -160,11 +162,11 @@ class InvoiceList(MyTreeView):
|
||||
copy_menu = self.add_copy_menu(menu, idx)
|
||||
address = invoice.get_address()
|
||||
if address:
|
||||
copy_menu.addAction(_("Address"), lambda: self.parent.do_copy(invoice.get_address(), title='Bitcoin Address'))
|
||||
copy_menu.addAction(_("Address"), lambda: self.main_window.do_copy(invoice.get_address(), title='Bitcoin Address'))
|
||||
if invoice.is_lightning():
|
||||
menu.addAction(_("Details"), lambda: self.parent.show_lightning_invoice(invoice))
|
||||
menu.addAction(_("Details"), lambda: self.main_window.show_lightning_invoice(invoice))
|
||||
else:
|
||||
menu.addAction(_("Details"), lambda: self.parent.show_onchain_invoice(invoice))
|
||||
menu.addAction(_("Details"), lambda: self.main_window.show_onchain_invoice(invoice))
|
||||
status = wallet.get_invoice_status(invoice)
|
||||
if status == PR_UNPAID:
|
||||
menu.addAction(_("Pay") + "...", lambda: self.send_tab.do_pay_invoice(invoice))
|
||||
|
||||
@@ -73,8 +73,10 @@ class RequestList(MyTreeView):
|
||||
|
||||
def __init__(self, receive_tab: 'ReceiveTab'):
|
||||
window = receive_tab.window
|
||||
super().__init__(window, self.create_menu,
|
||||
stretch_column=self.Columns.DESCRIPTION)
|
||||
super().__init__(
|
||||
main_window=window,
|
||||
stretch_column=self.Columns.DESCRIPTION,
|
||||
)
|
||||
self.wallet = window.wallet
|
||||
self.receive_tab = receive_tab
|
||||
self.std_model = QStandardItemModel(self)
|
||||
@@ -141,7 +143,7 @@ class RequestList(MyTreeView):
|
||||
amount = req.get_amount_sat()
|
||||
message = req.get_message()
|
||||
date = format_time(timestamp)
|
||||
amount_str = self.parent.format_amount(amount) if amount else ""
|
||||
amount_str = self.main_window.format_amount(amount) if amount else ""
|
||||
labels = [""] * len(self.Columns)
|
||||
labels[self.Columns.DATE] = date
|
||||
labels[self.Columns.DESCRIPTION] = message
|
||||
@@ -193,15 +195,15 @@ class RequestList(MyTreeView):
|
||||
menu = QMenu(self)
|
||||
copy_menu = self.add_copy_menu(menu, idx)
|
||||
if req.get_address():
|
||||
copy_menu.addAction(_("Address"), lambda: self.parent.do_copy(req.get_address(), title='Bitcoin Address'))
|
||||
copy_menu.addAction(_("Address"), lambda: self.main_window.do_copy(req.get_address(), title='Bitcoin Address'))
|
||||
if URI := self.wallet.get_request_URI(req):
|
||||
copy_menu.addAction(_("Bitcoin URI"), lambda: self.parent.do_copy(URI, title='Bitcoin URI'))
|
||||
copy_menu.addAction(_("Bitcoin URI"), lambda: self.main_window.do_copy(URI, title='Bitcoin URI'))
|
||||
if req.is_lightning():
|
||||
copy_menu.addAction(_("Lightning Request"), lambda: self.parent.do_copy(self.wallet.get_bolt11_invoice(req), title='Lightning Request'))
|
||||
copy_menu.addAction(_("Lightning Request"), lambda: self.main_window.do_copy(self.wallet.get_bolt11_invoice(req), title='Lightning Request'))
|
||||
#if 'view_url' in req:
|
||||
# menu.addAction(_("View in web browser"), lambda: webopen(req['view_url']))
|
||||
menu.addAction(_("Delete"), lambda: self.delete_requests([key]))
|
||||
run_hook('receive_list_menu', self.parent, menu, key)
|
||||
run_hook('receive_list_menu', self.main_window, menu, key)
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
|
||||
def delete_requests(self, keys):
|
||||
|
||||
@@ -626,14 +626,21 @@ class MyTreeView(QTreeView):
|
||||
|
||||
Columns: Type[BaseColumnsEnum]
|
||||
|
||||
def __init__(self, parent: 'ElectrumWindow', create_menu, *,
|
||||
stretch_column=None, editable_columns=None):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
parent: Optional[QWidget] = None,
|
||||
main_window: Optional['ElectrumWindow'] = None,
|
||||
stretch_column: Optional[int] = None,
|
||||
editable_columns: Optional[Sequence[int]] = None,
|
||||
):
|
||||
parent = parent or main_window
|
||||
super().__init__(parent)
|
||||
self.parent = parent
|
||||
self.config = self.parent.config
|
||||
self.main_window = main_window
|
||||
self.config = self.main_window.config if self.main_window else None
|
||||
self.stretch_column = stretch_column
|
||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.customContextMenuRequested.connect(create_menu)
|
||||
self.customContextMenuRequested.connect(self.create_menu)
|
||||
self.setUniformRowHeights(True)
|
||||
|
||||
# Control which columns are editable
|
||||
@@ -659,6 +666,9 @@ class MyTreeView(QTreeView):
|
||||
|
||||
self._default_bg_brush = QStandardItem().background()
|
||||
|
||||
def create_menu(self, position: QPoint) -> None:
|
||||
pass
|
||||
|
||||
def set_editability(self, items):
|
||||
for idx, i in enumerate(items):
|
||||
i.setEditable(idx in self.editable_columns)
|
||||
@@ -836,7 +846,7 @@ class MyTreeView(QTreeView):
|
||||
return cc
|
||||
|
||||
def place_text_on_clipboard(self, text: str, *, title: str = None) -> None:
|
||||
self.parent.do_copy(text, title=title)
|
||||
self.main_window.do_copy(text, title=title)
|
||||
|
||||
def showEvent(self, e: 'QShowEvent'):
|
||||
super().showEvent(e)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
from typing import Optional, List, Dict, Sequence, Set
|
||||
from typing import Optional, List, Dict, Sequence, Set, TYPE_CHECKING
|
||||
import enum
|
||||
import copy
|
||||
|
||||
@@ -39,6 +39,9 @@ from electrum.lnutil import LN_MAX_FUNDING_SAT, MIN_FUNDING_SAT
|
||||
from .util import MyTreeView, ColorScheme, MONOSPACE_FONT, EnterButton
|
||||
from .new_channel_dialog import NewChannelDialog
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
class UTXOList(MyTreeView):
|
||||
_spend_set: Set[str] # coins selected by the user to spend from
|
||||
@@ -64,12 +67,14 @@ class UTXOList(MyTreeView):
|
||||
ROLE_PREVOUT_STR = Qt.UserRole + 1000
|
||||
key_role = ROLE_PREVOUT_STR
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent, self.create_menu,
|
||||
stretch_column=self.stretch_column)
|
||||
def __init__(self, main_window: 'ElectrumWindow'):
|
||||
super().__init__(
|
||||
main_window=main_window,
|
||||
stretch_column=self.stretch_column,
|
||||
)
|
||||
self._spend_set = set()
|
||||
self._utxo_dict = {}
|
||||
self.wallet = self.parent.wallet
|
||||
self.wallet = self.main_window.wallet
|
||||
self.std_model = QStandardItemModel(self)
|
||||
self.setModel(self.std_model)
|
||||
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
@@ -95,7 +100,7 @@ class UTXOList(MyTreeView):
|
||||
labels = [""] * len(self.Columns)
|
||||
labels[self.Columns.OUTPOINT] = str(utxo.short_id)
|
||||
labels[self.Columns.ADDRESS] = utxo.address
|
||||
labels[self.Columns.AMOUNT] = self.parent.format_amount(utxo.value_sats(), whitespaces=True)
|
||||
labels[self.Columns.AMOUNT] = self.main_window.format_amount(utxo.value_sats(), whitespaces=True)
|
||||
utxo_item = [QStandardItem(x) for x in labels]
|
||||
self.set_editability(utxo_item)
|
||||
utxo_item[self.Columns.OUTPOINT].setData(name, self.ROLE_PREVOUT_STR)
|
||||
@@ -115,11 +120,11 @@ class UTXOList(MyTreeView):
|
||||
coins = [self._utxo_dict[x] for x in self._spend_set]
|
||||
coins = self._filter_frozen_coins(coins)
|
||||
amount = sum(x.value_sats() for x in coins)
|
||||
amount_str = self.parent.format_amount_and_units(amount)
|
||||
amount_str = self.main_window.format_amount_and_units(amount)
|
||||
num_outputs_str = _("{} outputs available ({} total)").format(len(coins), len(self._utxo_dict))
|
||||
self.parent.set_coincontrol_msg(_("Coin control active") + f': {num_outputs_str}, {amount_str}')
|
||||
self.main_window.set_coincontrol_msg(_("Coin control active") + f': {num_outputs_str}, {amount_str}')
|
||||
else:
|
||||
self.parent.set_coincontrol_msg(None)
|
||||
self.main_window.set_coincontrol_msg(None)
|
||||
|
||||
def refresh_row(self, key, row):
|
||||
assert row is not None
|
||||
@@ -184,7 +189,7 @@ class UTXOList(MyTreeView):
|
||||
selected = self.get_selected_outpoints()
|
||||
coins = [self._utxo_dict[name] for name in selected]
|
||||
if not coins:
|
||||
self.parent.show_error(_('You need to select coins from the list first.\nUse ctrl+left mouse button to select multiple items'))
|
||||
self.main_window.show_error(_('You need to select coins from the list first.\nUse ctrl+left mouse button to select multiple items'))
|
||||
return
|
||||
self.add_to_coincontrol(coins)
|
||||
|
||||
@@ -223,7 +228,7 @@ class UTXOList(MyTreeView):
|
||||
def swap_coins(self, coins):
|
||||
#self.clear_coincontrol()
|
||||
self.add_to_coincontrol(coins)
|
||||
self.parent.run_swap_dialog(is_reverse=False, recv_amount_sat='!')
|
||||
self.main_window.run_swap_dialog(is_reverse=False, recv_amount_sat='!')
|
||||
self.clear_coincontrol()
|
||||
|
||||
def can_open_channel(self, coins):
|
||||
@@ -236,7 +241,7 @@ class UTXOList(MyTreeView):
|
||||
# todo : use a single dialog in new flow
|
||||
#self.clear_coincontrol()
|
||||
self.add_to_coincontrol(coins)
|
||||
d = NewChannelDialog(self.parent)
|
||||
d = NewChannelDialog(self.main_window)
|
||||
d.max_button.setChecked(True)
|
||||
d.max_button.setEnabled(False)
|
||||
d.min_button.setEnabled(False)
|
||||
@@ -247,15 +252,15 @@ class UTXOList(MyTreeView):
|
||||
self.clear_coincontrol()
|
||||
|
||||
def clipboard_contains_address(self):
|
||||
text = self.parent.app.clipboard().text()
|
||||
text = self.main_window.app.clipboard().text()
|
||||
return is_address(text)
|
||||
|
||||
def pay_to_clipboard_address(self, coins):
|
||||
addr = self.parent.app.clipboard().text()
|
||||
addr = self.main_window.app.clipboard().text()
|
||||
outputs = [PartialTxOutput.from_address_and_value(addr, '!')]
|
||||
#self.clear_coincontrol()
|
||||
self.add_to_coincontrol(coins)
|
||||
self.parent.send_tab.pay_onchain_dialog(outputs)
|
||||
self.main_window.send_tab.pay_onchain_dialog(outputs)
|
||||
self.clear_coincontrol()
|
||||
|
||||
def create_menu(self, position):
|
||||
@@ -277,7 +282,7 @@ class UTXOList(MyTreeView):
|
||||
tx = self.wallet.adb.get_transaction(txid)
|
||||
if tx:
|
||||
label = self.wallet.get_label_for_txid(txid)
|
||||
menu.addAction(_("Privacy analysis"), lambda: self.parent.show_utxo(utxo))
|
||||
menu.addAction(_("Privacy analysis"), lambda: self.main_window.show_utxo(utxo))
|
||||
# fully spend
|
||||
menu_spend = menu.addMenu(_("Fully spend") + '…')
|
||||
m = menu_spend.addAction(_("send to address in clipboard"), lambda: self.pay_to_clipboard_address(coins))
|
||||
@@ -297,13 +302,13 @@ class UTXOList(MyTreeView):
|
||||
addr = utxo.address
|
||||
menu_freeze = menu.addMenu(_("Freeze"))
|
||||
if not self.wallet.is_frozen_coin(utxo):
|
||||
menu_freeze.addAction(_("Freeze Coin"), lambda: self.parent.set_frozen_state_of_coins([utxo], True))
|
||||
menu_freeze.addAction(_("Freeze Coin"), lambda: self.main_window.set_frozen_state_of_coins([utxo], True))
|
||||
else:
|
||||
menu_freeze.addAction(_("Unfreeze Coin"), lambda: self.parent.set_frozen_state_of_coins([utxo], False))
|
||||
menu_freeze.addAction(_("Unfreeze Coin"), lambda: self.main_window.set_frozen_state_of_coins([utxo], False))
|
||||
if not self.wallet.is_frozen_address(addr):
|
||||
menu_freeze.addAction(_("Freeze Address"), lambda: self.parent.set_frozen_state_of_addresses([addr], True))
|
||||
menu_freeze.addAction(_("Freeze Address"), lambda: self.main_window.set_frozen_state_of_addresses([addr], True))
|
||||
else:
|
||||
menu_freeze.addAction(_("Unfreeze Address"), lambda: self.parent.set_frozen_state_of_addresses([addr], False))
|
||||
menu_freeze.addAction(_("Unfreeze Address"), lambda: self.main_window.set_frozen_state_of_addresses([addr], False))
|
||||
elif len(coins) > 1: # multiple items selected
|
||||
menu.addSeparator()
|
||||
addrs = [utxo.address for utxo in coins]
|
||||
@@ -311,13 +316,13 @@ class UTXOList(MyTreeView):
|
||||
is_addr_frozen = [self.wallet.is_frozen_address(utxo.address) for utxo in coins]
|
||||
menu_freeze = menu.addMenu(_("Freeze"))
|
||||
if not all(is_coin_frozen):
|
||||
menu_freeze.addAction(_("Freeze Coins"), lambda: self.parent.set_frozen_state_of_coins(coins, True))
|
||||
menu_freeze.addAction(_("Freeze Coins"), lambda: self.main_window.set_frozen_state_of_coins(coins, True))
|
||||
if any(is_coin_frozen):
|
||||
menu_freeze.addAction(_("Unfreeze Coins"), lambda: self.parent.set_frozen_state_of_coins(coins, False))
|
||||
menu_freeze.addAction(_("Unfreeze Coins"), lambda: self.main_window.set_frozen_state_of_coins(coins, False))
|
||||
if not all(is_addr_frozen):
|
||||
menu_freeze.addAction(_("Freeze Addresses"), lambda: self.parent.set_frozen_state_of_addresses(addrs, True))
|
||||
menu_freeze.addAction(_("Freeze Addresses"), lambda: self.main_window.set_frozen_state_of_addresses(addrs, True))
|
||||
if any(is_addr_frozen):
|
||||
menu_freeze.addAction(_("Unfreeze Addresses"), lambda: self.parent.set_frozen_state_of_addresses(addrs, False))
|
||||
menu_freeze.addAction(_("Unfreeze Addresses"), lambda: self.main_window.set_frozen_state_of_addresses(addrs, False))
|
||||
|
||||
menu.exec_(self.viewport().mapToGlobal(position))
|
||||
|
||||
|
||||
@@ -32,15 +32,16 @@ from .util import MyTreeView, Buttons
|
||||
|
||||
|
||||
class WatcherList(MyTreeView):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent, self.create_menu, stretch_column=0)
|
||||
def __init__(self, parent: 'WatchtowerDialog'):
|
||||
super().__init__(
|
||||
parent=parent,
|
||||
stretch_column=0,
|
||||
)
|
||||
self.parent = parent
|
||||
self.setModel(QStandardItemModel(self))
|
||||
self.setSortingEnabled(True)
|
||||
self.update()
|
||||
|
||||
def create_menu(self, x):
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
if self.parent.lnwatcher is None:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user