diff --git a/electrum/gui/qml/qetxfinalizer.py b/electrum/gui/qml/qetxfinalizer.py index 1e72841e8..2223dea80 100644 --- a/electrum/gui/qml/qetxfinalizer.py +++ b/electrum/gui/qml/qetxfinalizer.py @@ -402,9 +402,10 @@ class QETxFinalizer(TxFeeSlider): try: # make unsigned transaction - tx = self.make_tx(amount='!' if self._amount.isMax else self._amount.satsInt) + amount = '!' if self._amount.isMax else self._amount.satsInt + tx = self.make_tx(amount=amount) except NotEnoughFunds: - self.warning = _("Not enough funds") + self.warning = self._wallet.wallet.get_text_not_enough_funds_mentioning_frozen(for_amount=amount) self._valid = False self.validChanged.emit() return diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index d0bb87ec5..e35d16b6d 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -851,6 +851,6 @@ class QEWallet(AuthMixin, QObject, QtEventListener): amount = tx.output_value() except NotEnoughFunds as e: self._logger.debug(str(e)) - message = self.wallet.get_text_not_enough_funds_mentioning_frozen() + message = self.wallet.get_text_not_enough_funds_mentioning_frozen(for_amount='!') return amount, message diff --git a/electrum/gui/qt/confirm_tx_dialog.py b/electrum/gui/qt/confirm_tx_dialog.py index a9338a7a0..798be1b56 100644 --- a/electrum/gui/qt/confirm_tx_dialog.py +++ b/electrum/gui/qt/confirm_tx_dialog.py @@ -490,8 +490,10 @@ class TxEditor(WindowModalDialog): elif self.can_pay_assuming_zero_fees(confirmed_only=confirmed_only): self.error += ' ' + _('You need to set a lower fee.') elif frozen_bal := self.wallet.get_frozen_balance_str(): - # FIXME only show if unfreezing would fix "not enough funds" - self.error += ' ' + _("Some coins are frozen: {} (can be unfrozen in the Addresses or in the Coins tab)").format(frozen_bal) + self.error = self.wallet.get_text_not_enough_funds_mentioning_frozen( + for_amount=self.output_value, + hint=_('Can be unfrozen in the Addresses or in the Coins tab') + ) if not self.tx: if self.not_enough_funds: self.io_widget.update(None) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index a73f4b4cc..98cc57dd5 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -1437,7 +1437,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener): # note: use confirmed_only=False here, regardless of config setting, # as the user needs to get to ConfirmTxDialog to change the config setting if not d.can_pay_assuming_zero_fees(confirmed_only=False): - text = self.wallet.get_text_not_enough_funds_mentioning_frozen() + text = self.wallet.get_text_not_enough_funds_mentioning_frozen(for_amount=output_value) self.show_message(text) return return d.run(), d.is_preview diff --git a/electrum/gui/qt/send_tab.py b/electrum/gui/qt/send_tab.py index 93620b0d5..dd73c3eb5 100644 --- a/electrum/gui/qt/send_tab.py +++ b/electrum/gui/qt/send_tab.py @@ -267,7 +267,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger): tx = make_tx(FixedFeePolicy(0)) except NotEnoughFunds as e: self.max_button.setChecked(False) - text = self.wallet.get_text_not_enough_funds_mentioning_frozen() + text = self.wallet.get_text_not_enough_funds_mentioning_frozen(for_amount='!') self.show_error(text) return diff --git a/electrum/wallet.py b/electrum/wallet.py index be9049560..c4216fdad 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -3417,11 +3417,28 @@ class Abstract_Wallet(ABC, Logger, EventListener): def get_unlocked_password(self): return self._password_in_memory - def get_text_not_enough_funds_mentioning_frozen(self) -> str: + def get_text_not_enough_funds_mentioning_frozen( + self, + *, + for_amount: Optional[Union[int, str]] = None, + hint: Optional[str] = None + ) -> str: + """Generate 'Not enough funds' text. + Include mention of frozen coins (and append optional hint), iff unfreezing would satisfy for_amount + """ text = _('Not enough funds') - frozen_str = self.get_frozen_balance_str() - if frozen_str: - text += ' ' + _('({} are frozen)').format(frozen_str) + if for_amount is not None: + if frozen_bal := sum(self.get_frozen_balance()): + frozen_str = None + if isinstance(for_amount, int): + if frozen_bal + self.get_spendable_balance_sat() > for_amount: + frozen_str = self.config.format_amount_and_units(frozen_bal) + elif for_amount == '!': + frozen_str = self.config.format_amount_and_units(frozen_bal) + if frozen_str: + text = _('Not enough funds') + " " + _('({} are frozen)').format(frozen_str) + if hint: + text += '. ' + hint return text def get_frozen_balance_str(self) -> Optional[str]: