From ec16e3b65c92587adf8e32bb1634c0b91f8441c5 Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 2 Mar 2019 14:32:19 +0000 Subject: [PATCH] Added message copy --- FAQ.md | 3 +- .../eu/faircode/email/AdapterMessage.java | 87 +++++++++++++++++++ app/src/main/java/eu/faircode/email/Core.java | 28 +++--- .../eu/faircode/email/EntityOperation.java | 1 + app/src/main/res/menu/menu_message.xml | 4 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 112 insertions(+), 12 deletions(-) diff --git a/FAQ.md b/FAQ.md index 3bc1c03537..0f964dffcc 100644 --- a/FAQ.md +++ b/FAQ.md @@ -30,7 +30,7 @@ For authorizing: * ~~Synchronize on demand (manual)~~ * ~~Semi-automatic encryption~~ -* Add message copy +* ~~Copy message~~ Anything on this list is in random order and *might* be added in the near future. @@ -188,6 +188,7 @@ The low priority status bar notification shows the number of pending operations, * *add*: add message to remote folder * *move*: move message to another remote folder +* *copy*: copy message to another remote folder * *delete*: delete message from remote folder * *send*: send message * *seen*: mark message as read/unread in remote folder diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 0a787c2a86..7000b5fa1a 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -1803,6 +1803,89 @@ public class AdapterMessage extends RecyclerView.Adapter>() { + @Override + protected List onExecute(Context context, Bundle args) { + DB db = DB.getInstance(context); + + EntityMessage message = db.message().getMessage(args.getLong("id")); + if (message == null) + return null; + + List folders = db.folder().getFolders(message.account); + if (folders == null) + return null; + + EntityFolder.sort(context, folders); + + return folders; + } + + @Override + protected void onExecuted(final Bundle args, List folders) { + if (folders == null) + return; + + View anchor = bnvActions.findViewById(R.id.action_more); + PopupMenu popupMenu = new PopupMenu(context, anchor); + + int order = 0; + for (EntityFolder folder : folders) + popupMenu.getMenu().add(Menu.NONE, folder.id.intValue(), order++, folder.getDisplayName(context)); + + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(final MenuItem target) { + args.putLong("target", target.getItemId()); + + new SimpleTask() { + @Override + protected Void onExecute(Context context, Bundle args) { + long id = args.getLong("id"); + long target = args.getLong("target"); + + DB db = DB.getInstance(context); + try { + db.beginTransaction(); + + EntityMessage message = db.message().getMessage(id); + if (message == null) + return null; + + EntityOperation.queue(context, db, message, EntityOperation.COPY, target); + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + return null; + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(context, owner, ex); + } + }.execute(context, owner, args, "message:copy"); + + return true; + } + }); + + popupMenu.show(); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Helper.unexpectedError(context, owner, ex); + } + }.execute(context, owner, args, "message:copy:list"); + } + private void onMenuDelete(final ActionData data) { Bundle args = new Bundle(); args.putLong("id", data.message.id); @@ -2165,6 +2248,7 @@ public class AdapterMessage extends RecyclerView.Adapter 1 && jargs.getBoolean(1)); + boolean canMove = istore.hasCapability("MOVE"); - if (canMove && + if (!copy && canMove && !EntityFolder.DRAFTS.equals(folder.type) && !EntityFolder.DRAFTS.equals(target.type)) { // Autoread @@ -474,8 +477,9 @@ class Core { // Move message to ifolder.moveMessages(new Message[]{imessage}, itarget); } else { - Log.w(folder.name + " MOVE by DELETE/APPEND" + - " cap=" + canMove + " from=" + folder.type + " to=" + target.type); + if (!copy) + Log.w(folder.name + " MOVE by DELETE/APPEND" + + " cap=" + canMove + " from=" + folder.type + " to=" + target.type); // Serialize source message ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -486,7 +490,7 @@ class Core { Message icopy = new MimeMessage(isession, bis); // Make sure the message has a message ID - if (message.msgid == null) { + if (copy || message.msgid == null) { String msgid = EntityMessage.generateMessageId(); Log.i(target.name + " generated message id=" + msgid); icopy.setHeader("Message-ID", msgid); @@ -540,8 +544,10 @@ class Core { } // Delete source - imessage.setFlag(Flags.Flag.DELETED, true); - ifolder.expunge(); + if (!copy) { + imessage.setFlag(Flags.Flag.DELETED, true); + ifolder.expunge(); + } } catch (Throwable ex) { if (itarget.isOpen()) itarget.close(); diff --git a/app/src/main/java/eu/faircode/email/EntityOperation.java b/app/src/main/java/eu/faircode/email/EntityOperation.java index 75d40916af..1264190615 100644 --- a/app/src/main/java/eu/faircode/email/EntityOperation.java +++ b/app/src/main/java/eu/faircode/email/EntityOperation.java @@ -70,6 +70,7 @@ public class EntityOperation { static final String ADD = "add"; static final String MOVE = "move"; + static final String COPY = "copy"; static final String DELETE = "delete"; static final String SEND = "send"; static final String SEEN = "seen"; diff --git a/app/src/main/res/menu/menu_message.xml b/app/src/main/res/menu/menu_message.xml index 850c503483..233799d9e4 100644 --- a/app/src/main/res/menu/menu_message.xml +++ b/app/src/main/res/menu/menu_message.xml @@ -12,6 +12,10 @@ android:id="@+id/menu_snooze" android:title="@string/title_snooze" /> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eae7715b4e..89e22a5be4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -329,6 +329,7 @@ Show original Trash + Copy … Delete More Spam