From 426a2bd8f495b5cf802e20248599dc5e08309aaf Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 23 May 2021 17:29:54 +0300 Subject: [PATCH] maintain amount text independent from the amount for example, the text may not be a valid amount, i.e. a sole "-" --- .../NewTransactionAccountRowItemHolder.java | 84 +++++++------------ .../new_transaction/NewTransactionModel.java | 77 +++++++++++++---- 2 files changed, 93 insertions(+), 68 deletions(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java index 0725f92c..04291c8d 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java @@ -44,13 +44,11 @@ import net.ktnx.mobileledger.utils.DimensionUtils; import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.Misc; -import java.text.DecimalFormatSymbols; +import java.text.ParseException; class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { - private final String decimalDot = "."; private final NewTransactionAccountRowBinding b; private boolean ignoreFocusChanges = false; - private String decimalSeparator; private boolean inUpdate = false; private boolean syncingData = false; NewTransactionAccountRowItemHolder(@NonNull NewTransactionAccountRowBinding b, @@ -94,12 +92,13 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { if (id == R.id.account_row_acc_amounts) { try { String input = String.valueOf(b.accountRowAccAmounts.getText()); - input = input.replace(decimalSeparator, decimalDot); - final String newText = String.format("%4.2f", Float.parseFloat(input)); + input = input.replace(Data.getDecimalSeparator(), Data.decimalDot); + final String newText = Data.formatNumber(Float.parseFloat(input)); if (!newText.equals(input)) { boolean wasSyncingData = syncingData; syncingData = true; try { + // FIXME this needs to reach the model somehow b.accountRowAccAmounts.setText(newText); } finally { @@ -129,11 +128,6 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { .getContext(), mProfile)); - decimalSeparator = ""; - Data.locale.observe(activity, locale -> decimalSeparator = String.valueOf( - DecimalFormatSymbols.getInstance(locale) - .getMonetaryDecimalSeparator())); - final TextWatcher tw = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -252,14 +246,21 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { } } public void checkAmountValid(String s) { + // FIXME this needs to be done in the model only boolean valid = true; try { if (s.length() > 0) { - float ignored = Float.parseFloat(s.replace(decimalSeparator, decimalDot)); + float ignored = + Float.parseFloat(s.replace(Data.getDecimalSeparator(), Data.decimalDot)); } } catch (NumberFormatException ex) { - valid = false; + try { + float ignored = Data.parseNumber(s); + } + catch (ParseException ex2) { + valid = false; + } } displayAmountValidity(valid); @@ -432,45 +433,23 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { acc.setComment(String.valueOf(b.comment.getText())); String amount = String.valueOf(b.accountRowAccAmounts.getText()); - amount = amount.trim(); - if (amount.isEmpty()) { - if (acc.isAmountSet()) - significantChange = true; - acc.resetAmount(); - acc.setAmountValid(true); - } - else { - try { - amount = amount.replace(decimalSeparator, decimalDot); - final float parsedAmount = Float.parseFloat(amount); - if (!acc.isAmountSet() || !Misc.equalFloats(parsedAmount, acc.getAmount())) - significantChange = true; - acc.setAmount(parsedAmount); - acc.setAmountValid(true); - } - catch (NumberFormatException e) { - Logger.debug("new-trans", String.format( - "assuming amount is not set due to number format exception. " + - "input was '%s'", amount)); - if (acc.isAmountValid()) - significantChange = true; - acc.resetAmount(); - acc.setAmountValid(false); - } - final String curr = String.valueOf(b.currency.getText()); - final String currValue; - if (curr.equals(b.currency.getContext() - .getResources() - .getString(R.string.currency_symbol)) || curr.isEmpty()) - currValue = null; - else - currValue = curr; - - if (!significantChange && !Misc.equalStrings(acc.getCurrency(), currValue)) - significantChange = true; - acc.setCurrency(currValue); - } + if (acc.setAndCheckAmountText(Misc.nullIsEmpty(amount))) + significantChange = true; + displayAmountValidity(!acc.isAmountSet() || acc.isAmountValid()); + + final String curr = String.valueOf(b.currency.getText()); + final String currValue; + if (curr.equals(b.currency.getContext() + .getResources() + .getString(R.string.currency_symbol)) || curr.isEmpty()) + currValue = null; + else + currValue = curr; + + if (!significantChange && !Misc.equalStrings(acc.getCurrency(), currValue)) + significantChange = true; + acc.setCurrency(currValue); return significantChange; } @@ -523,9 +502,8 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { acc.isLast() ? EditorInfo.IME_ACTION_DONE : EditorInfo.IME_ACTION_NEXT); setCurrencyString(acc.getCurrency()); - b.accountRowAccAmounts.setText( - acc.isAmountSet() ? String.format("%4.2f", acc.getAmount()) : null); - displayAmountValidity(true); + b.accountRowAccAmounts.setText(acc.getAmountText()); + displayAmountValidity(!acc.isAmountSet() || acc.isAmountValid()); final String comment = acc.getComment(); b.comment.setText(comment); diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionModel.java index cfe9c5d9..35bb3c82 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionModel.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionModel.java @@ -162,7 +162,7 @@ public class NewTransactionModel extends ViewModel { return copy; } private List shallowCopyList() { - return new ArrayList<>(items.getValue()); + return new ArrayList<>(Objects.requireNonNull(items.getValue())); } LiveData getShowComments() { return showComments; @@ -626,15 +626,14 @@ public class NewTransactionModel extends ViewModel { itemsWithAccountForCurrency.add(currName, item); } - if (item.isAmountSet()) { + if (item.isAmountSet() && item.isAmountValid()) { itemsWithAmountForCurrency.add(currName, item); balance.add(currName, item.getAmount()); } else { if (!item.isAmountValid()) { Logger.debug("submittable", - String.format("Not submittable: row %d has an invalid amount", - i + 1)); + String.format("Not submittable: row %d has an invalid amount", i)); submittable = false; hasInvalidAmount = true; } @@ -725,7 +724,7 @@ public class NewTransactionModel extends ViewModel { continue; if (item == receiver) { - final String hint = String.format("%1.2f", -currencyBalance); + final String hint = Data.formatNumber(-currencyBalance); if (!acc.isAmountHintSet() || !Misc.equalStrings(acc.getAmountHint(), hint)) { @@ -772,7 +771,7 @@ public class NewTransactionModel extends ViewModel { // if (Misc.isZero(balance.get(itemCurrencyName))) { // item.setCurrency(Currency.loadByName(balCurrency)); // item.setAmountHint( -// String.format("%1.2f", -balance.get(balCurrency))); +// Data.formatNumber(-balance.get(balCurrency))); // foundIt = true; // break; // } @@ -782,7 +781,7 @@ public class NewTransactionModel extends ViewModel { final TransactionAccount newAcc = new TransactionAccount("", balCurrency); final float bal = balance.get(balCurrency); if (!Misc.isZero(bal) && currAmounts == currRows) - newAcc.setAmountHint(String.format("%4.2f", -bal)); + newAcc.setAmountHint(Data.formatNumber(-bal)); Logger.debug("submittable", String.format("Adding new item with %s for currency %s", newAcc.getAmountHint(), balCurrency)); @@ -1072,6 +1071,8 @@ public class NewTransactionModel extends ViewModel { private float amount; private boolean amountSet; private boolean amountValid = true; + @NotNull + private String amountText = ""; private FocusedElement focusedElement = FocusedElement.Account; private boolean amountHintIsSet = false; private boolean isLast = false; @@ -1083,6 +1084,7 @@ public class NewTransactionModel extends ViewModel { amountSet = origin.amountSet; amountHint = origin.amountHint; amountHintIsSet = origin.amountHintIsSet; + amountText = origin.amountText; comment = origin.comment; currency = origin.currency; amountValid = origin.amountValid; @@ -1090,11 +1092,6 @@ public class NewTransactionModel extends ViewModel { isLast = origin.isLast; accountNameCursorPosition = origin.accountNameCursorPosition; } - public TransactionAccount(LedgerTransactionAccount account) { - super(); - currency = Misc.nullIsEmpty(account.getCurrency()); - amount = account.getAmount(); - } public TransactionAccount(String accountName) { super(); this.accountName = accountName; @@ -1104,6 +1101,46 @@ public class NewTransactionModel extends ViewModel { this.accountName = accountName; this.currency = currency; } + public @NotNull String getAmountText() { + return amountText; + } + public void setAmountText(@NotNull String amountText) { + this.amountText = amountText; + } + public boolean setAndCheckAmountText(@NotNull String amountText) { + String amtText = amountText.trim(); + this.amountText = amtText; + + boolean significantChange = false; + + if (amtText.isEmpty()) { + if (amountSet) { + significantChange = true; + } + resetAmount(); + } + else { + try { + amtText = amtText.replace(Data.getDecimalSeparator(), Data.decimalDot); + final float parsedAmount = Float.parseFloat(amtText); + if (!amountSet || !amountValid || !Misc.equalFloats(parsedAmount, amount)) + significantChange = true; + amount = parsedAmount; + amountSet = true; + amountValid = true; + } + catch (NumberFormatException e) { + Logger.debug("new-trans", String.format( + "assuming amount is not set due to number format exception. " + + "input was '%s'", amtText)); + if (amountValid) // it was valid and now it's not + significantChange = true; + amountValid = false; + } + } + + return significantChange; + } public boolean isLast() { return isLast; } @@ -1124,9 +1161,13 @@ public class NewTransactionModel extends ViewModel { public void setAmount(float amount) { this.amount = amount; amountSet = true; + amountValid = true; + amountText = Data.formatNumber(amount); } public void resetAmount() { amountSet = false; + amountValid = true; + amountText = ""; } @Override public ItemType getType() { @@ -1184,9 +1225,13 @@ public class NewTransactionModel extends ViewModel { b.append(String.format(" acc'%s'", accountName)); if (amountSet) - b.append(String.format(" %4.2f", amount)); + b.append(amountText) + .append(" [") + .append(amountValid ? "valid" : "invalid") + .append("] ") + .append(String.format(Locale.ROOT, " {raw %4.2f}", amount)); else if (amountHintIsSet) - b.append(String.format(" (%s)", amountHint)); + b.append(String.format(" (hint %s)", amountHint)); if (!TextUtils.isEmpty(currency)) b.append(" ") @@ -1206,7 +1251,9 @@ public class NewTransactionModel extends ViewModel { boolean equal = Misc.equalStrings(accountName, other.accountName); equal = equal && Misc.equalStrings(comment, other.comment) && - (amountSet ? other.amountSet && amount == other.amount : !other.amountSet); + (amountSet ? other.amountSet && amountValid == other.amountValid && + Misc.equalStrings(amountText, other.amountText) + : !other.amountSet); // compare amount hint only if there is no amount if (!amountSet) -- 2.39.5