async account list
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Sat, 5 Jan 2019 08:26:15 +0000 (08:26 +0000)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Sat, 5 Jan 2019 08:26:15 +0000 (08:26 +0000)
app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTask.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTaskParams.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java [new file with mode: 0644]
app/src/main/java/net/ktnx/mobileledger/model/Data.java
app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java
app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryViewModel.java

diff --git a/app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTask.java
new file mode 100644 (file)
index 0000000..7fb96b9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ * This file is part of Mobile-Ledger.
+ * Mobile-Ledger 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.
+ *
+ * Mobile-Ledger 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 Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.async;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.utils.MLDB;
+
+import java.util.ArrayList;
+
+public class CommitAccountsTask
+        extends AsyncTask<CommitAccountsTaskParams, Void, ArrayList<LedgerAccount>> {
+    protected ArrayList<LedgerAccount> doInBackground(CommitAccountsTaskParams... params) {
+        Data.backgroundTaskCount.incrementAndGet();
+        ArrayList<LedgerAccount> newList = new ArrayList<>();
+        try {
+
+            SQLiteDatabase db = MLDB.getWritableDatabase();
+            db.beginTransaction();
+            try {
+                for (LedgerAccount acc : params[0].accountList) {
+                    Log.d("db", String.format("Setting %s to %s", acc.getName(),
+                            acc.isHidden() ? "hidden" : "starred"));
+                    db.execSQL("UPDATE accounts SET hidden=? WHERE name=?",
+                            new Object[]{acc.isHiddenToBe() ? 1 : 0, acc.getName()});
+
+                    acc.setHidden(acc.isHiddenToBe());
+                    if (!params[0].showOnlyStarred || !acc.isHidden()) newList.add(acc);
+                }
+                db.setTransactionSuccessful();
+            }
+            finally {
+                db.endTransaction();
+            }
+        }
+        finally {
+            Data.backgroundTaskCount.decrementAndGet();
+        }
+
+        return newList;
+    }
+}
diff --git a/app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTaskParams.java b/app/src/main/java/net/ktnx/mobileledger/async/CommitAccountsTaskParams.java
new file mode 100644 (file)
index 0000000..c3de7f2
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ * This file is part of Mobile-Ledger.
+ * Mobile-Ledger 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.
+ *
+ * Mobile-Ledger 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 Mobile-Ledger. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.async;
+
+import net.ktnx.mobileledger.model.LedgerAccount;
+
+import java.util.List;
+
+public class CommitAccountsTaskParams {
+    List<LedgerAccount> accountList;
+    boolean showOnlyStarred;
+    public CommitAccountsTaskParams(List<LedgerAccount> accountList, boolean showOnlyStarred) {
+        this.accountList = accountList;
+        this.showOnlyStarred = showOnlyStarred;
+    }
+}
diff --git a/app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/UpdateAccountsTask.java
new file mode 100644 (file)
index 0000000..458c1af
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2019 Damyan Ivanov.
+ * This file is part of Mobile-Ledger.
+ * Mobile-Ledger 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.
+ *
+ * Mobile-Ledger 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 Mobile-Ledger. 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 android.util.Log;
+
+import net.ktnx.mobileledger.model.Data;
+import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.utils.MLDB;
+
+import java.util.ArrayList;
+
+public class UpdateAccountsTask extends AsyncTask<Boolean, Void, ArrayList<LedgerAccount>> {
+    protected ArrayList<LedgerAccount> doInBackground(Boolean[] onlyStarred) {
+        Data.backgroundTaskCount.incrementAndGet();
+        try {
+            ArrayList<LedgerAccount> newList = new ArrayList<>();
+
+            String sql = "SELECT name, hidden FROM accounts";
+            if (onlyStarred[0]) sql += " WHERE hidden = 0";
+            sql += " ORDER BY name";
+
+            SQLiteDatabase db = MLDB.getReadableDatabase();
+            try (Cursor cursor = db.rawQuery(sql, null)) {
+                while (cursor.moveToNext()) {
+                    LedgerAccount acc = new LedgerAccount(cursor.getString(0));
+                    acc.setHidden(cursor.getInt(1) == 1);
+                    try (Cursor c2 = db.rawQuery(
+                            "SELECT value, currency FROM account_values " + "WHERE account = ?",
+                            new String[]{acc.getName()}))
+                    {
+                        while (c2.moveToNext()) {
+                            acc.addAmount(c2.getFloat(0), c2.getString(1));
+                        }
+                    }
+                    newList.add(acc);
+                }
+            }
+
+            Data.accounts.set(newList);
+
+            return newList;
+        }
+        finally {
+            Log.d("UAT", "decrementing background task count");
+            Data.backgroundTaskCount.decrementAndGet();
+        }
+    }
+}
index 89d29c4dc0b3894d67aec66a1b9b3fefaf3053dc..e492e1425b91c3b4efb89831eee82680e981aa8b 100644 (file)
 
 package net.ktnx.mobileledger.model;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public final class Data {
     public static TransactionList transactions = new TransactionList();
-    public static ObservableValue<List<LedgerAccount>> accounts = new ObservableValue<>();
+    public static ObservableValue<ArrayList<LedgerAccount>> accounts =
+            new ObservableValue<>(new ArrayList<LedgerAccount>());
     public static ObservableValue<List<String>> descriptions = new ObservableValue<>();
     public static ObservableAtomicInteger backgroundTaskCount = new ObservableAtomicInteger(0);
 }
index 99ce8bded745ef230239f09ff4ae358b95e2ab23..9214e79445d1ff0d9732b95a4a2a801da21eed8c 100644 (file)
@@ -42,7 +42,6 @@ import net.ktnx.mobileledger.model.LedgerAccount;
 import net.ktnx.mobileledger.ui.MobileLedgerListFragment;
 import net.ktnx.mobileledger.ui.RecyclerItemListener;
 import net.ktnx.mobileledger.ui.activity.MainActivity;
-import net.ktnx.mobileledger.utils.MLDB;
 
 import java.lang.ref.WeakReference;
 import java.util.Date;
@@ -112,8 +111,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment {
         mActivity.markDrawerItemCurrent(R.id.nav_account_summary);
 
         model = ViewModelProviders.of(this).get(AccountSummaryViewModel.class);
-        List<LedgerAccount> accounts = model.getAccounts(this.getContext());
-        modelAdapter = new AccountSummaryAdapter(accounts);
+        modelAdapter = new AccountSummaryAdapter();
 
         RecyclerView root = mActivity.findViewById(R.id.account_root);
         root.setAdapter(modelAdapter);
@@ -133,7 +131,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment {
                             modelAdapter.selectItem(position);
                         }
                         else {
-                            List<LedgerAccount> accounts = model.getAccounts(mActivity);
+                            List<LedgerAccount> accounts = Data.accounts.get();
                             if (accounts != null) {
                                 LedgerAccount account = accounts.get(position);
 
@@ -210,8 +208,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment {
     private void update_account_table() {
         if (this.getContext() == null) return;
 
-        model.reloadAccounts(this.getContext());
-        modelAdapter.notifyDataSetChanged();
+        model.scheduleAccountListReload(this.getContext());
     }
     public void onShowOnlyStarredClicked(MenuItem mi) {
         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mActivity);
@@ -240,7 +237,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment {
         stopSelection();
     }
     public void onConfirmAccSelection(MenuItem item) {
-        model.commitSelections(mActivity);
+        AccountSummaryViewModel.commitSelections(mActivity);
         stopSelection();
     }
     @Override
index 26d97c5358e000d089be71fe9678bf3aa02fd429..1afced05433820f0e565cabad3677ee522b97980 100644 (file)
 
 package net.ktnx.mobileledger.ui.account_summary;
 
-import android.app.Application;
-import android.arch.lifecycle.AndroidViewModel;
+import android.arch.lifecycle.ViewModel;
 import android.content.Context;
 import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Typeface;
 import android.os.Build;
 import android.preference.PreferenceManager;
@@ -37,97 +34,67 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import net.ktnx.mobileledger.R;
+import net.ktnx.mobileledger.async.CommitAccountsTask;
+import net.ktnx.mobileledger.async.CommitAccountsTaskParams;
+import net.ktnx.mobileledger.async.UpdateAccountsTask;
+import net.ktnx.mobileledger.model.Data;
 import net.ktnx.mobileledger.model.LedgerAccount;
-import net.ktnx.mobileledger.utils.MLDB;
 
 import java.util.ArrayList;
-import java.util.List;
 
 import static net.ktnx.mobileledger.ui.activity.SettingsActivity.PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS;
 
-class AccountSummaryViewModel extends AndroidViewModel {
-    private List<LedgerAccount> accounts;
+class AccountSummaryViewModel extends ViewModel {
+    void scheduleAccountListReload(Context context) {
+        boolean showingOnlyStarred = PreferenceManager.getDefaultSharedPreferences(context)
+                .getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false);
 
-    public AccountSummaryViewModel(@NonNull Application application) {
-        super(application);
-    }
-
-    List<LedgerAccount> getAccounts(Context context) {
-        if (accounts == null) {
-            accounts = new ArrayList<>();
-            reloadAccounts(context);
-        }
+        UAT task = new UAT();
+        task.execute(showingOnlyStarred);
 
-        return accounts;
     }
-
-    void reloadAccounts(Context context) {
-        accounts.clear();
-        boolean showingOnlyStarred =
-                PreferenceManager.getDefaultSharedPreferences(getApplication())
-                        .getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false);
-        String sql = "SELECT name, hidden FROM accounts";
-        if (showingOnlyStarred) sql += " WHERE hidden = 0";
-        sql += " ORDER BY name";
-
-        try (SQLiteDatabase db = MLDB.getReadableDatabase()) {
-            try (Cursor cursor = db
-                    .rawQuery(sql,null))
-            {
-                while (cursor.moveToNext()) {
-                    LedgerAccount acc = new LedgerAccount(cursor.getString(0));
-                    acc.setHidden(cursor.getInt(1) == 1);
-                    try (Cursor c2 = db.rawQuery(
-                            "SELECT value, currency FROM account_values " + "WHERE account = ?",
-                            new String[]{acc.getName()}))
-                    {
-                        while (c2.moveToNext()) {
-                            acc.addAmount(c2.getFloat(0), c2.getString(1));
-                        }
-                    }
-                    accounts.add(acc);
-                }
-            }
+    static void commitSelections(Context context) {
+        boolean showingOnlyStarred = PreferenceManager.getDefaultSharedPreferences(context)
+                .getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false);
+        CAT task = new CAT();
+        //noinspection unchecked
+        task.execute(new CommitAccountsTaskParams(Data.accounts.get(), showingOnlyStarred));
+    }
+    private static class UAT extends UpdateAccountsTask {
+        @Override
+        protected void onPostExecute(ArrayList<LedgerAccount> list) {
+            super.onPostExecute(list);
+            if (list != null) Data.accounts.set(list);
         }
     }
-    void commitSelections(Context context) {
-        try (SQLiteDatabase db = MLDB.getWritableDatabase()) {
-            db.beginTransaction();
-            try {
-                for (LedgerAccount acc : accounts) {
-                    Log.d("db", String.format("Setting %s to %s", acc.getName(),
-                            acc.isHidden() ? "hidden" : "starred"));
-                    db.execSQL("UPDATE accounts SET hidden=? WHERE name=?",
-                            new Object[]{acc.isHiddenToBe() ? 1 : 0, acc.getName()});
-                }
-                db.setTransactionSuccessful();
-                for (LedgerAccount acc : accounts ) { acc.setHidden(acc.isHiddenToBe()); }
+    private static class CAT extends CommitAccountsTask {
+        @Override
+        protected void onPostExecute(ArrayList<LedgerAccount> list) {
+            super.onPostExecute(list);
+            if (list != null) {
+                Log.d("acc", "setting new account list");
+                Data.accounts.set(list);
             }
-            finally { db.endTransaction(); }
         }
     }
 }
 
-class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter
-.LedgerRowHolder> {
-    private List<LedgerAccount> accounts;
+class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter.LedgerRowHolder> {
     private boolean selectionActive;
 
-    AccountSummaryAdapter(List<LedgerAccount> accounts) {
-        this.accounts = accounts;
+    AccountSummaryAdapter() {
         this.selectionActive = false;
     }
 
     public void onBindViewHolder(@NonNull LedgerRowHolder holder, int position) {
-        LedgerAccount acc = accounts.get(position);
+        LedgerAccount acc = Data.accounts.get().get(position);
         Context ctx = holder.row.getContext();
         Resources rm = ctx.getResources();
 
         holder.tvAccountName.setText(acc.getShortName());
         holder.tvAccountName.setPadding(
                 acc.getLevel() * rm.getDimensionPixelSize(R.dimen.activity_horizontal_margin) / 2,
-                0, 0,
-                0);
+                0, 0, 0);
         holder.tvAccountAmounts.setText(acc.getAmountsString());
 
         if (acc.isHidden()) {
@@ -150,7 +117,7 @@ class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter
             else holder.row.setBackgroundColor(rm.getColor(R.color.drawer_background));
         }
 
-        holder.selectionCb.setVisibility( selectionActive ? View.VISIBLE : View.GONE);
+        holder.selectionCb.setVisibility(selectionActive ? View.VISIBLE : View.GONE);
         holder.selectionCb.setChecked(!acc.isHiddenToBe());
 
         holder.row.setTag(R.id.POS, position);
@@ -166,10 +133,10 @@ class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter
 
     @Override
     public int getItemCount() {
-        return accounts.size();
+        return Data.accounts.get().size();
     }
     public void startSelection() {
-        for( LedgerAccount acc : accounts ) acc.setHiddenToBe(acc.isHidden());
+        for (LedgerAccount acc : Data.accounts.get()) acc.setHiddenToBe(acc.isHidden());
         this.selectionActive = true;
         notifyDataSetChanged();
     }
@@ -184,13 +151,13 @@ class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter
     }
 
     public void selectItem(int position) {
-        LedgerAccount acc = accounts.get(position);
+        LedgerAccount acc = Data.accounts.get().get(position);
         acc.toggleHiddenToBe();
         toggleChildrenOf(acc, acc.isHiddenToBe());
         notifyDataSetChanged();
     }
     void toggleChildrenOf(LedgerAccount parent, boolean hiddenToBe) {
-        for (LedgerAccount acc : accounts) {
+        for (LedgerAccount acc : Data.accounts.get()) {
             String acc_parent = acc.getParentName();
             if ((acc_parent != null) && acc.getParentName().equals(parent.getName())) {
                 acc.setHiddenToBe(hiddenToBe);
@@ -198,6 +165,7 @@ class AccountSummaryAdapter extends RecyclerView.Adapter<AccountSummaryAdapter
             }
         }
     }
+
     class LedgerRowHolder extends RecyclerView.ViewHolder {
         CheckBox selectionCb;
         TextView tvAccountName, tvAccountAmounts;