From 35993af7709c0319c9eb15ad4cc569220fa50f20 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 14 Apr 2023 10:07:33 +0200 Subject: [PATCH] Added editing rule groups --- .../java/eu/faircode/email/AdapterRule.java | 19 +++- .../main/java/eu/faircode/email/DaoRule.java | 5 + .../email/FragmentDialogRuleGroup.java | 107 ++++++++++++++++++ .../java/eu/faircode/email/FragmentRules.java | 33 +++++- app/src/main/res/layout/dialog_rule_group.xml | 33 ++++++ 5 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/eu/faircode/email/FragmentDialogRuleGroup.java create mode 100644 app/src/main/res/layout/dialog_rule_group.xml diff --git a/app/src/main/java/eu/faircode/email/AdapterRule.java b/app/src/main/java/eu/faircode/email/AdapterRule.java index 38a31a301f..b1921f7874 100644 --- a/app/src/main/java/eu/faircode/email/AdapterRule.java +++ b/app/src/main/java/eu/faircode/email/AdapterRule.java @@ -299,9 +299,10 @@ public class AdapterRule extends RecyclerView.Adapter { popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_execute, 2, R.string.title_rule_execute) .setEnabled(ActivityBilling.isPro(context)); popupMenu.getMenu().add(Menu.NONE, R.string.title_reset, 3, R.string.title_reset); + popupMenu.getMenu().add(Menu.NONE, R.string.title_rule_group, 4, R.string.title_rule_group); if (protocol == EntityAccount.TYPE_IMAP) { - popupMenu.getMenu().add(Menu.NONE, R.string.title_move_to_folder, 4, R.string.title_move_to_folder); - popupMenu.getMenu().add(Menu.NONE, R.string.title_copy, 5, R.string.title_copy); + popupMenu.getMenu().add(Menu.NONE, R.string.title_move_to_folder, 5, R.string.title_move_to_folder); + popupMenu.getMenu().add(Menu.NONE, R.string.title_copy, 6, R.string.title_copy); } popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @@ -317,6 +318,9 @@ public class AdapterRule extends RecyclerView.Adapter { } else if (itemId == R.string.title_reset) { onActionReset(); return true; + } else if (itemId == R.string.title_rule_group) { + onActionGroup(); + return true; } else if (itemId == R.string.title_move_to_folder) { onActionMove(); return true; @@ -460,6 +464,17 @@ public class AdapterRule extends RecyclerView.Adapter { }.execute(context, owner, args, "rule:reset"); } + private void onActionGroup() { + Bundle args = new Bundle(); + args.putLong("rule", rule.id); + args.putString("name", rule.group); + + FragmentDialogRuleGroup fragment = new FragmentDialogRuleGroup(); + fragment.setArguments(args); + fragment.setTargetFragment(parentFragment, FragmentRules.REQUEST_GROUP); + fragment.show(parentFragment.getParentFragmentManager(), "rule:group"); + } + private void onActionMove() { Bundle args = new Bundle(); args.putInt("icon", R.drawable.twotone_drive_file_move_24); diff --git a/app/src/main/java/eu/faircode/email/DaoRule.java b/app/src/main/java/eu/faircode/email/DaoRule.java index cc30b6e3ec..e68cb5f9bc 100644 --- a/app/src/main/java/eu/faircode/email/DaoRule.java +++ b/app/src/main/java/eu/faircode/email/DaoRule.java @@ -86,6 +86,11 @@ public interface DaoRule { " WHERE id = :id AND NOT (enabled IS :enabled)") int setRuleEnabled(long id, boolean enabled); + @Query("UPDATE rule" + + " SET `group` = :group" + + " WHERE id = :id AND NOT (`group` IS :group)") + int setRuleGroup(long id, String group); + @Query("UPDATE rule" + " SET applied = applied + 1, last_applied = :time" + " WHERE id = :id") diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogRuleGroup.java b/app/src/main/java/eu/faircode/email/FragmentDialogRuleGroup.java new file mode 100644 index 0000000000..09c4dc61fe --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentDialogRuleGroup.java @@ -0,0 +1,107 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail 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 for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2023 by Marcel Bokhorst (M66B) +*/ + +import static android.app.Activity.RESULT_OK; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import java.util.List; + +public class FragmentDialogRuleGroup extends FragmentDialogBase { + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + final Context context = getContext(); + View view = LayoutInflater.from(context).inflate(R.layout.dialog_rule_group, null); + final AutoCompleteTextView etGroup = view.findViewById(R.id.etGroup); + + ArrayAdapter adapterGroup = new ArrayAdapter<>(context, R.layout.spinner_item1_dropdown, android.R.id.text1); + etGroup.setThreshold(1); + etGroup.setAdapter(adapterGroup); + + new SimpleTask>() { + @Override + protected List onExecute(Context context, Bundle args) { + DB db = DB.getInstance(context); + return db.rule().getGroups(); + } + + @Override + protected void onExecuted(Bundle args, List groups) { + adapterGroup.clear(); + adapterGroup.addAll(groups); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Log.unexpectedError(getParentFragmentManager(), ex); + } + }.execute(this, new Bundle(), "rule:groups"); + + Bundle args = getArguments(); + etGroup.setText(args.getString("name")); + + etGroup.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId != EditorInfo.IME_ACTION_DONE) + return false; + AlertDialog dialog = (AlertDialog) getDialog(); + if (dialog == null) + return false; + Button btnOk = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + if (btnOk == null) + return false; + btnOk.performClick(); + return true; + } + }); + + return new AlertDialog.Builder(context) + .setView(view) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String group = etGroup.getText().toString().trim(); + args.putString("name", TextUtils.isEmpty(group) ? null : group); + sendResult(RESULT_OK); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .create(); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentRules.java b/app/src/main/java/eu/faircode/email/FragmentRules.java index bdcb55ccb5..4fce10e03e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentRules.java +++ b/app/src/main/java/eu/faircode/email/FragmentRules.java @@ -93,10 +93,11 @@ public class FragmentRules extends FragmentBase { private static final int REQUEST_EXPORT = 1; private static final int REQUEST_IMPORT = 2; - static final int REQUEST_MOVE = 3; - static final int REQUEST_RULE_COPY_ACCOUNT = 4; - static final int REQUEST_RULE_COPY_FOLDER = 5; - private static final int REQUEST_CLEAR = 6; + static final int REQUEST_GROUP = 3; + static final int REQUEST_MOVE = 4; + static final int REQUEST_RULE_COPY_ACCOUNT = 5; + static final int REQUEST_RULE_COPY_FOLDER = 6; + private static final int REQUEST_CLEAR = 7; @Override public void onCreate(Bundle savedInstanceState) { @@ -266,6 +267,7 @@ public class FragmentRules extends FragmentBase { String sort = prefs.getString("rule_sort", "order"); adapter.set(protocol, sort, rules); + rvRule.invalidateItemDecorations(); pbWait.setVisibility(View.GONE); grpReady.setVisibility(View.VISIBLE); @@ -287,6 +289,10 @@ public class FragmentRules extends FragmentBase { if (resultCode == RESULT_OK && data != null) onImport(data); break; + case REQUEST_GROUP: + if (resultCode == RESULT_OK && data != null) + onGroup(data.getBundleExtra("args")); + break; case REQUEST_MOVE: if (resultCode == RESULT_OK && data != null) onMove(data.getBundleExtra("args")); @@ -675,6 +681,25 @@ public class FragmentRules extends FragmentBase { }.execute(this, args, "rules:import"); } + private void onGroup(Bundle args) { + new SimpleTask() { + @Override + protected Void onExecute(Context context, Bundle args) { + long id = args.getLong("rule"); + String name = args.getString("name"); + + DB db = DB.getInstance(context); + db.rule().setRuleGroup(id, name); + return null; + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Log.unexpectedError(getParentFragmentManager(), ex); + } + }.execute(this, args, "rule:group"); + } + private void onMove(Bundle args) { new SimpleTask() { @Override diff --git a/app/src/main/res/layout/dialog_rule_group.xml b/app/src/main/res/layout/dialog_rule_group.xml new file mode 100644 index 0000000000..c9028e3255 --- /dev/null +++ b/app/src/main/res/layout/dialog_rule_group.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file