+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
+ builder.setCancelable(true)
+ .setTitle(R.string.choose_template_to_apply)
+ .setIcon(R.drawable.ic_baseline_auto_graph_24)
+ .setSingleChoiceItems(cursor, -1, templateNameColumn, (dialog, which) -> {
+ model.applyTemplate(matchingTemplates.get(which), matchedText);
+ dialog.dismiss();
+ })
+ .create()
+ .show();
+ }
+ public void descriptionSelected(String description) {
+ debug("description selected", description);
+ if (!model.accountListIsEmpty())
+ return;
+
+ String accFilter = mProfile.getPreferredAccountsFilter();
+
+ ArrayList<String> params = new ArrayList<>();
+ StringBuilder sb = new StringBuilder("select t.profile, t.id from transactions t");
+
+ if (!TextUtils.isEmpty(accFilter)) {
+ sb.append(" JOIN transaction_accounts ta")
+ .append(" ON ta.profile = t.profile")
+ .append(" AND ta.transaction_id = t.id");
+ }
+
+ sb.append(" WHERE t.description=?");
+ params.add(description);
+
+ if (!TextUtils.isEmpty(accFilter)) {
+ sb.append(" AND ta.account_name LIKE '%'||?||'%'");
+ params.add(accFilter);
+ }
+
+ sb.append(" ORDER BY t.year desc, t.month desc, t.day desc LIMIT 1");
+
+ final String sql = sb.toString();
+ debug("description", sql);
+ debug("description", params.toString());
+
+ // FIXME: handle exceptions?
+ MLDB.queryInBackground(sql, params.toArray(new String[]{}), new MLDB.CallbackHelper() {
+ @Override
+ public void onStart() {
+ model.incrementBusyCounter();
+ }
+ @Override
+ public void onDone() {
+ model.decrementBusyCounter();
+ }
+ @Override
+ public boolean onRow(@NonNull Cursor cursor) {
+ final long profileId = cursor.getLong(0);
+ final int transactionId = cursor.getInt(1);
+ runOnUiThread(() -> model.loadTransactionIntoModel(profileId, transactionId));
+ return false; // limit 1, by the way
+ }
+ @Override
+ public void onNoRows() {
+ if (TextUtils.isEmpty(accFilter))
+ return;
+
+ debug("description", "Trying transaction search without preferred account filter");
+
+ final String broaderSql =
+ "select t.profile, t.id from transactions t where t.description=?" +
+ " ORDER BY year desc, month desc, day desc LIMIT 1";
+ params.remove(1);
+ debug("description", broaderSql);
+ debug("description", description);
+
+ runOnUiThread(() -> Snackbar.make(b.newTransactionNav,
+ R.string.ignoring_preferred_account, Snackbar.LENGTH_INDEFINITE)
+ .show());
+
+ MLDB.queryInBackground(broaderSql, new String[]{description},
+ new MLDB.CallbackHelper() {
+ @Override
+ public void onStart() {
+ model.incrementBusyCounter();
+ }
+ @Override
+ public boolean onRow(@NonNull Cursor cursor) {
+ final long profileId = cursor.getLong(0);
+ final int transactionId = cursor.getInt(1);
+ runOnUiThread(() -> model.loadTransactionIntoModel(profileId,
+ transactionId));
+ return false;
+ }
+ @Override
+ public void onDone() {
+ model.decrementBusyCounter();
+ }
+ });
+ }
+ });
+ }
+ private void onFabPressed() {
+ fabManager.hideFab();
+ Misc.hideSoftKeyboard(this);
+
+ LedgerTransaction tr = model.constructLedgerTransaction();
+
+ onTransactionSave(tr);
+ }
+ @Override
+ public Context getContext() {
+ return this;
+ }
+ @Override
+ public void showManagedFab() {
+ if (Objects.requireNonNull(model.isSubmittable()
+ .getValue()))
+ fabManager.showFab();
+ }
+ @Override
+ public void hideManagedFab() {
+ fabManager.hideFab();
+ }