From: Damyan Ivanov Date: Sun, 30 Dec 2018 11:50:44 +0000 (+0000) Subject: add transaction filter X-Git-Tag: v0.3~161 X-Git-Url: https://git.ktnx.net/?a=commitdiff_plain;h=14873dbc3aa249dc5af735c8906be1a19b5f7dda;p=mobile-ledger.git add transaction filter --- diff --git a/app/build.gradle b/app/build.gradle index 01a301f7..db130222 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } diff --git a/app/src/main/java/net/ktnx/mobileledger/MobileLedgerApplication.java b/app/src/main/java/net/ktnx/mobileledger/MobileLedgerApplication.java index 39d7e542..2cd3db0a 100644 --- a/app/src/main/java/net/ktnx/mobileledger/MobileLedgerApplication.java +++ b/app/src/main/java/net/ktnx/mobileledger/MobileLedgerApplication.java @@ -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); } } } diff --git a/app/src/main/java/net/ktnx/mobileledger/TransactionListActivity.java b/app/src/main/java/net/ktnx/mobileledger/TransactionListActivity.java index 6a9c24d9..ac992cdf 100644 --- a/app/src/main/java/net/ktnx/mobileledger/TransactionListActivity.java +++ b/app/src/main/java/net/ktnx/mobileledger/TransactionListActivity.java @@ -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); } } diff --git a/app/src/main/java/net/ktnx/mobileledger/TransactionListAdapter.java b/app/src/main/java/net/ktnx/mobileledger/TransactionListAdapter.java index 7fa85d3a..41c3cdd5 100644 --- a/app/src/main/java/net/ktnx/mobileledger/TransactionListAdapter.java +++ b/app/src/main/java/net/ktnx/mobileledger/TransactionListAdapter.java @@ -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 { 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; diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListViewModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListViewModel.java index 480c0de2..1680236b 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListViewModel.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListViewModel.java @@ -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 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))); } diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java b/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java index 39884f05..b7fffadf 100644 --- a/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java +++ b/app/src/main/java/net/ktnx/mobileledger/utils/Globals.java @@ -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 index 00000000..f0edd1ef --- /dev/null +++ b/app/src/main/res/drawable/ic_filter_list_white_24dp.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/layout/transaction_list_fragment.xml b/app/src/main/res/layout/transaction_list_fragment.xml index 25b6a57f..ead3956e 100644 --- a/app/src/main/res/layout/transaction_list_fragment.xml +++ b/app/src/main/res/layout/transaction_list_fragment.xml @@ -34,6 +34,34 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> + + + + + + + + + + + + + + + + \ No newline at end of file