]> git.ktnx.net Git - mobile-ledger.git/blobdiff - app/src/main/java/net/ktnx/mobileledger/AccountSummary.java
separate packages for the different aspects of the application
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / AccountSummary.java
index fbdc89f2c659205a8ddaa39b5c0b54d0f202564d..9182949828910225deee0e627cea72ae4e8457ae 100644 (file)
@@ -1,41 +1,55 @@
+/*
+ * Copyright © 2018 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;
 
-import android.annotation.SuppressLint;
+import android.arch.lifecycle.ViewModelProviders;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Typeface;
 import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
+import android.support.design.widget.FloatingActionButton;
 import android.support.design.widget.Snackbar;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.app.ActionBarDrawerToggle;
 import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.Toolbar;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.ContextMenu;
-import android.view.Gravity;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
 import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
 
+import net.ktnx.mobileledger.async.RetrieveAccountsTask;
+import net.ktnx.mobileledger.model.LedgerAccount;
+import net.ktnx.mobileledger.utils.MobileLedgerDatabase;
+
+import java.lang.ref.WeakReference;
 import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.List;
 
-import static android.view.View.GONE;
-import static net.ktnx.mobileledger.MobileLedgerDB.db;
-import static net.ktnx.mobileledger.MobileLedgerDB.set_option_value;
+import static net.ktnx.mobileledger.SettingsActivity.PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS;
 
 public class AccountSummary extends AppCompatActivity {
     DrawerLayout drawer;
@@ -44,12 +58,14 @@ public class AccountSummary extends AppCompatActivity {
     private static boolean account_list_needs_update = true;
     MenuItem mShowHiddenAccounts;
     SharedPreferences.OnSharedPreferenceChangeListener sBindPreferenceSummaryToValueListener;
-    private AccountRowLayout clickedAccountRow;
+    private MobileLedgerDatabase dbh;
+    private AccountSummaryViewModel model;
+    private AccountSummaryAdapter modelAdapter;
+    private Menu optMenu;
 
     public static void preferences_changed() {
         account_list_needs_update = true;
     }
-    MenuItem mRefresh;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -58,6 +74,8 @@ public class AccountSummary extends AppCompatActivity {
         Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
 
+        dbh = new MobileLedgerDatabase(this);
+
         drawer = findViewById(R.id.drawer_layout);
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                 this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
@@ -73,8 +91,55 @@ public class AccountSummary extends AppCompatActivity {
             e.printStackTrace();
         }
 
+        model = ViewModelProviders.of(this).get(AccountSummaryViewModel.class);
+        List<LedgerAccount> accounts = model.getAccounts();
+        modelAdapter = new AccountSummaryAdapter(accounts);
+
+        RecyclerView root = findViewById(R.id.account_root);
+        root.setAdapter(modelAdapter);
+
+        LinearLayoutManager llm = new LinearLayoutManager(this);
+        llm.setOrientation(LinearLayoutManager.VERTICAL);
+        root.setLayoutManager(llm);
+
+        root.addOnItemTouchListener(new RecyclerItemListener(this, root, new RecyclerItemListener.RecyclerTouchListener() {
+            @Override
+            public void onClickItem(View v, int position) {
+                Log.d("list", String.format("item %d clicked", position));
+                if (modelAdapter.isSelectionActive()) {
+                    modelAdapter.selectItem(position);
+                }
+            }
+
+            @Override
+            public void onLongClickItem(View v, int position) {
+                Log.d("list", String.format("item %d long-clicked", position));
+                modelAdapter.startSelection();
+                if (optMenu != null) {
+                    optMenu.findItem(R.id.menu_acc_summary_cancel_selection).setVisible(true);
+                    optMenu.findItem(R.id.menu_acc_summary_confirm_selection).setVisible(true);
+                    optMenu.findItem(R.id.menu_acc_summary_only_starred).setVisible(false);
+                }
+                {
+                    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.btn_add_transaction);
+                    if (fab != null) fab.hide();
+                }
+            }
+        }));
+
+        root.addOnScrollListener(new RecyclerView.OnScrollListener() {
+            @Override
+            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+                if (dy < 0) ((FloatingActionButton) findViewById(R.id.btn_add_transaction)).show();
+                if (dy > 0) ((FloatingActionButton) findViewById(R.id.btn_add_transaction)).hide();
+            }
+        });
+        ((SwipeRefreshLayout) findViewById(R.id.account_swiper)).setOnRefreshListener(() -> {
+            Log.d("ui", "refreshing accounts via swipe");
+            update_accounts(true);
+        });
         prepare_db();
-        update_account_table();
+//        update_account_table();
         update_accounts(false);
     }
 
@@ -109,7 +174,7 @@ public class AccountSummary extends AppCompatActivity {
     }
 
     public void nav_exit_clicked(View view) {
-        Log.w("mobileledger", "exiting");
+        Log.w("app", "exiting");
         finish();
     }
 
@@ -132,25 +197,17 @@ public class AccountSummary extends AppCompatActivity {
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate the menu; this adds items to the action bar if it is present.
         getMenuInflater().inflate(R.menu.account_summary, menu);
-        mRefresh = menu.findItem(R.id.menu_acc_summary_refresh);
-        if (mRefresh == null) throw new AssertionError();
+        optMenu = menu;
 
-        mShowHiddenAccounts = menu.findItem(R.id.menu_acc_summary_show_hidden);
+        mShowHiddenAccounts = menu.findItem(R.id.menu_acc_summary_only_starred);
         if (mShowHiddenAccounts == null) throw new AssertionError();
 
-        sBindPreferenceSummaryToValueListener =
-                new SharedPreferences.OnSharedPreferenceChangeListener() {
-                    @Override
-                    public
-                    void onSharedPreferenceChanged(SharedPreferences preference, String value) {
-                        mShowHiddenAccounts
-                                .setChecked(preference.getBoolean("show_hidden_accounts", false));
-                    }
-                };
+        sBindPreferenceSummaryToValueListener = (preference, value) -> mShowHiddenAccounts
+                .setChecked(preference.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false));
         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
         pref.registerOnSharedPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
 
-        mShowHiddenAccounts.setChecked(pref.getBoolean("show_hidden_accounts", false));
+        mShowHiddenAccounts.setChecked(pref.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false));
 
         return true;
     }
@@ -175,30 +232,20 @@ public class AccountSummary extends AppCompatActivity {
     }
 
     public
-    void onShowHiddenAccountsClicked(MenuItem mi) {
+    void onShowOnlyStarredClicked(MenuItem mi) {
         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
-        boolean flag = pref.getBoolean("show_hidden_accounts", false);
+        boolean flag = pref.getBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, false);
 
         SharedPreferences.Editor editor = pref.edit();
-        editor.putBoolean("show_hidden_accounts", !flag);
-        Log.d("pref", "Setting show_hidden_accounts to " + (flag ? "false" : "true"));
+        editor.putBoolean(PREF_KEY_SHOW_ONLY_STARRED_ACCOUNTS, !flag);
+        Log.d("pref", "Setting show only starred accounts pref to " + (flag ? "false" : "true"));
         editor.apply();
 
         update_account_table();
     }
 
     private void prepare_db() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            MobileLedgerDB.setDb_filename(this.getApplicationInfo().deviceProtectedDataDir + "/" + MobileLedgerDB.DATABASE_NAME);
-        }
-        else {
-            MobileLedgerDB.setDb_filename(
-                    this.getApplicationInfo().dataDir + "/" + MobileLedgerDB.DATABASE_NAME);
-        }
-        MobileLedgerDB.initDB(getResources(), getPackageName());
-
-        account_list_last_updated = MobileLedgerDB.get_option_value("last_refresh", (long) 0);
-
+        account_list_last_updated = dbh.get_option_value("last_refresh", (long) 0);
     }
 
     private void update_accounts(boolean force) {
@@ -210,167 +257,46 @@ public class AccountSummary extends AppCompatActivity {
     }
 
     private void update_accounts() {
-        if (mRefresh != null) mRefresh.setVisible(false);
-        Resources rm = getResources();
-
-        ProgressBar pb = findViewById(R.id.progressBar);
-        pb.setVisibility(View.VISIBLE);
-        TextView pt = findViewById(R.id.textProgress);
-        pt.setVisibility(View.VISIBLE);
-        pb.setIndeterminate(true);
-
-        RetrieveAccountsTask task = new RetrieveAccountsTask() {
-            @Override
-            protected void onProgressUpdate(Integer... values) {
-                if ( values[0] == 0 )
-                    pt.setText(R.string.progress_connecting);
-                else
-                    pt.setText(String.format(getResources().getString(R.string.progress_N_accounts_loaded), values[0]));
-            }
-
-            @Override
-            protected void onPostExecute(Void result) {
-                pb.setVisibility(GONE);
-                pt.setVisibility(GONE);
-                if (mRefresh != null) mRefresh.setVisible(true);
-                if (this.error != 0) {
-                    String err_text = rm.getString(this.error);
-                    Log.d("visual", String.format("showing snackbar: %s", err_text));
-                    Snackbar.make(drawer, err_text, Snackbar.LENGTH_LONG ).show();
-                }
-                else {
-                    set_option_value("last_refresh", new Date().getTime() );
-                    update_account_table();
-                }
-            }
-        };
+        RetrieveAccountsTask task = new RetrieveAccountsTask(new WeakReference<>(this));
 
         task.setPref(PreferenceManager.getDefaultSharedPreferences(this));
         task.execute();
 
     }
-
-    public int dp2px(float dp) {
-        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()));
-    }
-
-    Pattern higher_account = Pattern.compile("^[^:]+:");
-
-    private String strip_higher_accounts(String acc_name, int[] count) {
-        count[0] = 0;
-        while (true) {
-            Matcher m = higher_account.matcher(acc_name);
-            if (m.find()) {
-                count[0]++;
-                acc_name = m.replaceFirst("");
-            }
-            else break;
+    public void onAccountRefreshDone(int error) {
+        SwipeRefreshLayout srl = findViewById(R.id.account_swiper);
+        srl.setRefreshing(false);
+        if (error != 0) {
+            String err_text = getResources().getString(error);
+            Log.d("visual", String.format("showing snackbar: %s", err_text));
+            Snackbar.make(drawer, err_text, Snackbar.LENGTH_LONG ).show();
+        }
+        else {
+            dbh.set_option_value("last_refresh", new Date().getTime() );
+            update_account_table();
         }
-
-        return acc_name;
-    }
-
-    public void hideAccountClicked(MenuItem item) {
-        db.execSQL("update accounts set hidden=1 where name=?",
-                new Object[]{clickedAccountRow.getAccountName()});
-        update_account_table();
     }
-
-    @SuppressLint("DefaultLocale")
     private void update_account_table() {
-        LinearLayout root = findViewById(R.id.account_root);
-        root.removeAllViewsInLayout();
-
-        View.OnCreateContextMenuListener ccml = new View.OnCreateContextMenuListener() {
-            @Override
-            public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-                clickedAccountRow = (AccountRowLayout) v;
-                getMenuInflater().inflate(R.menu.account_summary_account_menu, menu);
-            }
-        };
-
-        int rowHeight =
-                (int) (getTheme().obtainStyledAttributes(new int[]{android.R.attr.actionBarSize})
-                        .getDimensionPixelSize(0, dp2px(56)) * 0.75);
-
-        boolean showingHiddenAccounts = PreferenceManager.getDefaultSharedPreferences(this)
-                .getBoolean("show_hidden_accounts", false);
-        Log.d("pref", "show_hidden_accounts is " + (showingHiddenAccounts ? "true" : "false"));
-
-        try (Cursor cursor = db
-                .rawQuery("SELECT name, hidden FROM accounts ORDER BY name;", null))
+        model.reloadAccounts();
+        modelAdapter.notifyDataSetChanged();
+    }
+    void stopSelection() {
+        modelAdapter.stopSelection();
+        if (optMenu != null) {
+            optMenu.findItem(R.id.menu_acc_summary_cancel_selection).setVisible(false);
+            optMenu.findItem(R.id.menu_acc_summary_confirm_selection).setVisible(false);
+            optMenu.findItem(R.id.menu_acc_summary_only_starred).setVisible(true);
+        }
         {
-            boolean even = false;
-            String skippingAccountName = null;
-            while (cursor.moveToNext()) {
-                String acc_name = cursor.getString(0);
-                if (skippingAccountName != null) {
-                    if (acc_name.startsWith(skippingAccountName + ":")) continue;
-
-                    skippingAccountName = null;
-                }
-
-                boolean is_hidden = cursor.getInt(1) == 1;
-
-                if (!showingHiddenAccounts && is_hidden) {
-                    skippingAccountName = acc_name;
-                    continue;
-                }
-
-                LinearLayout r = new AccountRowLayout(this, acc_name);
-                r.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-                r.setGravity(Gravity.CENTER_VERTICAL);
-                r.setPadding(getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), dp2px(3), getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin), dp2px(4));
-                r.setMinimumHeight(rowHeight);
-
-                if (even) {
-                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                        r.setBackgroundColor(
-                                getResources().getColor(R.color.table_row_even_bg, getTheme()));
-                    }
-                    else {
-                        r.setBackgroundColor(getResources().getColor(R.color.table_row_even_bg));
-                    }
-                }
-                even = !even;
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                    r.setContextClickable(true);
-                }
-                r.setOnCreateContextMenuListener(ccml);
-
-
-                TextView acc_tv = new TextView(this, null, R.style.account_summary_account_name);
-                acc_tv.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 5f));
-                acc_tv.setGravity(Gravity.CENTER_VERTICAL);
-                int[] indent_level = new int[]{0};
-                String short_acc_name = strip_higher_accounts(acc_name, indent_level);
-                acc_tv.setPadding(indent_level[0] * getResources().getDimensionPixelSize(R.dimen.activity_horizontal_margin) / 2, 0, 0, 0);
-                acc_tv.setText(short_acc_name);
-                if (is_hidden) acc_tv.setTypeface(null, Typeface.ITALIC);
-                r.addView(acc_tv);
-
-                TextView amt_tv = new TextView(this, null, R.style.account_summary_amounts);
-                amt_tv.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 1f));
-                amt_tv.setTextAlignment(EditText.TEXT_ALIGNMENT_VIEW_END);
-                amt_tv.setGravity(Gravity.CENTER_VERTICAL);
-//                amt_tv.setGravity(Gravity.CENTER);
-                amt_tv.setMinWidth(dp2px(60f));
-                StringBuilder amt_text = new StringBuilder();
-                try (Cursor cAmounts = db.rawQuery("SELECT currency, value FROM account_values WHERE account = ?", new String[]{acc_name})) {
-                    while (cAmounts.moveToNext()) {
-                        String curr = cAmounts.getString(0);
-                        Float amt = cAmounts.getFloat(1);
-                        if (amt_text.length() != 0) amt_text.append('\n');
-                        amt_text.append(String.format("%s %,1.2f", curr, amt));
-                    }
-                }
-                amt_tv.setText(amt_text.toString());
-                if (is_hidden) amt_tv.setTypeface(null, Typeface.ITALIC);
-
-                r.addView(amt_tv);
-
-                root.addView(r);
-            }
+            FloatingActionButton fab = findViewById(R.id.btn_add_transaction);
+            if (fab != null) fab.show();
         }
     }
+    public void onCancelAccSelection(MenuItem item) {
+        stopSelection();
+    }
+    public void onConfirmAccSelection(MenuItem item) {
+        model.commitSelections();
+        stopSelection();
+    }
 }