X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Fnew_transaction%2FNewTransactionItemHolder.java;h=f60980fa652e1b770909ac3d36b89c46f5a0cea4;hb=20c84d4501460fbe7eb3587b98e540a277b7d6db;hp=d93752e8da660ea53cef2fb9798b05c1b8de85fb;hpb=ac1a592ecbdf1557e2455976aa045de7d6b15b03;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionItemHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionItemHolder.java index d93752e8..f60980fa 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionItemHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionItemHolder.java @@ -124,8 +124,9 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder try { String input = String.valueOf(b.accountRowAccAmounts.getText()); input = input.replace(decimalSeparator, decimalDot); - b.accountRowAccAmounts.setText( - String.format("%4.2f", Float.parseFloat(input))); + final String newText = String.format("%4.2f", Float.parseFloat(input)); + if (!newText.equals(input)) + b.accountRowAccAmounts.setText(newText); } catch (NumberFormatException ex) { // ignored @@ -176,10 +177,11 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder return; Logger.debug("textWatcher", "calling syncData()"); - syncData(); - Logger.debug("textWatcher", - "syncData() returned, checking if transaction is submittable"); - adapter.model.checkTransactionSubmittable(null); + if (syncData()) { + Logger.debug("textWatcher", + "syncData() returned, checking if transaction is submittable"); + adapter.model.checkTransactionSubmittable(null); + } Logger.debug("textWatcher", "done"); } }; @@ -205,8 +207,8 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder b.currencyButton.setOnClickListener(v -> { CurrencySelectorFragment cpf = new CurrencySelectorFragment(); cpf.showPositionAndPadding(); - cpf.setOnCurrencySelectedListener( - c -> adapter.setItemCurrency(getAdapterPosition(), c.getName())); + cpf.setOnCurrencySelectedListener(c -> adapter.setItemCurrency(getAdapterPosition(), + (c == null) ? null : c.getName())); cpf.show(activity.getSupportFragmentManager(), "currency-selector"); }); @@ -214,67 +216,7 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder commentFocusChanged(b.comment, false); adapter.model.getFocusInfo() - .observe(activity, focusInfo -> { - if (ignoreFocusChanges) { - Logger.debug("new-trans", "Ignoring focus change"); - return; - } - ignoreFocusChanges = true; - try { - if (((focusInfo == null) || (focusInfo.element == null) || - focusInfo.position != getAdapterPosition()) || - itemView.hasFocus()) - return; - - NewTransactionModel.Item item = getItem(); - if (item instanceof NewTransactionModel.TransactionHead) { - NewTransactionModel.TransactionHead head = - item.toTransactionHead(); - // bad idea - double pop-up, and not really necessary. - // the user can tap the input to get the calendar - //if (!tvDate.hasFocus()) tvDate.requestFocus(); - switch (focusInfo.element) { - case TransactionComment: - b.transactionComment.setVisibility(View.VISIBLE); - b.transactionComment.requestFocus(); - break; - case Description: - boolean focused = - b.newTransactionDescription.requestFocus(); -// tvDescription.dismissDropDown(); - if (focused) - Misc.showSoftKeyboard( - (NewTransactionActivity) b.getRoot() - .getContext()); - break; - } - } - else if (item instanceof NewTransactionModel.TransactionAccount) { - NewTransactionModel.TransactionAccount acc = - item.toTransactionAccount(); - switch (focusInfo.element) { - case Amount: - b.accountRowAccAmounts.requestFocus(); - break; - case Comment: - b.comment.setVisibility(View.VISIBLE); - b.comment.requestFocus(); - break; - case Account: - boolean focused = b.accountRowAccName.requestFocus(); -// b.accountRowAccName.dismissDropDown(); - if (focused) - Misc.showSoftKeyboard( - (NewTransactionActivity) b.getRoot() - .getContext()); - break; - } - } - } - finally { - ignoreFocusChanges = false; - } - }); + .observe(activity, this::applyFocus); Data.currencyGap.observe(activity, hasGap -> updateCurrencyPositionAndPadding(Data.currencySymbolPosition.getValue(), @@ -289,12 +231,12 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder if (showCurrency) { b.currency.setVisibility(View.VISIBLE); b.currencyButton.setVisibility(View.VISIBLE); - b.currency.setText(mProfile.getDefaultCommodity()); + setCurrencyString(mProfile.getDefaultCommodity()); } else { b.currency.setVisibility(View.GONE); b.currencyButton.setVisibility(View.GONE); - b.currency.setText(null); + setCurrencyString(null); } }); @@ -330,6 +272,61 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder b.transactionCommentLayout.setVisibility(show ? View.VISIBLE : View.GONE); }); } + private void applyFocus(NewTransactionModel.FocusInfo focusInfo) { + if (ignoreFocusChanges) { + Logger.debug("new-trans", "Ignoring focus change"); + return; + } + ignoreFocusChanges = true; + try { + if (((focusInfo == null) || (focusInfo.element == null) || + focusInfo.position != getAdapterPosition())) + return; + + NewTransactionModel.Item item = getItem(); + if (item instanceof NewTransactionModel.TransactionHead) { + NewTransactionModel.TransactionHead head = item.toTransactionHead(); + // bad idea - double pop-up, and not really necessary. + // the user can tap the input to get the calendar + //if (!tvDate.hasFocus()) tvDate.requestFocus(); + switch (focusInfo.element) { + case TransactionComment: + b.transactionComment.setVisibility(View.VISIBLE); + b.transactionComment.requestFocus(); + break; + case Description: + boolean focused = b.newTransactionDescription.requestFocus(); +// tvDescription.dismissDropDown(); + if (focused) + Misc.showSoftKeyboard((NewTransactionActivity) b.getRoot() + .getContext()); + break; + } + } + else if (item instanceof NewTransactionModel.TransactionAccount) { + NewTransactionModel.TransactionAccount acc = item.toTransactionAccount(); + switch (focusInfo.element) { + case Amount: + b.accountRowAccAmounts.requestFocus(); + break; + case Comment: + b.comment.setVisibility(View.VISIBLE); + b.comment.requestFocus(); + break; + case Account: + boolean focused = b.accountRowAccName.requestFocus(); +// b.accountRowAccName.dismissDropDown(); + if (focused) + Misc.showSoftKeyboard((NewTransactionActivity) b.getRoot() + .getContext()); + break; + } + } + } + finally { + ignoreFocusChanges = false; + } + } public void checkAmountValid(String s) { boolean valid = true; try { @@ -440,7 +437,7 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder private void setCurrencyString(String currency) { @ColorInt int textColor = b.dummyText.getTextColors() .getDefaultColor(); - if ((currency == null) || currency.isEmpty()) { + if (TextUtils.isEmpty(currency)) { b.currency.setText(R.string.currency_symbol); int alpha = (textColor >> 24) & 0xff; alpha = alpha * 3 / 4; @@ -487,17 +484,35 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder syncingData = true; + boolean significantChange = false; + try { if (item instanceof NewTransactionModel.TransactionHead) { NewTransactionModel.TransactionHead head = item.toTransactionHead(); head.setDate(String.valueOf(b.newTransactionDate.getText())); + + // transaction description is required + if (TextUtils.isEmpty(head.getDescription()) != + TextUtils.isEmpty(b.newTransactionDescription.getText())) + significantChange = true; + head.setDescription(String.valueOf(b.newTransactionDescription.getText())); head.setComment(String.valueOf(b.transactionComment.getText())); } else if (item instanceof NewTransactionModel.TransactionAccount) { NewTransactionModel.TransactionAccount acc = item.toTransactionAccount(); - acc.setAccountName(String.valueOf(b.accountRowAccName.getText())); + + // having account name is important + final Editable incomingAccountName = b.accountRowAccName.getText(); + if (TextUtils.isEmpty(acc.getAccountName()) != + TextUtils.isEmpty(incomingAccountName)) + significantChange = true; + + acc.setAccountName(String.valueOf(incomingAccountName)); + final int accNameSelEnd = b.accountRowAccName.getSelectionEnd(); + final int accNameSelStart = b.accountRowAccName.getSelectionStart(); + acc.setAccountNameCursorPosition(accNameSelEnd); acc.setComment(String.valueOf(b.comment.getText())); @@ -505,36 +520,48 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder amount = amount.trim(); if (amount.isEmpty()) { + if (acc.isAmountSet()) + significantChange = true; acc.resetAmount(); acc.setAmountValid(true); } else { try { amount = amount.replace(decimalSeparator, decimalDot); - acc.setAmount(Float.parseFloat(amount)); + 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.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()) - acc.setCurrency(null); + currValue = null; else - acc.setCurrency(curr); + currValue = curr; + + if (!significantChange && !TextUtils.equals(acc.getCurrency(), currValue)) + significantChange = true; + acc.setCurrency(currValue); } } else { throw new RuntimeException("Should not happen"); } - return true; + return significantChange; } catch (ParseException e) { throw new RuntimeException("Should not happen", e); @@ -582,21 +609,29 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder b.ntrData.setVisibility(View.VISIBLE); b.ntrAccount.setVisibility(View.GONE); - b.ntrPadding.setVisibility(View.GONE); setEditable(true); } else if (item instanceof NewTransactionModel.TransactionAccount) { NewTransactionModel.TransactionAccount acc = item.toTransactionAccount(); - // avoid triggering completion pop-up - AccountAutocompleteAdapter a = - (AccountAutocompleteAdapter) b.accountRowAccName.getAdapter(); - try { - b.accountRowAccName.setAdapter(null); - b.accountRowAccName.setText(acc.getAccountName()); - } - finally { - b.accountRowAccName.setAdapter(a); + final String incomingAccountName = acc.getAccountName(); + final String presentAccountName = String.valueOf(b.accountRowAccName.getText()); + if (!TextUtils.equals(incomingAccountName, presentAccountName)) { + Logger.debug("bind", + String.format("Setting account name from '%s' to '%s' (| @ %d)", + presentAccountName, incomingAccountName, + acc.getAccountNameCursorPosition())); + // avoid triggering completion pop-up + AccountAutocompleteAdapter a = + (AccountAutocompleteAdapter) b.accountRowAccName.getAdapter(); + try { + b.accountRowAccName.setAdapter(null); + b.accountRowAccName.setText(incomingAccountName); + b.accountRowAccName.setSelection(acc.getAccountNameCursorPosition()); + } + finally { + b.accountRowAccName.setAdapter(a); + } } final String amountHint = acc.getAmountHint(); @@ -619,13 +654,15 @@ class NewTransactionItemHolder extends RecyclerView.ViewHolder b.ntrData.setVisibility(View.GONE); b.ntrAccount.setVisibility(View.VISIBLE); - b.ntrPadding.setVisibility(View.GONE); setEditable(true); } else { throw new RuntimeException("Don't know how to handle " + item); } + + applyFocus(mAdapter.model.getFocusInfo() + .getValue()); } finally { syncingData = false;