diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index 766ae81333..d1c84a11cf 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -471,7 +471,7 @@ class Core { break; case EntityOperation.DELETE: - onDelete(context, jargs, account, folder, messages, (IMAPFolder) ifolder); + onDelete(context, jargs, account, folder, messages, (IMAPStore) istore, (IMAPFolder) ifolder); break; case EntityOperation.HEADERS: @@ -1784,11 +1784,12 @@ class Core { } } - private static void onDelete(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, List messages, IMAPFolder ifolder) throws MessagingException, IOException { + private static void onDelete(Context context, JSONArray jargs, EntityAccount account, EntityFolder folder, List messages, IMAPStore istore, IMAPFolder ifolder) throws MessagingException, IOException { // Delete message DB db = DB.getInstance(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean perform_expunge = prefs.getBoolean("perform_expunge", true); + boolean gmail_delete_all = prefs.getBoolean("gmail_delete_all", false); if (folder.local) { Log.i(folder.name + " local delete"); @@ -1798,6 +1799,62 @@ class Core { } try { + if (account.isGmail() && gmail_delete_all) { + EntityFolder trash = db.folder().getFolderByType(account.id, EntityFolder.TRASH); + if (trash != null) { + Map folders = new HashMap<>(); + EntityFolder archive = db.folder().getFolderByType(account.id, EntityFolder.ARCHIVE); + if (archive != null) + folders.put(archive.name, archive.id); + + List uids = new ArrayList<>(); + for (EntityMessage message : messages) + if (message.uid != null) + uids.add(message.uid); + + IMAPFolder itrash = (IMAPFolder) istore.getFolder(trash.name); + Message[] imessages = ifolder.getMessagesByUID(Helper.toLongArray(uids)); + + for (Message imessage : imessages) + if (imessage instanceof GmailMessage) + try { + String[] labels = ((GmailMessage) imessage).getLabels(); + for (String label : labels) + if (!folders.containsKey(label)) { + EntityFolder f = db.folder().getFolderByName(account.id, label); + if (f != null) + folders.put(f.name, f.id); + } + } catch (Throwable ex) { + Log.e(ex); + } + + ifolder.moveMessages(imessages, itrash); + + itrash.open(READ_WRITE); + try { + List trashed = new ArrayList<>(); + for (EntityMessage message : messages) { + Message[] itrashed = itrash.search(new MessageIDTerm(message.msgid)); + if (itrashed != null && itrashed.length == 1) + trashed.add(itrashed[0]); + } + + itrash.setFlags(trashed.toArray(new Message[0]), new Flags(Flags.Flag.DELETED), true); + if (perform_expunge) + expunge(context, itrash, trashed); + } finally { + if (itrash.isOpen()) + itrash.close(); + } + + for (long fid : folders.values()) + EntityOperation.sync(context, fid, false); + + return; + } + } + if (messages.size() > 1) { boolean ui_deleted = messages.get(0).ui_deleted; diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java index 38ce024a8a..9eee7724e3 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java @@ -110,6 +110,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe private SwitchCompat swMoveThreadAll; private SwitchCompat swMoveThreadSent; private SwitchCompat swSwipeTrashAll; + private SwitchCompat swGmailDeleteAll; private Button btnDefaultFolder; private TextView tvDefaultFolder; @@ -129,7 +130,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe "undo_timeout", "autoread", "flag_snoozed", "flag_unsnoozed", "autounflag", "auto_important", "reset_importance", "reset_snooze", "auto_block_sender", "auto_hide_answer", "swipe_reply", - "move_thread_all", "move_thread_sent", "swipe_trash_all", + "move_thread_all", "move_thread_sent", "swipe_trash_all", "gmail_delete_all", "default_folder" )); @@ -196,6 +197,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe swMoveThreadAll = view.findViewById(R.id.swMoveThreadAll); swMoveThreadSent = view.findViewById(R.id.swMoveThreadSent); swSwipeTrashAll = view.findViewById(R.id.swSwipeTrashAll); + swGmailDeleteAll = view.findViewById(R.id.swGmailDeleteAll); btnDefaultFolder = view.findViewById(R.id.btnDefaultFolder); tvDefaultFolder = view.findViewById(R.id.tvDefaultFolder); @@ -626,6 +628,13 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe } }); + swGmailDeleteAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("gmail_delete_all", checked).apply(); + } + }); + Intent tree = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); Helper.openAdvanced(getContext(), tree); PackageManager pm = getContext().getPackageManager(); @@ -802,6 +811,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe swMoveThreadSent.setChecked(prefs.getBoolean("move_thread_sent", false)); swMoveThreadSent.setEnabled(!swMoveThreadAll.isChecked()); swSwipeTrashAll.setChecked(prefs.getBoolean("swipe_trash_all", true)); + swGmailDeleteAll.setChecked(prefs.getBoolean("gmail_delete_all", false)); tvDefaultFolder.setText(prefs.getString("default_folder", null)); } catch (Throwable ex) { diff --git a/app/src/main/res/layout/fragment_options_behavior.xml b/app/src/main/res/layout/fragment_options_behavior.xml index 631a4a9ed9..34def9edcf 100644 --- a/app/src/main/res/layout/fragment_options_behavior.xml +++ b/app/src/main/res/layout/fragment_options_behavior.xml @@ -913,6 +913,17 @@ app:layout_constraintTop_toBottomOf="@id/swMoveThreadSent" app:switchPadding="12dp" /> + +