// state of the database
db.setTransactionSuccessful();
db.endTransaction();
- Data.accounts.setList(accountList);
+ profile.setAccounts(accountList);
db.beginTransaction();
continue;
}
profile.deleteNotPresentAccounts(db);
throwIfCancelled();
db.setTransactionSuccessful();
- listFilledOK = true;
}
finally {
db.endTransaction();
}
}
- // should not be set in the DB transaction, because of a possible deadlock
- // with the main and DbOpQueueRunner threads
- if (listFilledOK)
- Data.accounts.setList(accountList);
+
+ profile.setAccounts(accountList);
return true;
}
+++ /dev/null
-/*
- * Copyright © 2019 Damyan Ivanov.
- * This file is part of MoLe.
- * MoLe is free software: you can distribute it and/or modify it
- * under the term of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion), any later version.
- *
- * MoLe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License terms for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.ktnx.mobileledger.async;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.AsyncTask;
-
-import net.ktnx.mobileledger.App;
-import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.LedgerAccount;
-import net.ktnx.mobileledger.model.MobileLedgerProfile;
-
-import java.util.ArrayList;
-
-import static net.ktnx.mobileledger.utils.Logger.debug;
-
-public class UpdateAccountsTask extends AsyncTask<Void, Void, ArrayList<LedgerAccount>> {
- protected ArrayList<LedgerAccount> doInBackground(Void... params) {
- Data.backgroundTaskStarted();
- try {
- MobileLedgerProfile profile = Data.profile.getValue();
- if (profile == null) throw new AssertionError();
- String profileUUID = profile.getUuid();
- ArrayList<LedgerAccount> newList = new ArrayList<>();
-
- String sql = "SELECT a.name from accounts a WHERE a.profile = ?";
- sql += " ORDER BY a.name";
-
- SQLiteDatabase db = App.getDatabase();
- try (Cursor cursor = db.rawQuery(sql, new String[]{profileUUID})) {
- while (cursor.moveToNext()) {
- final String accName = cursor.getString(0);
-// debug("accounts",
-// String.format("Read account '%s' from DB [%s]", accName, profileUUID));
- LedgerAccount acc = profile.loadAccount(db, accName);
- if (acc.isVisible(newList)) newList.add(acc);
- }
- }
-
- return newList;
- }
- finally {
- debug("UAT", "decrementing background task count");
- Data.backgroundTaskFinished();
- }
- }
-}
new MutableLiveData<>(null);
public static final MutableLiveData<SimpleDate> latestTransactionDate =
new MutableLiveData<>(null);
- public static final ObservableList<LedgerAccount> accounts =
- new ObservableList<>(new ArrayList<>());
public static final MutableLiveData<Boolean> backgroundTasksRunning =
new MutableLiveData<>(false);
public static final MutableLiveData<Date> lastUpdateDate = new MutableLiveData<>();
name.equals(((LedgerAccount) obj).getName());
}
// an account is visible if:
- // - it is starred (not hidden by a star)
- // - and it has an expanded parent or is a top account
- public boolean isVisible() {
- if (level == 0) return true;
-
- return isVisible(Data.accounts);
- }
+ // - it has an expanded parent or is a top account
public boolean isVisible(List<LedgerAccount> list) {
for (LedgerAccount acc : list) {
if (acc.isParentOf(this)) {
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import net.ktnx.mobileledger.App;
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.async.DbOpQueue;
import net.ktnx.mobileledger.async.SendTransactionTask;
+import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.MLDB;
import net.ktnx.mobileledger.utils.Misc;
private SendTransactionTask.API apiVersion = SendTransactionTask.API.auto;
private Calendar firstTransactionDate;
private Calendar lastTransactionDate;
+ private MutableLiveData<ArrayList<LedgerAccount>> accounts =
+ new MutableLiveData<>(new ArrayList<>());
+ private AccountListLoader loader = null;
public MobileLedgerProfile() {
this.uuid = String.valueOf(UUID.randomUUID());
}
db.endTransaction();
}
}
+ public LiveData<ArrayList<LedgerAccount>> getAccounts() {
+ return accounts;
+ }
+ synchronized public void scheduleAccountListReload() {
+ Logger.debug("async-acc", "scheduleAccountListReload() enter");
+ if ((loader != null) && loader.isAlive()) {
+ Logger.debug("async-acc", "returning early - loader already active");
+ return;
+ }
+
+ Logger.debug("async-acc", "Starting AccountListLoader");
+ loader = new AccountListLoader(this);
+ loader.start();
+ }
+ synchronized public void abortAccountListReload() {
+ if (loader == null)
+ return;
+ loader.interrupt();
+ loader = null;
+ }
public boolean getShowCommentsByDefault() {
return showCommentsByDefault;
}
}
@Nullable
public LedgerAccount tryLoadAccount(SQLiteDatabase db, String accName) {
- try (Cursor cursor = db.rawQuery("SELECT a.expanded, (select 1 from accounts a2 " +
+ try (Cursor cursor = db.rawQuery("SELECT a.expanded, a.amounts_expanded, (select 1 from accounts a2 " +
"where a2.profile = a.profile and a2.name like a" +
".name||':%' limit 1) " +
"FROM accounts a WHERE a.profile = ? and a.name=?",
if (cursor.moveToFirst()) {
LedgerAccount acc = new LedgerAccount(this, accName);
acc.setExpanded(cursor.getInt(0) == 1);
- acc.setHasSubAccounts(cursor.getInt(1) == 1);
+ acc.setAmountsExpanded(cursor.getInt(1) == 1);
+ acc.setHasSubAccounts(cursor.getInt(2) == 1);
try (Cursor c2 = db.rawQuery(
"SELECT value, currency FROM account_values WHERE profile = ? " +
public Calendar getLastTransactionDate() {
return lastTransactionDate;
}
+ public void setAccounts(ArrayList<LedgerAccount> list) {
+ accounts.postValue(list);
+ }
public enum FutureDates {
None(0), OneWeek(7), TwoWeeks(14), OneMonth(30), TwoMonths(60), ThreeMonths(90),
SixMonths(180), OneYear(365), All(-1);
}
}
}
+
+ static class AccountListLoader extends Thread {
+ MobileLedgerProfile profile;
+ AccountListLoader(MobileLedgerProfile profile) {
+ this.profile = profile;
+ }
+ @Override
+ public void run() {
+ Logger.debug("async-acc", "AccountListLoader::run() entered");
+ String profileUUID = profile.getUuid();
+ ArrayList<LedgerAccount> newList = new ArrayList<>();
+
+ String sql = "SELECT a.name from accounts a WHERE a.profile = ?";
+ sql += " ORDER BY a.name";
+
+ SQLiteDatabase db = App.getDatabase();
+ try (Cursor cursor = db.rawQuery(sql, new String[]{profileUUID})) {
+ while (cursor.moveToNext()) {
+ if (isInterrupted())
+ return;
+
+ final String accName = cursor.getString(0);
+// debug("accounts",
+// String.format("Read account '%s' from DB [%s]", accName,
+// profileUUID));
+ LedgerAccount acc = profile.loadAccount(db, accName);
+ if (acc.isVisible(newList))
+ newList.add(acc);
+ }
+ }
+
+ if (isInterrupted())
+ return;
+
+ Logger.debug("async-acc", "AccountListLoader::run() posting new list");
+ profile.accounts.postValue(newList);
+ }
+ }
}
import android.content.Context;
import android.content.res.Resources;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.recyclerview.widget.AsyncListDiffer;
+import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.async.DbOpQueue;
import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.ui.activity.MainActivity;
-import net.ktnx.mobileledger.utils.LockHolder;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+import static net.ktnx.mobileledger.utils.Logger.debug;
public class AccountSummaryAdapter
extends RecyclerView.Adapter<AccountSummaryAdapter.LedgerRowHolder> {
public static final int AMOUNT_LIMIT = 3;
-
- AccountSummaryAdapter() { }
+ private MobileLedgerProfile profile;
+ private AsyncListDiffer<LedgerAccount> listDiffer;
+ AccountSummaryAdapter() {
+ listDiffer = new AsyncListDiffer<>(this, new DiffUtil.ItemCallback<LedgerAccount>() {
+ @Override
+ public boolean areItemsTheSame(@NotNull LedgerAccount oldItem,
+ @NotNull LedgerAccount newItem) {
+ return TextUtils.equals(oldItem.getName(), newItem.getName());
+ }
+ @Override
+ public boolean areContentsTheSame(@NotNull LedgerAccount oldItem,
+ @NotNull LedgerAccount newItem) {
+ return (oldItem.isExpanded() == newItem.isExpanded()) &&
+ (oldItem.amountsExpanded() == newItem.amountsExpanded());
+ }
+ });
+ }
public void onBindViewHolder(@NonNull LedgerRowHolder holder, int position) {
- try (LockHolder lh = Data.accounts.lockForReading()) {
- LedgerAccount acc = Data.accounts.get(position);
- Context ctx = holder.row.getContext();
- Resources rm = ctx.getResources();
-
- holder.row.setTag(acc);
- holder.row.setVisibility(View.VISIBLE);
- holder.tvAccountName.setText(acc.getShortName());
- ConstraintLayout.LayoutParams lp =
- (ConstraintLayout.LayoutParams) holder.tvAccountName.getLayoutParams();
- lp.setMarginStart(
- acc.getLevel() * rm.getDimensionPixelSize(R.dimen.thumb_row_height) / 3);
- holder.expanderContainer.setVisibility(
- acc.hasSubAccounts() ? View.VISIBLE : View.GONE);
- holder.expanderContainer.setRotation(acc.isExpanded() ? 0 : 180);
- int amounts = acc.getAmountCount();
- if ((amounts > AMOUNT_LIMIT) && !acc.amountsExpanded()) {
- holder.tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
- holder.accountExpanderContainer.setVisibility(View.VISIBLE);
- }
- else {
- holder.tvAccountAmounts.setText(acc.getAmountsString());
- holder.accountExpanderContainer.setVisibility(View.GONE);
- }
-
- holder.row.setTag(R.id.POS, position);
- }
+ holder.bindToAccount(listDiffer.getCurrentList().get(position));
}
@NonNull
@Override
public int getItemCount() {
- return Data.accounts.size();
+ return listDiffer.getCurrentList().size();
+ }
+ public void setAccounts(MobileLedgerProfile profile, ArrayList<LedgerAccount> newList) {
+ this.profile = profile;
+ listDiffer.submitList(newList);
}
- static class LedgerRowHolder extends RecyclerView.ViewHolder {
+ class LedgerRowHolder extends RecyclerView.ViewHolder {
TextView tvAccountName, tvAccountAmounts;
ConstraintLayout row;
View expanderContainer;
View accountExpanderContainer;
public LedgerRowHolder(@NonNull View itemView) {
super(itemView);
- this.row = itemView.findViewById(R.id.account_summary_row);
- this.tvAccountName = itemView.findViewById(R.id.account_row_acc_name);
- this.tvAccountAmounts = itemView.findViewById(R.id.account_row_acc_amounts);
- this.expanderContainer = itemView.findViewById(R.id.account_expander_container);
- this.expander = itemView.findViewById(R.id.account_expander);
- this.accountExpanderContainer =
+ row = itemView.findViewById(R.id.account_summary_row);
+ tvAccountName = itemView.findViewById(R.id.account_row_acc_name);
+ tvAccountAmounts = itemView.findViewById(R.id.account_row_acc_amounts);
+ expanderContainer = itemView.findViewById(R.id.account_expander_container);
+ expander = itemView.findViewById(R.id.account_expander);
+ accountExpanderContainer =
itemView.findViewById(R.id.account_row_amounts_expander_container);
itemView.setOnLongClickListener(this::onItemLongClick);
expanderContainer.setOnLongClickListener(this::onItemLongClick);
expander.setOnLongClickListener(this::onItemLongClick);
row.setOnLongClickListener(this::onItemLongClick);
+
+ tvAccountName.setOnClickListener(v -> toggleAccountExpanded());
+ expanderContainer.setOnClickListener(v -> toggleAccountExpanded());
+ expander.setOnClickListener(v -> toggleAccountExpanded());
+ tvAccountAmounts.setOnClickListener(v -> toggleAmountsExpanded());
+ }
+ private @NonNull
+ LedgerAccount getAccount() {
+ final ArrayList<LedgerAccount> accountList = profile.getAccounts()
+ .getValue();
+ if (accountList == null)
+ throw new IllegalStateException("No account list");
+
+ return accountList.get(getAdapterPosition());
+ }
+ private void toggleAccountExpanded() {
+ LedgerAccount acc = getAccount();
+ if (!acc.hasSubAccounts())
+ return;
+ debug("accounts", "Account expander clicked");
+
+ acc.toggleExpanded();
+ expanderContainer.animate()
+ .rotation(acc.isExpanded() ? 0 : 180);
+
+ MobileLedgerProfile profile = acc.getProfile();
+ if (profile == null)
+ return;
+
+ DbOpQueue.add("update accounts set expanded=? where name=? and profile=?",
+ new Object[]{acc.isExpanded(), acc.getName(), profile.getUuid()
+ }, profile::scheduleAccountListReload);
+
+ }
+ private void toggleAmountsExpanded() {
+ LedgerAccount acc = getAccount();
+ if (acc.getAmountCount() <= AMOUNT_LIMIT)
+ return;
+
+ acc.toggleAmountsExpanded();
+ if (acc.amountsExpanded()) {
+ tvAccountAmounts.setText(acc.getAmountsString());
+ accountExpanderContainer.setVisibility(View.GONE);
+ }
+ else {
+ tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
+ accountExpanderContainer.setVisibility(View.VISIBLE);
+ }
+
+ MobileLedgerProfile profile = acc.getProfile();
+ if (profile == null)
+ return;
+
+ DbOpQueue.add("update accounts set amounts_expanded=? where name=? and profile=?",
+ new Object[]{acc.amountsExpanded(), acc.getName(), profile.getUuid()
+ });
+
}
private boolean onItemLongClick(View v) {
MainActivity activity = (MainActivity) v.getContext();
String.format("Don't know how to handle long click on id %d", id));
return false;
}
- LedgerAccount acc = (LedgerAccount) row.getTag();
+ LedgerAccount acc = getAccount();
builder.setTitle(acc.getName());
builder.setItems(R.array.acc_ctx_menu, (dialog, which) -> {
switch (which) {
case 0:
// show transactions
- activity.showAccountTransactions(acc);
+ activity.showAccountTransactions(acc.getName());
break;
}
dialog.dismiss();
builder.show();
return true;
}
+ public void bindToAccount(LedgerAccount acc) {
+ Context ctx = row.getContext();
+ Resources rm = ctx.getResources();
+
+ row.setTag(acc);
+
+ tvAccountName.setText(acc.getShortName());
+
+ ConstraintLayout.LayoutParams lp =
+ (ConstraintLayout.LayoutParams) tvAccountName.getLayoutParams();
+ lp.setMarginStart(
+ acc.getLevel() * rm.getDimensionPixelSize(R.dimen.thumb_row_height) / 3);
+
+ if (acc.hasSubAccounts()) {
+ expanderContainer.setVisibility(View.VISIBLE);
+ expanderContainer.setRotation(acc.isExpanded() ? 0 : 180);
+ }
+ else {
+ expanderContainer.setVisibility(View.GONE);
+ }
+
+ int amounts = acc.getAmountCount();
+ if ((amounts > AMOUNT_LIMIT) && !acc.amountsExpanded()) {
+ tvAccountAmounts.setText(acc.getAmountsString(AMOUNT_LIMIT));
+ accountExpanderContainer.setVisibility(View.VISIBLE);
+ }
+ else {
+ tvAccountAmounts.setText(acc.getAmountsString());
+ accountExpanderContainer.setVisibility(View.GONE);
+ }
+ }
}
}
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.model.MobileLedgerProfile;
import net.ktnx.mobileledger.ui.MobileLedgerListFragment;
import net.ktnx.mobileledger.ui.activity.MainActivity;
import net.ktnx.mobileledger.utils.Colors;
+import net.ktnx.mobileledger.utils.Logger;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+
import static net.ktnx.mobileledger.utils.Logger.debug;
public class AccountSummaryFragment extends MobileLedgerListFragment {
Data.scheduleTransactionListRetrieval(mainActivity);
});
- Data.accounts.addObserver(
- (o, arg) -> mainActivity.runOnUiThread(() -> modelAdapter.notifyDataSetChanged()));
+ Data.profile.observe(getViewLifecycleOwner(), profile -> profile.getAccounts()
+ .observe(
+ getViewLifecycleOwner(),
+ (accounts) -> onAccountsChanged(
+ profile,
+ accounts)));
+ }
+ private void onAccountsChanged(MobileLedgerProfile profile, ArrayList<LedgerAccount> accounts) {
+ Logger.debug("async-acc", "fragment: got new account list");
+ modelAdapter.setAccounts(profile, accounts);
}
}
+++ /dev/null
-/*
- * Copyright © 2019 Damyan Ivanov.
- * This file is part of MoLe.
- * MoLe is free software: you can distribute it and/or modify it
- * under the term of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your opinion), any later version.
- *
- * MoLe is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License terms for details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package net.ktnx.mobileledger.ui.account_summary;
-
-import android.os.AsyncTask;
-
-import androidx.lifecycle.ViewModel;
-
-import net.ktnx.mobileledger.async.UpdateAccountsTask;
-import net.ktnx.mobileledger.model.Data;
-import net.ktnx.mobileledger.model.LedgerAccount;
-
-import java.util.ArrayList;
-
-import static net.ktnx.mobileledger.utils.Logger.debug;
-
-public class AccountSummaryViewModel extends ViewModel {
- static public void scheduleAccountListReload() {
- if (Data.profile.getValue() == null) return;
-
- UAT task = new UAT();
- task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- }
-
- private static class UAT extends UpdateAccountsTask {
- @Override
- protected void onPostExecute(ArrayList<LedgerAccount> list) {
- super.onPostExecute(list);
- if (list != null) {
- debug("acc", "setting updated account list");
- Data.accounts.setList(list);
- }
- }
- }
-
-}
-
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import com.google.android.material.snackbar.Snackbar;
import net.ktnx.mobileledger.R;
-import net.ktnx.mobileledger.async.DbOpQueue;
import net.ktnx.mobileledger.async.RefreshDescriptionsTask;
import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerAccount;
import net.ktnx.mobileledger.model.MobileLedgerProfile;
-import net.ktnx.mobileledger.ui.account_summary.AccountSummaryAdapter;
import net.ktnx.mobileledger.ui.account_summary.AccountSummaryFragment;
-import net.ktnx.mobileledger.ui.account_summary.AccountSummaryViewModel;
import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment;
import net.ktnx.mobileledger.ui.profiles.ProfilesRecyclerViewAdapter;
import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment;
import net.ktnx.mobileledger.ui.transaction_list.TransactionListViewModel;
import net.ktnx.mobileledger.utils.Colors;
import net.ktnx.mobileledger.utils.GetOptCallback;
-import net.ktnx.mobileledger.utils.LockHolder;
import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.MLDB;
else
setTitle(R.string.app_name);
+ if (this.profile != null)
+ this.profile.getAccounts()
+ .removeObservers(this);
+
this.profile = profile;
int newProfileTheme = haveProfile ? profile.getThemeHue() : -1;
debug("transactions", "requesting list reload");
TransactionListViewModel.scheduleTransactionListReload();
- Data.accounts.clear();
- AccountSummaryViewModel.scheduleAccountListReload();
-
if (haveProfile) {
+ profile.scheduleAccountListReload();
+
if (profile.isPostingPermitted()) {
mToolbar.setSubtitle(null);
fab.show();
showTransactionsFragment((String) null);
}
- private void showTransactionsFragment(String accName) {
+ public void showTransactionsFragment(String accName) {
Data.accountFilter.setValue(accName);
mViewPager.setCurrentItem(1, true);
}
- private void showTransactionsFragment(LedgerAccount account) {
- showTransactionsFragment((account == null) ? null : account.getName());
- }
- public void showAccountTransactions(LedgerAccount account) {
+ public void showAccountTransactions(String accountName) {
mBackMeansToAccountList = true;
- showTransactionsFragment(account);
+ showTransactionsFragment(accountName);
}
@Override
public void onBackPressed() {
case R.id.account_row_acc_name:
case R.id.account_expander:
case R.id.account_expander_container:
- debug("accounts", "Account expander clicked");
- if (!acc.hasSubAccounts())
- return;
-
- boolean wasExpanded = acc.isExpanded();
-
- View arrow = row.findViewById(R.id.account_expander_container);
-
- arrow.clearAnimation();
- ViewPropertyAnimator animator = arrow.animate();
-
- acc.toggleExpanded();
- DbOpQueue.add("update accounts set expanded=? where name=? and profile=?",
- new Object[]{acc.isExpanded(), acc.getName(), profile.getUuid()
- });
-
- if (wasExpanded) {
- debug("accounts", String.format("Collapsing account '%s'", acc.getName()));
- arrow.setRotation(0);
- animator.rotationBy(180);
-
- // removing all child accounts from the view
- int start = -1, count = 0;
- try (LockHolder ignored = Data.accounts.lockForWriting()) {
- for (int i = 0; i < Data.accounts.size(); i++) {
- if (acc.isParentOf(Data.accounts.get(i))) {
-// debug("accounts", String.format("Found a child '%s' at position
-// %d",
-// Data.accounts.get(i).getName(), i));
- if (start == -1) {
- start = i;
- }
- count++;
- }
- else {
- if (start != -1) {
-// debug("accounts",
-// String.format("Found a non-child '%s' at position %d",
-// Data.accounts.get(i).getName(), i));
- break;
- }
- }
- }
-
- if (start != -1) {
- for (int j = 0; j < count; j++) {
-// debug("accounts", String.format("Removing item %d: %s", start + j,
-// Data.accounts.get(start).getName()));
- Data.accounts.removeQuietly(start);
- }
-
- mAccountSummaryFragment.modelAdapter.notifyItemRangeRemoved(start,
- count);
- }
- }
- }
- else {
- debug("accounts", String.format("Expanding account '%s'", acc.getName()));
- arrow.setRotation(180);
- animator.rotationBy(-180);
- List<LedgerAccount> children = profile.loadVisibleChildAccountsOf(acc);
- try (LockHolder ignored = Data.accounts.lockForWriting()) {
- int parentPos = Data.accounts.indexOf(acc);
- if (parentPos != -1) {
- // may have disappeared in a concurrent refresh operation
- Data.accounts.addAllQuietly(parentPos + 1, children);
- mAccountSummaryFragment.modelAdapter.notifyItemRangeInserted(
- parentPos + 1, children.size());
- }
- }
- }
break;
case R.id.account_row_acc_amounts:
- if (acc.getAmountCount() > AccountSummaryAdapter.AMOUNT_LIMIT) {
- acc.toggleAmountsExpanded();
- DbOpQueue.add(
- "update accounts set amounts_expanded=? where name=? and profile=?",
- new Object[]{acc.amountsExpanded(), acc.getName(), profile.getUuid()
- });
- Data.accounts.triggerItemChangedNotification(acc);
- }
break;
}
}
<resources>
<item name="VH" type="id" />
- <item name="POS" type="id" />
<item name="SELECTING" type="id" />
</resources>
\ No newline at end of file