X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Fnew_transaction%2FNewTransactionModel.java;h=f17f77b17b1c97c8e2e461779c751c95f1456f0b;hb=3173a61c334646acf7cdd776b1001243dddd1baa;hp=d092be213a9e008cab7519985812e5ad37171270;hpb=fc6385026ff7f7fb74c7e21f6243a1fa90eb352e;p=mobile-ledger.git 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 d092be21..f17f77b1 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 @@ -18,8 +18,6 @@ package net.ktnx.mobileledger.ui.new_transaction; import android.annotation.SuppressLint; -import android.os.Handler; -import android.os.Looper; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -31,15 +29,17 @@ import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; import net.ktnx.mobileledger.BuildConfig; +import net.ktnx.mobileledger.db.Currency; import net.ktnx.mobileledger.db.DB; +import net.ktnx.mobileledger.db.Profile; import net.ktnx.mobileledger.db.TemplateAccount; import net.ktnx.mobileledger.db.TemplateHeader; +import net.ktnx.mobileledger.db.TransactionWithAccounts; import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.model.InertMutableLiveData; import net.ktnx.mobileledger.model.LedgerTransaction; import net.ktnx.mobileledger.model.LedgerTransactionAccount; import net.ktnx.mobileledger.model.MatchedTemplate; -import net.ktnx.mobileledger.model.MobileLedgerProfile; import net.ktnx.mobileledger.utils.Globals; import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.Misc; @@ -73,7 +73,7 @@ public class NewTransactionModel extends ViewModel { private final MutableLiveData simulateSave = new InertMutableLiveData<>(false); private final AtomicInteger busyCounter = new AtomicInteger(0); private final MutableLiveData busyFlag = new InertMutableLiveData<>(false); - private final Observer profileObserver = profile -> { + private final Observer profileObserver = profile -> { showCurrency.postValue(profile.getShowCommodityByDefault()); showComments.postValue(profile.getShowCommentsByDefault()); }; @@ -92,6 +92,26 @@ public class NewTransactionModel extends ViewModel { checkTransactionSubmittable(newList); setItemsWithoutSubmittableChecks(newList); } + private void replaceItems(@NonNull List newList) { + renumberItems(); + + setItems(newList); + } + /** + * make old items replaceable in-place. makes the new values visually blend in + */ + private void renumberItems() { + renumberItems(items.getValue()); + } + private void renumberItems(List list) { + if (list == null) { + return; + } + + int id = 0; + for (Item item : list) + item.id = id++; + } private void setItemsWithoutSubmittableChecks(@NonNull List list) { final int cnt = list.size(); for (int i = 1; i < cnt - 1; i++) { @@ -170,10 +190,14 @@ public class NewTransactionModel extends ViewModel { void reset() { Logger.debug("new-trans", "Resetting model"); List list = new ArrayList<>(); + Item.resetIdDispenser(); list.add(new TransactionHead("")); - list.add(new TransactionAccount("")); - list.add(new TransactionAccount("")); + final String defaultCurrency = Objects.requireNonNull(Data.getProfile()) + .getDefaultCommodity(); + list.add(new TransactionAccount("", defaultCurrency)); + list.add(new TransactionAccount("", defaultCurrency)); noteFocusChanged(0, FocusedElement.Description); + renumberItems(); isSubmittable.setValue(false); setItemsWithoutSubmittableChecks(list); } @@ -270,25 +294,31 @@ public class NewTransactionModel extends ViewModel { if (amount != null && acc.getNegateAmount() != null && acc.getNegateAmount()) amount = -amount; - // TODO currency TransactionAccount accRow = new TransactionAccount(accountName); accRow.setComment(accountComment); if (amount != null) accRow.setAmount(amount); + accRow.setCurrency( + extractCurrencyFromMatches(matchResult, acc.getCurrencyMatchGroup(), + acc.getCurrencyObject())); newItems.add(accRow); } - new Handler(Looper.getMainLooper()).post(() -> setItems(newItems)); + renumberItems(newItems); + Misc.onMainThread(() -> replaceItems(newItems)); }); } + private String extractCurrencyFromMatches(MatchResult m, Integer group, Currency literal) { + return extractStringFromMatches(m, group, (literal == null) ? "" : literal.getName()); + } private int extractIntFromMatches(MatchResult m, Integer group, Integer literal) { if (literal != null) return literal; if (group != null) { int grp = group; - if (grp > 0 & grp <= m.groupCount()) + if (grp > 0 && grp <= m.groupCount()) try { return Integer.parseInt(m.group(grp)); } @@ -305,7 +335,7 @@ public class NewTransactionModel extends ViewModel { if (group != null) { int grp = group; - if (grp > 0 & grp <= m.groupCount()) + if (grp > 0 && grp <= m.groupCount()) return m.group(grp); } @@ -317,7 +347,7 @@ public class NewTransactionModel extends ViewModel { if (group != null) { int grp = group; - if (grp > 0 & grp <= m.groupCount()) + if (grp > 0 && grp <= m.groupCount()) try { return Float.valueOf(m.group(grp)); } @@ -348,6 +378,11 @@ public class NewTransactionModel extends ViewModel { List newList = shallowCopyList(); Item item = newList.remove(fromIndex); newList.add(toIndex, item); + + FocusInfo fi = focusInfo.getValue(); + if (fi != null && fi.position == fromIndex) + noteFocusChanged(toIndex, fi.element); + items.setValue(newList); // same count, same submittable state } void moveItemLast(List list, int index) { @@ -401,7 +436,6 @@ public class NewTransactionModel extends ViewModel { List list = Objects.requireNonNull(items.getValue()); TransactionHead head = list.get(0) .toTransactionHead(); - SimpleDate date = head.getDate(); LedgerTransaction tr = head.asLedgerTransaction(); tr.setComment(head.getComment()); @@ -435,22 +469,23 @@ public class NewTransactionModel extends ViewModel { return tr; } - void loadTransactionIntoModel(String profileUUID, int transactionId) { + void loadTransactionIntoModel(@NonNull TransactionWithAccounts tr) { List newList = new ArrayList<>(); - LedgerTransaction tr; - MobileLedgerProfile profile = Data.getProfile(profileUUID); - if (profile == null) - throw new RuntimeException(String.format( - "Unable to find profile %s, which is supposed to contain transaction %d", - profileUUID, transactionId)); + Item.resetIdDispenser(); - tr = profile.loadTransaction(transactionId); - TransactionHead head = new TransactionHead(tr.getDescription()); - head.setComment(tr.getComment()); + Item currentHead = items.getValue() + .get(0); + TransactionHead head = new TransactionHead(tr.transaction.getDescription()); + head.setComment(tr.transaction.getComment()); + if (currentHead instanceof TransactionHead) + head.setDate(((TransactionHead) currentHead).date); newList.add(head); - List accounts = tr.getAccounts(); + List accounts = new ArrayList<>(); + for (net.ktnx.mobileledger.db.TransactionAccount acc : tr.accounts) { + accounts.add(new LedgerTransactionAccount(acc)); + } TransactionAccount firstNegative = null; TransactionAccount firstPositive = null; @@ -499,9 +534,10 @@ public class NewTransactionModel extends ViewModel { moveItemLast(newList, singlePositiveIndex); } - setItems(newList); - - noteFocusChanged(1, FocusedElement.Amount); + Misc.onMainThread(() -> { + setItems(newList); + noteFocusChanged(1, FocusedElement.Amount); + }); } /** * A transaction is submittable if: @@ -529,7 +565,8 @@ public class NewTransactionModel extends ViewModel { } if (BuildConfig.DEBUG) - dumpItemList("Before submittable checks", list); + dumpItemList(String.format("Before submittable checks (%s)", + workingWithLiveList ? "LIVE LIST" : "custom list"), list); int accounts = 0; final BalanceForCurrency balance = new BalanceForCurrency(); @@ -682,7 +719,7 @@ public class NewTransactionModel extends ViewModel { if (item == receiver) { final String hint = String.format("%1.2f", -currencyBalance); if (!acc.isAmountHintSet() || - !TextUtils.equals(acc.getAmountHint(), hint)) + !Misc.equalStrings(acc.getAmountHint(), hint)) { Logger.debug("submittable", String.format("Setting amount hint of {%s} to %s [%s]", @@ -859,9 +896,15 @@ public class NewTransactionModel extends ViewModel { private static int idDispenser = 0; protected int id; private Item() { - synchronized (Item.class) { - id = ++idDispenser; - } + if (this instanceof TransactionHead) + id = 0; + else + synchronized (Item.class) { + id = ++idDispenser; + } + } + public Item(int id) { + this.id = id; } public static Item from(Item origin) { if (origin instanceof TransactionHead) @@ -870,6 +913,9 @@ public class NewTransactionModel extends ViewModel { return new TransactionAccount((TransactionAccount) origin); throw new RuntimeException("Don't know how to handle " + origin); } + private static void resetIdDispenser() { + idDispenser = 0; + } public int getId() { return id; } @@ -918,7 +964,7 @@ public class NewTransactionModel extends ViewModel { this.description = description; } public TransactionHead(TransactionHead origin) { - id = origin.id; + super(origin.id); date = origin.date; description = origin.description; comment = origin.comment; @@ -967,7 +1013,7 @@ public class NewTransactionModel extends ViewModel { if (TextUtils.isEmpty(description)) b.append(" «no description»"); else - b.append(String.format(" descr'%s'", description)); + b.append(String.format(" '%s'", description)); if (date != null) b.append(String.format("@%s", date.toString())); @@ -994,15 +1040,16 @@ public class NewTransactionModel extends ViewModel { return ItemType.generalData; } public LedgerTransaction asLedgerTransaction() { - return new LedgerTransaction(null, date, description, Data.getProfile()); + return new LedgerTransaction(0, (date == null) ? SimpleDate.today() : date, description, + Data.getProfile()); } public boolean equalContents(TransactionHead other) { if (other == null) return false; return Objects.equals(date, other.date) && - TextUtils.equals(description, other.description) && - TextUtils.equals(comment, other.comment); + Misc.equalStrings(description, other.description) && + Misc.equalStrings(comment, other.comment); } } @@ -1019,7 +1066,7 @@ public class NewTransactionModel extends ViewModel { private boolean isLast = false; private int accountNameCursorPosition; public TransactionAccount(TransactionAccount origin) { - id = origin.id; + super(origin.id); accountName = origin.accountName; amount = origin.amount; amountSet = origin.amountSet; @@ -1144,16 +1191,16 @@ public class NewTransactionModel extends ViewModel { if (other == null) return false; - boolean equal = TextUtils.equals(accountName, other.accountName); - equal = equal && TextUtils.equals(comment, other.comment) && + boolean equal = Misc.equalStrings(accountName, other.accountName); + equal = equal && Misc.equalStrings(comment, other.comment) && (amountSet ? other.amountSet && amount == other.amount : !other.amountSet); // compare amount hint only if there is no amount if (!amountSet) equal = equal && (amountHintIsSet ? other.amountHintIsSet && - TextUtils.equals(amountHint, other.amountHint) + Misc.equalStrings(amountHint, other.amountHint) : !other.amountHintIsSet); - equal = equal && TextUtils.equals(currency, other.currency) && isLast == other.isLast; + equal = equal && Misc.equalStrings(currency, other.currency) && isLast == other.isLast; Logger.debug("new-trans", String.format("Comparing {%s} and {%s}: %s", this.toString(), other.toString(),