Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANR when Edit Account #45

Merged
merged 2 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ public List<String> getDescendantAccountUIDs(String accountUID, String where, St
}

/**
* Returns a cursor to the dataset containing sub-accounts of the account with record ID <code>accoundId</code>
* Returns a cursor to the dataset containing sub-accounts of the account with record ID <code>accountUID</code>
*
* @param accountUID GUID of the parent account
* @return {@link Cursor} to the sub accounts data set
Expand Down Expand Up @@ -1039,7 +1039,7 @@ public String getOrCreateGnuCashRootAccountUID() {
}

/**
* Returns the number of accounts for which the account with ID <code>accoundId</code> is a first level parent
* Returns the number of accounts for which the account with ID <code>accountUID</code> is a first level parent
*
* @param accountUID String Unique ID (GUID) of the account
* @return Number of sub accounts
Expand Down Expand Up @@ -1356,4 +1356,23 @@ public int getTransactionMaxSplitNum(@NonNull String accountUID) {
cursor.close();
}
}

public Account getSimpleRecord(@NonNull String uid) {
Log.v(LOG_TAG, "Fetching simple record with GUID " + uid);

Cursor cursor = fetchRecord(uid);
try {
if (cursor.moveToFirst()) {
return buildSimpleAccountInstance(cursor);
} else {
throw new IllegalArgumentException(LOG_TAG + ": Record with " + uid + " does not exist");
}
} finally {
cursor.close();
}
}

public long getTransactionCount(@NonNull String uid) {
return mTransactionsAdapter.getTransactionsCountForAccount(uid);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ public enum UpdateMethod {
insert, update, replace
}

;

/**
* Opens the database adapter with an existing database
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public long bulkAddRecords(@NonNull List<Transaction> transactionList, UpdateMet
}

/**
* Returns a cursor to a set of all transactions which have a split belonging to the accound with unique ID
* Returns a cursor to a set of all transactions which have a split belonging to the account with unique ID
* <code>accountUID</code>.
*
* @param accountUID UID of the account whose transactions are to be retrieved
Expand Down Expand Up @@ -382,15 +382,10 @@ public Cursor fetchTransactionsWithSplitsWithTransactionAccount(String[] columns
* @return Number of transactions
*/
public long getRecordsCount() {
String queryCount = "SELECT COUNT(*) FROM " + TransactionEntry.TABLE_NAME +
" WHERE " + TransactionEntry.COLUMN_TEMPLATE + " =0";
Cursor cursor = mDb.rawQuery(queryCount, null);
try {
cursor.moveToFirst();
return cursor.getLong(0);
} finally {
cursor.close();
}
String sql = "SELECT COUNT(*) FROM " + TransactionEntry.TABLE_NAME +
" WHERE " + TransactionEntry.COLUMN_TEMPLATE + " =0";
SQLiteStatement statement = mDb.compileStatement(sql);
return statement.simpleQueryForLong();
}

/**
Expand All @@ -412,11 +407,13 @@ public long getRecordsCount(@Nullable String where, @Nullable String[] whereArgs
null,
null);
try {
cursor.moveToFirst();
return cursor.getLong(0);
if (cursor != null && cursor.moveToFirst()) {
return cursor.getLong(0);
}
} finally {
cursor.close();
}
return 0L;
}

/**
Expand Down Expand Up @@ -694,4 +691,26 @@ private long getTimestamp(String mod, AccountType type, String currencyCode) {
return timestamp;
}

public long getTransactionsCountForAccount(String accountUID) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(
TransactionEntry.TABLE_NAME + " t "
+ " INNER JOIN " + SplitEntry.TABLE_NAME + " s ON "
+ "t." + TransactionEntry.COLUMN_UID + " = "
+ "s." + SplitEntry.COLUMN_TRANSACTION_UID
);
String[] projectionIn = new String[]{"COUNT(*)"};
String selection = "s." + SplitEntry.COLUMN_ACCOUNT_UID + " = ?";
String[] selectionArgs = new String[]{accountUID};

Cursor cursor = queryBuilder.query(mDb, projectionIn, selection, selectionArgs, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
return cursor.getLong(0);
}
} finally {
cursor.close();
}
return 0L;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.cursoradapter.widget.SimpleCursorAdapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
Expand Down Expand Up @@ -76,6 +76,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
Expand Down Expand Up @@ -283,7 +284,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {

@Override
public void afterTextChanged(Editable s) {
if (s.toString().length() > 0) {
if (!TextUtils.isEmpty(s)) {
mTextInputLayout.setErrorEnabled(false);
}
}
Expand All @@ -303,7 +304,6 @@ public void onNothingSelected(AdapterView<?> adapterView) {
}
});


mParentAccountSpinner.setEnabled(false);

mParentCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
Expand Down Expand Up @@ -351,7 +351,7 @@ public void onActivityCreated(Bundle savedInstanceState) {

ActionBar supportActionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (mAccountUID != null) {
mAccount = mAccountsDbAdapter.getRecord(mAccountUID);
mAccount = mAccountsDbAdapter.getSimpleRecord(mAccountUID);
supportActionBar.setTitle(R.string.title_edit_account);
} else {
supportActionBar.setTitle(R.string.title_create_account);
Expand Down Expand Up @@ -540,12 +540,12 @@ private void setDefaultTransferAccountSelection(long defaultTransferAccountId, b
*/
private int[] getAccountColorOptions() {
Resources res = getResources();
int colorDefault = ResourcesCompat.getColor(res, R.color.title_green, null);
TypedArray colorTypedArray = res.obtainTypedArray(R.array.account_colors);
int[] colorOptions = new int[colorTypedArray.length()];
for (int i = 0; i < colorTypedArray.length(); i++) {
int color = colorTypedArray.getColor(i, ContextCompat.getColor(getContext(),
R.color.title_green));
colorOptions[i] = color;
int colorLength = colorTypedArray.length();
int[] colorOptions = new int[colorLength];
for (int i = 0; i < colorLength; i++) {
colorOptions[i] = colorTypedArray.getColor(i, colorDefault);
}
colorTypedArray.recycle();
return colorOptions;
Expand Down Expand Up @@ -763,18 +763,18 @@ private void saveAccount() {
// accounts to update, in case we're updating full names of a sub account tree
ArrayList<Account> accountsToUpdate = new ArrayList<>();
boolean nameChanged = false;
String newName = getEnteredName();
if (mAccount == null) {
String name = getEnteredName();
if (name.length() == 0) {
if (TextUtils.isEmpty(newName)) {
mTextInputLayout.setErrorEnabled(true);
mTextInputLayout.setError(getString(R.string.toast_no_account_name_entered));
return;
}
mAccount = new Account(getEnteredName());
mAccount = new Account(newName);
mAccountsDbAdapter.addRecord(mAccount, DatabaseAdapter.UpdateMethod.insert); //new account, insert it
} else {
nameChanged = !mAccount.getName().equals(getEnteredName());
mAccount.setName(getEnteredName());
nameChanged = !mAccount.getName().equals(newName);
mAccount.setName(newName);
}

long commodityId = mCurrencySpinner.getSelectedItemId();
Expand Down Expand Up @@ -823,15 +823,15 @@ private void saveAccount() {
}
mAccount.setFullName(newAccountFullName);
if (mDescendantAccountUIDs != null) {
// modifying existing account, e.t. name changed and/or parent changed
// modifying existing account, e.g. name changed and/or parent changed
if ((nameChanged || parentAccountId != newParentAccountId) && mDescendantAccountUIDs.size() > 0) {
// parent change, update all full names of descent accounts
accountsToUpdate.addAll(mAccountsDbAdapter.getSimpleAccountList(
DatabaseSchema.AccountEntry.COLUMN_UID + " IN ('" +
TextUtils.join("','", mDescendantAccountUIDs) + "')", null, null
));
}
HashMap<String, Account> mapAccount = new HashMap<>();
Map<String, Account> mapAccount = new HashMap<>();
for (Account acct : accountsToUpdate) mapAccount.put(acct.getUID(), acct);
for (String uid : mDescendantAccountUIDs) {
// mAccountsDbAdapter.getDescendantAccountUIDs() will ensure a parent-child order
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ public void onClick(View v) {
Intent addAccountIntent = new Intent(AccountsActivity.this, FormActivity.class);
addAccountIntent.setAction(Intent.ACTION_INSERT_OR_EDIT);
addAccountIntent.putExtra(UxArgument.FORM_TYPE, FormActivity.FormType.ACCOUNT.name());
startActivityForResult(addAccountIntent, AccountsActivity.REQUEST_EDIT_ACCOUNT);
startActivity(addAccountIntent);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,35 +240,32 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}

/**
* Delete the account with record ID <code>rowId</code>
* Delete the account with UID.
* It shows the delete confirmation dialog if the account has transactions,
* else deletes the account immediately
*
* @param rowId The record ID of the account
* @param accountUID The UID of the account
*/
public void tryDeleteAccount(long rowId) {
Account acc = mAccountsDbAdapter.getRecord(rowId);
if (acc.getTransactionCount() > 0 || mAccountsDbAdapter.getSubAccountCount(acc.getUID()) > 0) {
showConfirmationDialog(rowId);
private void tryDeleteAccount(String accountUID) {
if (mAccountsDbAdapter.getTransactionCount(accountUID) > 0 || mAccountsDbAdapter.getSubAccountCount(accountUID) > 0) {
showConfirmationDialog(accountUID);
} else {
BackupManager.backupActiveBook();
// Avoid calling AccountsDbAdapter.deleteRecord(long). See #654
String uid = mAccountsDbAdapter.getUID(rowId);
mAccountsDbAdapter.deleteRecord(uid);
mAccountsDbAdapter.deleteRecord(accountUID);
refresh();
}
}

/**
* Shows the delete confirmation dialog
*
* @param id Record ID of account to be deleted after confirmation
* @param accountUID Unique ID of account to be deleted after confirmation
*/
public void showConfirmationDialog(long id) {
private void showConfirmationDialog(String accountUID) {
DeleteAccountDialogFragment alertFragment =
DeleteAccountDialogFragment.newInstance(mAccountsDbAdapter.getUID(id));
alertFragment.setTargetFragment(this, 0);
alertFragment.show(getActivity().getSupportFragmentManager(), "delete_confirmation_dialog");
DeleteAccountDialogFragment.newInstance(accountUID);
alertFragment.show(getChildFragmentManager(), "delete_confirmation_dialog");
}

@Override
Expand Down Expand Up @@ -331,16 +328,16 @@ public void onDestroy() {

/**
* Opens a new activity for creating or editing an account.
* If the <code>accountId</code> &lt; 1, then create else edit the account.
* If the <code>accountUID</code> is empty, then create else edit the account.
*
* @param accountId Long record ID of account to be edited. Pass 0 to create a new account.
* @param accountUID Unique ID of account to be edited. Pass 0 to create a new account.
*/
public void openCreateOrEditActivity(long accountId) {
public void openCreateOrEditActivity(String accountUID) {
Intent editAccountIntent = new Intent(AccountsListFragment.this.getActivity(), FormActivity.class);
editAccountIntent.setAction(Intent.ACTION_INSERT_OR_EDIT);
editAccountIntent.putExtra(UxArgument.SELECTED_ACCOUNT_UID, mAccountsDbAdapter.getUID(accountId));
editAccountIntent.putExtra(UxArgument.SELECTED_ACCOUNT_UID, accountUID);
editAccountIntent.putExtra(UxArgument.FORM_TYPE, FormActivity.FormType.ACCOUNT.name());
startActivityForResult(editAccountIntent, AccountsActivity.REQUEST_EDIT_ACCOUNT);
startActivity(editAccountIntent);
}

@Override
Expand Down Expand Up @@ -493,7 +490,7 @@ public AccountViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public void onBindViewHolderCursor(final AccountViewHolder holder, final Cursor cursor) {
final String accountUID = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_UID));
mAccountsDbAdapter = AccountsDbAdapter.getInstance();
holder.accoundId = mAccountsDbAdapter.getID(accountUID);
holder.accountUID = accountUID;

holder.accountName.setText(cursor.getString(cursor.getColumnIndexOrThrow(DatabaseSchema.AccountEntry.COLUMN_NAME)));
int subAccountCount = mAccountsDbAdapter.getSubAccountCount(accountUID);
Expand Down Expand Up @@ -593,7 +590,8 @@ class AccountViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnM
View colorStripView;
@BindView(R.id.budget_indicator)
ProgressBar budgetIndicator;
long accoundId;

String accountUID;

public AccountViewHolder(View itemView) {
super(itemView);
Expand All @@ -617,11 +615,11 @@ public void onClick(View v) {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.context_menu_edit_accounts:
openCreateOrEditActivity(accoundId);
openCreateOrEditActivity(accountUID);
return true;

case R.id.context_menu_delete:
tryDeleteAccount(accoundId);
tryDeleteAccount(accountUID);
return true;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,11 @@ public void refresh(String uid) {
* @param budgetUID GUID of budget
*/
public void onClickBudget(String budgetUID) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, BudgetDetailFragment.newInstance(budgetUID));
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
FragmentManager fragmentManager = getParentFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, BudgetDetailFragment.newInstance(budgetUID))
.addToBackStack(null)
.commit();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ protected void onCreate(Bundle savedInstanceState) {

if (savedInstanceState == null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, new BudgetListFragment());
fragmentTransaction.commit();
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, new BudgetListFragment())
.commit();
}
}

Expand Down
Loading
Loading