diff --git a/electrum/exchange_rate.py b/electrum/exchange_rate.py index ea0a79ca7..f3c67712d 100644 --- a/electrum/exchange_rate.py +++ b/electrum/exchange_rate.py @@ -567,6 +567,9 @@ class FxThread(ThreadJob, EventListener): return text return text[:dp_loc] + util.DECIMAL_POINT + text[dp_loc+1:] + def ccy_precision(self, ccy=None) -> int: + return CCY_PRECISIONS.get(self.ccy if ccy is None else ccy, 2) + async def run(self): while True: # every few minutes, refresh spot price diff --git a/electrum/gui/qml/components/controls/BtcField.qml b/electrum/gui/qml/components/controls/BtcField.qml index 3afeaa029..4414dd709 100644 --- a/electrum/gui/qml/components/controls/BtcField.qml +++ b/electrum/gui/qml/components/controls/BtcField.qml @@ -1,4 +1,4 @@ -import QtQuick 2.6 +import QtQuick 2.15 import QtQuick.Controls 2.0 import org.electrum 1.0 @@ -11,6 +11,10 @@ TextField { font.family: FixedFont placeholderText: qsTr('Amount') inputMethodHints: Qt.ImhDigitsOnly + validator: RegularExpressionValidator { + regularExpression: Config.btcAmountRegex + } + property Amount textAsSats onTextChanged: { textAsSats = Config.unitsToSats(amount.text) diff --git a/electrum/gui/qml/components/controls/FiatField.qml b/electrum/gui/qml/components/controls/FiatField.qml index fff8150e0..47cb53694 100644 --- a/electrum/gui/qml/components/controls/FiatField.qml +++ b/electrum/gui/qml/components/controls/FiatField.qml @@ -1,4 +1,4 @@ -import QtQuick 2.6 +import QtQuick 2.15 import QtQuick.Controls 2.0 import org.electrum 1.0 @@ -11,6 +11,10 @@ TextField { font.family: FixedFont placeholderText: qsTr('Amount') inputMethodHints: Qt.ImhDigitsOnly + validator: RegularExpressionValidator { + regularExpression: Daemon.fx.fiatAmountRegex + } + onTextChanged: { if (amountFiat.activeFocus) btcfield.text = text == '' diff --git a/electrum/gui/qml/qeconfig.py b/electrum/gui/qml/qeconfig.py index b71811c94..5f1735fa8 100644 --- a/electrum/gui/qml/qeconfig.py +++ b/electrum/gui/qml/qeconfig.py @@ -2,11 +2,11 @@ import copy from decimal import Decimal from typing import TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.i18n import set_language, languages from electrum.logging import get_logger -from electrum.util import DECIMAL_POINT_DEFAULT, format_satoshis +from electrum.util import DECIMAL_POINT_DEFAULT, base_unit_name_to_decimal_point from electrum.invoices import PR_DEFAULT_EXPIRATION_WHEN_CREATING from .qetypes import QEAmount @@ -82,6 +82,15 @@ class QEConfig(AuthMixin, QObject): self.config.set_base_unit(unit) self.baseUnitChanged.emit() + @pyqtProperty('QRegularExpression', notify=baseUnitChanged) + def btcAmountRegex(self): + decimal_point = base_unit_name_to_decimal_point(self.config.get_base_unit()) + exp = '[0-9]{0,8}' + if decimal_point: + exp += '\\.' + exp += '[0-9]{0,%d}' % decimal_point + return QRegularExpression(exp) + thousandsSeparatorChanged = pyqtSignal() @pyqtProperty(bool, notify=thousandsSeparatorChanged) def thousandsSeparator(self): diff --git a/electrum/gui/qml/qefx.py b/electrum/gui/qml/qefx.py index ce69cc304..c742d990d 100644 --- a/electrum/gui/qml/qefx.py +++ b/electrum/gui/qml/qefx.py @@ -1,7 +1,7 @@ from datetime import datetime from decimal import Decimal -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression from electrum.bitcoin import COIN from electrum.exchange_rate import FxThread @@ -60,6 +60,15 @@ class QEFX(QObject, QtEventListener): self.fiatCurrencyChanged.emit() self.rateSourcesChanged.emit() + @pyqtProperty('QRegularExpression', notify=fiatCurrencyChanged) + def fiatAmountRegex(self): + decimals = self.fx.ccy_precision() + exp = '[0-9]*' + if decimals: + exp += '\\.' + exp += '[0-9]{0,%d}' % decimals + return QRegularExpression(exp) + historicRatesChanged = pyqtSignal() @pyqtProperty(bool, notify=historicRatesChanged) def historicRates(self):