private boolean amountSet = false;
private String currency;
private String comment;
+ private boolean amountValid = true;
public LedgerTransactionAccount(String accountName, float amount, String currency,
String comment) {
this.setAccountName(accountName);
this.amount = amount;
this.amountSet = true;
+ this.amountValid = true;
this.currency = Misc.emptyIsNull(currency);
this.comment = Misc.emptyIsNull(comment);
}
setComment(origin.getComment());
if (origin.isAmountSet())
setAmount(origin.getAmount());
+ amountValid = origin.amountValid;
currency = origin.getCurrency();
}
public String getComment() {
public void setAmount(float account_amount) {
this.amount = account_amount;
this.amountSet = true;
+ this.amountValid = true;
}
public void resetAmount() {
this.amountSet = false;
+ this.amountValid = true;
+ }
+ public void invalidateAmount() {
+ this.amountValid = false;
}
public boolean isAmountSet() {
return amountSet;
}
+ public boolean isAmountValid() { return amountValid; }
public String getCurrency() {
return currency;
}
private Observer<Currency> currencyObserver;
private Observer<Boolean> showCurrencyObserver;
private Observer<String> commentObserver;
+ private Observer<Boolean> amountValidityObserver;
private boolean inUpdate = false;
private boolean syncingData = false;
private View commentButton;
});
transactionCommentLayout.findViewById(R.id.comment_button)
- .setOnClickListener(v -> {
- tvTransactionComment.setVisibility(View.VISIBLE);
- tvTransactionComment.requestFocus();
- });
+ .setOnClickListener(v -> {
+ tvTransactionComment.setVisibility(View.VISIBLE);
+ tvTransactionComment.requestFocus();
+ });
mProfile = Data.profile.getValue();
if (mProfile == null)
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
- // only one decimal separator is allowed
- // plus and minus are allowed only at the beginning
- String allowed = "0123456789";
- String val = s.toString();
- Logger.debug("input", val);
- if (val.isEmpty() || (tvAmount.getSelectionStart() == 0))
- allowed += "-";
- if (!val.contains(decimalSeparator) && !val.contains(decimalDot))
- allowed += decimalSeparator + decimalDot;
-
- tvAmount.setKeyListener(DigitsKeyListener.getInstance(allowed));
- }
if (syncData())
adapter.checkTransactionSubmittable();
transactionCommentLayout.setVisibility(show ? View.VISIBLE : View.GONE);
};
+
+ amountValidityObserver = valid -> {
+ tvAmount.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ valid ? 0 : R.drawable.ic_error_outline_black_24dp, 0, 0, 0);
+ tvAmount.setMinEms(valid ? 4 : 5);
+ };
}
private void commentFocusChanged(View layout, TextView textView, boolean hasFocus) {
int textColor;
if (amount.isEmpty()) {
account.resetAmount();
-// account.setCurrency(null);
+ item.validateAmount();
}
else {
try {
amount = amount.replace(decimalSeparator, decimalDot);
account.setAmount(Float.parseFloat(amount));
+ item.validateAmount();
}
catch (NumberFormatException e) {
Logger.debug("new-trans", String.format(
"assuming amount is not set due to number format exception. " +
"input was '%s'", amount));
- account.resetAmount();
+ account.invalidateAmount();
+ item.invalidateAmount();
}
final String curr = String.valueOf(tvCurrency.getText());
if (curr.equals(tvCurrency.getContext()
this.item.getModel().showCurrency.removeObserver(showCurrencyObserver);
this.item.stopObservingComment(commentObserver);
this.item.getModel().showComments.removeObserver(showCommentsObserver);
+ this.item.stopObservingAmountValidity(amountValidityObserver);
this.item = null;
}
item.observeComment(activity, commentObserver);
item.getModel()
.observeAccountCount(activity, accountCountObserver);
+ item.observeAmountValidity(activity, amountValidityObserver);
break;
}
}
itemsWithAccountForCurrency.add(currName, item);
}
- if (acc.isAmountSet()) {
+ if (!acc.isAmountValid()) {
+ Logger.debug("submittable",
+ String.format("Not submittable: row %d has an invalid amount", i + 1));
+ submittable = false;
+ }
+ else if (acc.isAmountSet()) {
itemsWithAmountForCurrency.add(currName, item);
balance.add(currName, acc.getAmount());
}
private FocusedElement focusedElement = FocusedElement.Account;
private MutableLiveData<String> comment = new MutableLiveData<>(null);
private MutableLiveData<Currency> currency = new MutableLiveData<>(null);
+ private MutableLiveData<Boolean> amountValid = new MutableLiveData<>(true);
private boolean amountHintIsSet = false;
Item(NewTransactionModel model) {
this.model = model;
boolean isAmountHintSet() {
return amountHintIsSet;
}
+ void validateAmount() {
+ amountValid.setValue(true);
+ }
+ void invalidateAmount() {
+ amountValid.setValue(false);
+ }
+ void observeAmountValidity(NewTransactionActivity activity, Observer<Boolean> observer) {
+ amountValid.observe(activity, observer);
+ }
+ void stopObservingAmountValidity(Observer<Boolean> observer) {
+ amountValid.removeObserver(observer);
+ }
}
}
--- /dev/null
+<!--
+ ~ Copyright Google Inc.
+ ~
+ ~ Licensed under the Apache License, version 2.0 ("the License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the license at:
+ ~
+ ~ https://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distribution under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ Modified/adapted by Damyan Ivanov for MoLe
+ -->
+
+<vector android:autoMirrored="true" android:height="24dp"
+ android:tint="?colorAccent" android:viewportHeight="24.0"
+ android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF000000" android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+</vector>
android:hint="@string/zero_amount"
android:imeOptions="actionNext"
android:inputType="numberSigned|numberDecimal|number"
- android:minWidth="80sp"
+ android:minEms="4"
android:selectAllOnFocus="true"
android:textAlignment="viewEnd"
app:layout_constraintBottom_toBottomOf="parent"