From 59564ed14ad933c65dd459389a122a152ae8dae5 Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 5 Nov 2020 16:45:30 +0100 Subject: [PATCH] Fine grained operations delete --- app/src/main/java/eu/faircode/email/Core.java | 2 +- .../eu/faircode/email/EntityOperation.java | 4 +- .../eu/faircode/email/FragmentOperations.java | 79 +++++++++++++++++-- .../res/layout/dialog_delete_operations.xml | 67 ++++++++++++++++ app/src/main/res/values/strings.xml | 7 +- 5 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 app/src/main/res/layout/dialog_delete_operations.xml diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index 55a392789c..fc3b21eeda 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -489,7 +489,7 @@ class Core { db.beginTransaction(); // Cleanup operation - op.cleanup(context); + op.cleanup(context, true); // There is no use in repeating db.operation().deleteOperation(op.id); diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index 631cb3a999..21465ca82a 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -441,7 +441,7 @@ public class EntityOperation { Log.i("Queued subscribe=" + subscribe + " folder=" + folder); } - void cleanup(Context context) { + void cleanup(Context context, boolean fetch) { DB db = DB.getInstance(context); if (message != null) @@ -473,7 +473,7 @@ public class EntityOperation { if (EntityOperation.SYNC.equals(name)) db.folder().setFolderSyncState(folder, null); - if (message != null) { + if (fetch && message != null) { EntityMessage m = db.message().getMessage(message); if (m == null || m.uid == null) return; diff --git a/app/src/main/java/eu/faircode/email/FragmentOperations.java b/app/src/main/java/eu/faircode/email/FragmentOperations.java index 73022db416..37f2fc15ce 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOperations.java +++ b/app/src/main/java/eu/faircode/email/FragmentOperations.java @@ -29,6 +29,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; import android.widget.TextView; import androidx.annotation.NonNull; @@ -130,23 +131,80 @@ public class FragmentOperations extends FragmentBase { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + final View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_delete_operations, null); + final CheckBox cbError = dview.findViewById(R.id.cbError); + final CheckBox cbFetch = dview.findViewById(R.id.cbFetch); + final CheckBox cbMove = dview.findViewById(R.id.cbMove); + final CheckBox cbFlag = dview.findViewById(R.id.cbFlag); + final CheckBox cbDelete = dview.findViewById(R.id.cbDelete); + return new AlertDialog.Builder(getContext()) - .setMessage(R.string.title_delete_operation) + .setView(dview) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Bundle args = new Bundle(); + args.putBoolean("error", cbError.isChecked()); + args.putBoolean("fetch", cbFetch.isChecked()); + args.putBoolean("move", cbMove.isChecked()); + args.putBoolean("flag", cbFlag.isChecked()); + args.putBoolean("delete", cbDelete.isChecked()); + new SimpleTask() { @Override protected Void onExecute(Context context, Bundle args) { + boolean error = args.getBoolean("error"); + boolean fetch = args.getBoolean("fetch"); + boolean move = args.getBoolean("move"); + boolean flag = args.getBoolean("flag"); + boolean delete = args.getBoolean("delete"); + DB db = DB.getInstance(context); - List ops = db.operation().getOperationsError(); - Log.i("Operations with error count=" + ops.size()); - for (EntityOperation op : ops) { - Log.w("Deleting operation=" + op.id + " error=" + op.error); - if (op.message != null) - db.message().setMessageUiHide(op.message, false); - db.operation().deleteOperation(op.id); + try { + db.beginTransaction(); + + List ops = new ArrayList<>(); + + if (error) + addAll(ops, db.operation().getOperationsError()); + + if (fetch) { + addAll(ops, db.operation().getOperations(EntityOperation.FETCH)); + addAll(ops, db.operation().getOperations(EntityOperation.BODY)); + addAll(ops, db.operation().getOperations(EntityOperation.ATTACHMENT)); + addAll(ops, db.operation().getOperations(EntityOperation.HEADERS)); + addAll(ops, db.operation().getOperations(EntityOperation.SYNC)); + } + + if (move) { + addAll(ops, db.operation().getOperations(EntityOperation.MOVE)); + addAll(ops, db.operation().getOperations(EntityOperation.COPY)); + } + + if (flag) { + addAll(ops, db.operation().getOperations(EntityOperation.SEEN)); + addAll(ops, db.operation().getOperations(EntityOperation.ANSWERED)); + addAll(ops, db.operation().getOperations(EntityOperation.FLAG)); + addAll(ops, db.operation().getOperations(EntityOperation.KEYWORD)); + addAll(ops, db.operation().getOperations(EntityOperation.LABEL)); + } + + if (delete) { + addAll(ops, db.operation().getOperations(EntityOperation.DELETE)); + addAll(ops, db.operation().getOperations(EntityOperation.PURGE)); + } + + for (EntityOperation op : ops) { + EntityLog.log(context, "Deleting operation=" + op.id + ":" + op.name + " error=" + op.error); + if (db.operation().deleteOperation(op.id) > 0) + op.cleanup(context, false); + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); } + return null; } @@ -154,6 +212,11 @@ public class FragmentOperations extends FragmentBase { protected void onException(Bundle args, Throwable ex) { Log.unexpectedError(getParentFragmentManager(), ex); } + + private void addAll(List list, List sublist) { + if (sublist != null) + list.addAll(sublist); + } }.execute(getContext(), getActivity(), new Bundle(), "operations:delete"); } }) diff --git a/app/src/main/res/layout/dialog_delete_operations.xml b/app/src/main/res/layout/dialog_delete_operations.xml new file mode 100644 index 0000000000..b8ad31a91d --- /dev/null +++ b/app/src/main/res/layout/dialog_delete_operations.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70f1f01830..c3de03834a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -737,7 +737,12 @@ Delete all trashed messages of all accounts permanently? Delete all spam messages of all accounts permanently? This will delete all messages both from the device and the server - Delete operations with an error message? + Delete operations + With an error message + Fetch operations + Move operations + Flag operations + Delete operations Delete all local contacts? No pending operations Deleting operations can result in disappearing messages and synchronization problems