]> git.ktnx.net Git - mobile-ledger.git/commitdiff
add transaction filter
authorDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 30 Dec 2018 11:50:44 +0000 (11:50 +0000)
committerDamyan Ivanov <dam+mobileledger@ktnx.net>
Sun, 30 Dec 2018 11:50:44 +0000 (11:50 +0000)
app/build.gradle
app/src/main/java/net/ktnx/mobileledger/MobileLedgerApplication.java
app/src/main/java/net/ktnx/mobileledger/TransactionListActivity.java
app/src/main/java/net/ktnx/mobileledger/TransactionListAdapter.java
app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListViewModel.java
app/src/main/java/net/ktnx/mobileledger/utils/Globals.java
app/src/main/res/drawable/ic_filter_list_white_24dp.xml [new file with mode: 0644]
app/src/main/res/layout/transaction_list_fragment.xml
app/src/main/res/menu/transaction_list.xml [new file with mode: 0644]

index 01a301f7427fb19096bad75be96aa361bfad1e4e..db1302221ea1f7adfc6d5402b617340843c01c35 100644 (file)
@@ -54,4 +54,5 @@ dependencies {
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'com.android.support.test:runner:1.0.2'
     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+    implementation 'org.jetbrains:annotations:15.0'
 }
index 39d7e542d8f8a201d37f83e360b5153d41b72f7a..2cd3db0a0d555859f02419d21389977e6de304d5 100644 (file)
@@ -42,10 +42,14 @@ public class MobileLedgerApplication extends Application {
             Resources.Theme theme = getTheme();
             Globals.table_row_odd_bg = rm.getColor(R.color.table_row_odd_bg, theme);
             Globals.table_row_even_bg = rm.getColor(R.color.table_row_even_bg, theme);
+            Globals.primaryDark = rm.getColor(R.color.design_default_color_primary_dark, theme);
+            Globals.defaultTextColor = rm.getColor(android.R.color.tab_indicator_text, theme);
         }
         else {
             Globals.table_row_odd_bg = rm.getColor(R.color.table_row_odd_bg);
             Globals.table_row_even_bg = rm.getColor(R.color.table_row_even_bg);
+            Globals.primaryDark = rm.getColor(R.color.design_default_color_primary_dark);
+            Globals.defaultTextColor = rm.getColor(android.R.color.tab_indicator_text);
         }
     }
 }
index 6a9c24d9a5dbbc78bc0be5f153922514026c7da1..ac992cdf8df0d7bfed137aa06c046ccbd45e5fc2 100644 (file)
@@ -18,6 +18,7 @@
 package net.ktnx.mobileledger;
 
 import android.arch.lifecycle.ViewModelProviders;
+import android.database.MatrixCursor;
 import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -28,7 +29,12 @@ import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.Toolbar;
 import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AutoCompleteTextView;
 import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
@@ -44,6 +50,9 @@ import java.util.Date;
 
 public class TransactionListActivity extends AppCompatActivity {
     public TransactionListViewModel model;
+    private View bTransactionListCancelDownload;
+    private MenuItem menuTransactionListFilter;
+    private View vAccountFilter;
     private SwipeRefreshLayout swiper;
     private RecyclerView root;
     private ProgressBar progressBar;
@@ -51,6 +60,7 @@ public class TransactionListActivity extends AppCompatActivity {
     private TextView tvLastUpdate;
     private TransactionListAdapter modelAdapter;
     private RetrieveTransactionsTask retrieveTransactionsTask;
+    private AutoCompleteTextView accNameFilter;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -91,6 +101,24 @@ public class TransactionListActivity extends AppCompatActivity {
 
         swiper.setColorSchemeResources(R.color.colorPrimary, R.color.colorAccent);
 
+        vAccountFilter = findViewById(R.id.transaction_list_account_name_filter);
+        accNameFilter = findViewById(R.id.transaction_filter_account_name);
+        bTransactionListCancelDownload = findViewById(R.id.transaction_list_cancel_download);
+
+        MLDB.hook_autocompletion_adapter(this, accNameFilter, "accounts", "name");
+        TransactionListActivity me = this;
+        accNameFilter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                Log.d("tmp", "direct onItemClick");
+                model.reloadTransactions(me);
+                MatrixCursor mc = (MatrixCursor) parent.getItemAtPosition(position);
+                modelAdapter.setBoldAccountName(mc.getString(1));
+                modelAdapter.notifyDataSetChanged();
+                me.hideSoftKeyboard();
+            }
+        });
+
         updateLastUpdateText();
         long last_update = MLDB.get_option_value(this, MLDB.OPT_TRANSACTION_LIST_STAMP, 0L);
         Log.d("transactions", String.format("Last update = %d", last_update));
@@ -121,7 +149,7 @@ public class TransactionListActivity extends AppCompatActivity {
                 PreferenceManager.getDefaultSharedPreferences(this));
 
         retrieveTransactionsTask.execute(params);
-        findViewById(R.id.transaction_list_cancel_download).setEnabled(true);
+        bTransactionListCancelDownload.setEnabled(true);
     }
 
     public void onRetrieveStart() {
@@ -130,6 +158,14 @@ public class TransactionListActivity extends AppCompatActivity {
         else progressBar.setProgress(0);
         progressLayout.setVisibility(View.VISIBLE);
     }
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.transaction_list, menu);
+        menuTransactionListFilter = menu.findItem(R.id.menu_transaction_list_filter);
+        if ((menuTransactionListFilter == null)) throw new AssertionError();
+
+        return true;
+    }
     public void onRetrieveProgress(RetrieveTransactionsTask.Progress progress) {
         if ((progress.getTotal() == RetrieveTransactionsTask.Progress.INDETERMINATE) ||
             (progress.getTotal() == 0))
@@ -177,9 +213,33 @@ public class TransactionListActivity extends AppCompatActivity {
             }
         }
     }
+    public void onClearAccountNameClick(View view) {
+        vAccountFilter.setVisibility(View.GONE);
+        menuTransactionListFilter.setVisible(true);
+        accNameFilter.setText(null);
+        model.reloadTransactions(this);
+        modelAdapter.resetBoldAccountName();
+        modelAdapter.notifyDataSetChanged();
+        hideSoftKeyboard();
+    }
+    private void hideSoftKeyboard() {
+        // hide the keyboard
+        View v = getCurrentFocus();
+        if (v != null) {
+            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
+            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+        }
+    }
+    public void onShowFilterClick(MenuItem menuItem) {
+        vAccountFilter.setVisibility(View.VISIBLE);
+        menuTransactionListFilter.setVisible(false);
+        accNameFilter.requestFocus();
+        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
+        imm.showSoftInput(accNameFilter, 0);
+    }
     public void onStopTransactionRefreshClick(View view) {
         Log.d("interactive", "Cancelling transactions refresh");
         if (retrieveTransactionsTask != null) retrieveTransactionsTask.cancel(false);
-        findViewById(R.id.transaction_list_cancel_download).setEnabled(false);
+        bTransactionListCancelDownload.setEnabled(false);
     }
 }
index 7fa85d3a6c98b277350126403798588e985833bd..41c3cdd551eaa6b08a12c82e02def820314377eb 100644 (file)
@@ -19,6 +19,7 @@ package net.ktnx.mobileledger;
 
 import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Typeface;
 import android.support.annotation.NonNull;
 import android.support.constraint.ConstraintLayout;
 import android.support.v7.widget.AppCompatTextView;
@@ -42,6 +43,7 @@ import static net.ktnx.mobileledger.utils.DimensionUtils.dp2px;
 class TransactionListAdapter
         extends RecyclerView.Adapter<TransactionListAdapter.TransactionRowHolder> {
     TransactionListViewModel model;
+    private String boldAccountName;
     public TransactionListAdapter(TransactionListViewModel model) {
         this.model = model;
     }
@@ -73,8 +75,9 @@ class TransactionListAdapter
                     row.setOrientation(LinearLayout.HORIZONTAL);
                     row.setPaddingRelative(dp2px(ctx, 8), 0, 0, 0);
                     accName = new AppCompatTextView(ctx);
-                    accName.setLayoutParams(new LinearLayout.LayoutParams(0,
-                                    LinearLayout.LayoutParams.WRAP_CONTENT, 5f));
+                    accName.setLayoutParams(
+                            new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT,
+                                    5f));
                     accName.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
                     row.addView(accName);
                     accAmount = new AppCompatTextView(ctx);
@@ -94,6 +97,20 @@ class TransactionListAdapter
                 }
                 accName.setText(acc.getAccountName());
                 accAmount.setText(acc.toString());
+
+                if ((boldAccountName != null) && boldAccountName.equals(acc.getAccountName())) {
+                    accName.setTypeface(null, Typeface.BOLD);
+                    accAmount.setTypeface(null, Typeface.BOLD);
+                    accName.setTextColor(Globals.primaryDark);
+                    accAmount.setTextColor(Globals.primaryDark);
+                }
+                else {
+                    accName.setTypeface(null, Typeface.NORMAL);
+                    accAmount.setTypeface(null, Typeface.NORMAL);
+                    accName.setTextColor(Globals.defaultTextColor);
+                    accAmount.setTextColor(Globals.defaultTextColor);
+                }
+
             }
             if (holder.tableAccounts.getChildCount() > rowIndex) {
                 holder.tableAccounts
@@ -121,10 +138,15 @@ class TransactionListAdapter
     }
 
     @Override
-    public int getItemCount()
-    {
+    public int getItemCount() {
         return model.getTransactionCount();
     }
+    public void setBoldAccountName(String boldAccountName) {
+        this.boldAccountName = boldAccountName;
+    }
+    public void resetBoldAccountName() {
+        this.boldAccountName = null;
+    }
     class TransactionRowHolder extends RecyclerView.ViewHolder {
         TextView tvDescription, tvDate;
         LinearLayout tableAccounts;
index 480c0de271b9d4d71d0f2215c84102a04e482c07..1680236bc9c96a12675be57dd39b6488ce93ed8f 100644 (file)
@@ -22,7 +22,11 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.util.Log;
+import android.view.View;
+import android.widget.AutoCompleteTextView;
 
+import net.ktnx.mobileledger.R;
+import net.ktnx.mobileledger.TransactionListActivity;
 import net.ktnx.mobileledger.model.LedgerTransaction;
 import net.ktnx.mobileledger.utils.MLDB;
 
@@ -35,10 +39,33 @@ public class TransactionListViewModel extends ViewModel {
     public void reloadTransactions(Context context) {
         ArrayList<LedgerTransaction> newList = new ArrayList<>();
 
-        String sql = "SELECT id FROM transactions ORDER BY date desc, id desc";
+        TransactionListActivity act = (TransactionListActivity) context;
+        boolean hasFilter =
+                act.findViewById(R.id.transaction_list_account_name_filter).getVisibility() ==
+                View.VISIBLE;
 
+        String sql;
+        String[] params;
+
+        sql = "SELECT id FROM transactions  ORDER BY date desc, id desc";
+        params = null;
+
+        if (hasFilter) {
+            String filterAccName = String.valueOf(
+                    ((AutoCompleteTextView) act.findViewById(R.id.transaction_filter_account_name))
+                            .getText());
+
+            if (!filterAccName.isEmpty()) {
+                sql = "SELECT distinct tr.id from transactions tr JOIN transaction_accounts ta " +
+                      "ON ta.transaction_id=tr.id WHERE ta.account_name LIKE ?||'%' AND ta" +
+                      ".amount <> 0 ORDER BY tr.date desc, tr.id desc";
+                params = new String[]{filterAccName};
+            }
+        }
+
+        Log.d("tmp", sql);
         try (SQLiteDatabase db = MLDB.getReadableDatabase(context)) {
-            try (Cursor cursor = db.rawQuery(sql, null)) {
+            try (Cursor cursor = db.rawQuery(sql, params)) {
                 while (cursor.moveToNext()) {
                     newList.add(new LedgerTransaction(cursor.getInt(0)));
                 }
index 39884f0517ad389859578b5db954bd44c221ac11..b7fffadf4b0c150153dbaff3df711d707ae22923 100644 (file)
@@ -24,5 +24,7 @@ public final class Globals {
     public static int table_row_even_bg;
     @ColorInt
     public static int table_row_odd_bg;
+    @ColorInt
+    public static int primaryDark, defaultTextColor;
 
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_filter_list_white_24dp.xml b/app/src/main/res/drawable/ic_filter_list_white_24dp.xml
new file mode 100644 (file)
index 0000000..f0edd1e
--- /dev/null
@@ -0,0 +1,21 @@
+<!--
+  ~ 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 permissionsand
+  ~ limitations under the License.
+  -->
+
+<vector android:height="24dp" android:tint="#EEEEEE"
+    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="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
+</vector>
index 25b6a57f6b833416cf0814fcf8bc0ea1565fcba5..ead3956e9def3f5b61c31cfc29472f37a437ec87 100644 (file)
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent">
 
+        <LinearLayout
+            android:id="@+id/transaction_list_account_name_filter"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal"
+            android:visibility="gone">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Account filter" />
+
+            <AutoCompleteTextView
+                android:id="@+id/transaction_filter_account_name"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+
+            <TextView
+                android:id="@+id/textView3"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:background="@drawable/ic_clear_black_24dp"
+                android:clickable="true"
+                android:onClick="onClearAccountNameClick" />
+
+        </LinearLayout>
+
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/app/src/main/res/menu/transaction_list.xml b/app/src/main/res/menu/transaction_list.xml
new file mode 100644 (file)
index 0000000..0043337
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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/>.
+  -->
+
+<menu xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/menu_transaction_list_filter"
+        android:icon="@drawable/ic_filter_list_white_24dp"
+        android:onClick="onShowFilterClick"
+        android:title="Filter"
+        app:showAsAction="always" />
+</menu>
\ No newline at end of file