]> git.ktnx.net Git - mobile-ledger.git/commitdiff
maintain amount text independent from the amount
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 23 May 2021 14:29:54 +0000 (17:29 +0300)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 23 May 2021 14:29:54 +0000 (17:29 +0300)
for example, the text may not be a valid amount, i.e. a sole "-"

app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java
app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionModel.java

index 0725f92c4beb2add32966c198228ab204f767c6f..04291c8dfb9e75c086650ef35d52046fd4390fb7 100644 (file)
@@ -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);
index cfe9c5d951d94604121e4f938606047bc0cedb86..35bb3c82889c700efbc6e62e2bf91c7110157778 100644 (file)
@@ -162,7 +162,7 @@ public class NewTransactionModel extends ViewModel {
         return copy;
     }
     private List<Item> shallowCopyList() {
-        return new ArrayList<>(items.getValue());
+        return new ArrayList<>(Objects.requireNonNull(items.getValue()));
     }
     LiveData<Boolean> 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)