2022-09-15 10:12:38 +00:00
|
|
|
import QtQuick 2.14
|
|
|
|
import QtQuick.Layouts 1.14
|
|
|
|
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import StatusQ.Core.Theme 0.1
|
2023-08-10 12:23:59 +00:00
|
|
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
2022-09-15 10:12:38 +00:00
|
|
|
|
|
|
|
import utils 1.0
|
|
|
|
|
|
|
|
Input {
|
|
|
|
id: root
|
|
|
|
|
|
|
|
property int maximumLength: 10
|
2024-04-16 09:09:02 +00:00
|
|
|
property var locale: LocaleUtils.userInputLocale
|
2022-09-15 10:12:38 +00:00
|
|
|
|
|
|
|
readonly property alias amount: d.amount
|
2023-08-10 12:23:59 +00:00
|
|
|
property alias multiplierIndex: d.multiplierIndex
|
|
|
|
|
2022-09-15 10:12:38 +00:00
|
|
|
readonly property bool valid: validationError.length === 0
|
|
|
|
property bool allowDecimals: true
|
|
|
|
|
2023-04-27 21:38:09 +00:00
|
|
|
property bool validateMaximumAmount: false
|
2023-08-10 12:23:59 +00:00
|
|
|
property string maximumAmount: "0"
|
2023-08-30 08:05:48 +00:00
|
|
|
property bool allowZero: true
|
|
|
|
|
|
|
|
property alias labelText: labelText.text
|
|
|
|
|
|
|
|
property string maximumExceededErrorText: qsTr("Amount exceeds balance")
|
2023-04-27 21:38:09 +00:00
|
|
|
|
2022-09-15 10:12:38 +00:00
|
|
|
validationErrorTopMargin: 8
|
|
|
|
fontPixelSize: 13
|
|
|
|
customHeight: 36
|
|
|
|
placeholderText: locale.zeroDigit
|
|
|
|
|
|
|
|
textField.rightPadding: labelText.implicitWidth + labelText.anchors.rightMargin
|
|
|
|
+ textField.leftPadding
|
|
|
|
|
2023-08-10 12:23:59 +00:00
|
|
|
function setAmount(amount, multiplierIndex = 0) {
|
|
|
|
console.assert(typeof amount === "string")
|
|
|
|
|
|
|
|
d.multiplierIndex = multiplierIndex
|
|
|
|
const amountNumber = SQUtils.AmountsArithmetic.toNumber(
|
|
|
|
amount, multiplierIndex)
|
|
|
|
|
|
|
|
root.text = LocaleUtils.numberToLocaleString(amountNumber, -1,
|
|
|
|
root.locale)
|
2022-09-15 10:12:38 +00:00
|
|
|
}
|
|
|
|
|
2023-04-27 21:38:09 +00:00
|
|
|
onTextChanged: d.validate()
|
|
|
|
onValidateMaximumAmountChanged: d.validate()
|
|
|
|
onMaximumAmountChanged: d.validate()
|
2023-08-10 12:23:59 +00:00
|
|
|
onMultiplierIndexChanged: d.validate()
|
2023-04-27 21:38:09 +00:00
|
|
|
|
2022-09-15 10:12:38 +00:00
|
|
|
QtObject {
|
|
|
|
id: d
|
|
|
|
|
2023-08-10 12:23:59 +00:00
|
|
|
property string amount: "0"
|
|
|
|
property int multiplierIndex: 0
|
2023-03-02 11:33:14 +00:00
|
|
|
|
|
|
|
function getEffectiveDigitsCount(str) {
|
|
|
|
const digits = LocaleUtils.getLocalizedDigitsCount(text, root.locale)
|
2024-04-16 09:09:02 +00:00
|
|
|
return str.startsWith(root.locale.decimalPoint) ? digits + 1 : digits
|
2023-03-02 11:33:14 +00:00
|
|
|
}
|
2023-04-27 21:38:09 +00:00
|
|
|
|
|
|
|
function validate() {
|
|
|
|
if (!root.allowDecimals)
|
|
|
|
root.text = root.text.replace(root.locale.decimalPoint, "")
|
|
|
|
|
|
|
|
if(root.text.length === 0) {
|
2023-08-10 12:23:59 +00:00
|
|
|
d.amount = "0"
|
2023-04-27 21:38:09 +00:00
|
|
|
root.validationError = ""
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d.getEffectiveDigitsCount(text) > root.maximumLength) {
|
|
|
|
root.validationError = qsTr("The maximum number of characters is %1").arg(root.maximumLength)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-08-10 12:23:59 +00:00
|
|
|
const amountNumber = LocaleUtils.numberFromLocaleString(root.text, root.locale)
|
|
|
|
if (isNaN(amountNumber)) {
|
|
|
|
d.amount = "0"
|
2023-04-27 21:38:09 +00:00
|
|
|
root.validationError = qsTr("Invalid amount format")
|
2023-08-10 12:23:59 +00:00
|
|
|
return
|
2023-04-27 21:38:09 +00:00
|
|
|
}
|
2023-08-10 12:23:59 +00:00
|
|
|
|
2023-08-30 08:05:48 +00:00
|
|
|
if (!root.allowZero && amountNumber === 0) {
|
|
|
|
d.amount = "0"
|
|
|
|
root.validationError = qsTr("Amount must be greater than 0")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-08-10 12:23:59 +00:00
|
|
|
const amount = SQUtils.AmountsArithmetic.fromNumber(
|
|
|
|
amountNumber, d.multiplierIndex)
|
|
|
|
|
|
|
|
if (root.validateMaximumAmount) {
|
|
|
|
const maximumAmount = SQUtils.AmountsArithmetic.fromString(
|
|
|
|
root.maximumAmount)
|
|
|
|
|
|
|
|
const maxExceeded = SQUtils.AmountsArithmetic.cmp(
|
|
|
|
amount, maximumAmount) === 1
|
|
|
|
|
|
|
|
if (SQUtils.AmountsArithmetic.cmp(amount, maximumAmount) === 1) {
|
2023-08-30 08:05:48 +00:00
|
|
|
root.validationError = root.maximumExceededErrorText
|
2023-08-10 12:23:59 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fallback to handle float amounts for permissions
|
|
|
|
// As a target amount should be always integer number
|
|
|
|
if (!Number.isInteger(amountNumber) && d.multiplierIndex === 0) {
|
|
|
|
d.amount = amount.toString()
|
|
|
|
} else {
|
|
|
|
d.amount = amount.toFixed(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
root.validationError = ""
|
2023-04-27 21:38:09 +00:00
|
|
|
}
|
2022-09-15 10:12:38 +00:00
|
|
|
}
|
|
|
|
|
2023-01-17 22:56:58 +00:00
|
|
|
validator: DoubleValidator {
|
2022-09-15 10:12:38 +00:00
|
|
|
decimals: root.allowDecimals ? 100 : 0
|
|
|
|
bottom: 0
|
|
|
|
notation: DoubleValidator.StandardNotation
|
2023-05-08 18:18:24 +00:00
|
|
|
locale: root.locale.name.split("_")[0] // For whatever reason, this doesn't work properly when being
|
|
|
|
// passed "language_country". We pass only the language part.
|
2022-09-15 10:12:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StatusBaseText {
|
|
|
|
id: labelText
|
|
|
|
|
|
|
|
parent: root.textField
|
|
|
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.rightMargin: 13
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
text: qsTr("Amount")
|
|
|
|
color: Theme.palette.baseColor1
|
|
|
|
font.pixelSize: 13
|
|
|
|
}
|
|
|
|
}
|