diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java
index a0c6a0ff4a..cb6be7684a 100644
--- a/app/src/main/java/eu/faircode/email/FragmentCompose.java
+++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java
@@ -4561,6 +4561,9 @@ public class FragmentCompose extends FragmentBase {
} else if ("forward".equals(action)) {
data.draft.thread = data.draft.msgid; // new thread
data.draft.wasforwardedfrom = ref.msgid;
+ } else if ("resend".equals(action)) {
+ data.draft.thread = data.draft.msgid;
+ data.draft.headers = ref.headers;
} else if ("editasnew".equals(action))
data.draft.thread = data.draft.msgid;
@@ -4591,7 +4594,7 @@ public class FragmentCompose extends FragmentBase {
ref.language,
alt_fwd ? R.string.title_subject_forward_alt : R.string.title_subject_forward,
subject);
- } else if ("editasnew".equals(action)) {
+ } else if ("resend".equals(action) || "editasnew".equals(action)) {
if (ref.from != null && ref.from.length == 1) {
String from = ((InternetAddress) ref.from[0]).getAddress();
for (EntityIdentity identity : data.identities)
@@ -4695,6 +4698,7 @@ public class FragmentCompose extends FragmentBase {
// Reply header
if (ref.content &&
+ !"resend".equals(action) &&
!"editasnew".equals(action) &&
!("list".equals(action) && TextUtils.isEmpty(selected_text)) &&
!"dsn".equals(action)) {
@@ -4902,7 +4906,9 @@ public class FragmentCompose extends FragmentBase {
if (ref != null &&
("reply".equals(action) || "reply_all".equals(action) ||
- "forward".equals(action) || "editasnew".equals(action))) {
+ "forward".equals(action) ||
+ "resend".equals(action) ||
+ "editasnew".equals(action))) {
List cid = new ArrayList<>();
for (Element img : document.select("img")) {
@@ -4915,8 +4921,10 @@ public class FragmentCompose extends FragmentBase {
List attachments = db.attachment().getAttachments(ref.id);
for (EntityAttachment attachment : attachments)
if (!attachment.isEncryption() &&
- ("forward".equals(action) || "editasnew".equals(action) ||
- cid.contains(attachment.cid))) {
+ (cid.contains(attachment.cid) ||
+ "forward".equals(action) ||
+ "resend".equals(action) ||
+ "editasnew".equals(action))) {
if (attachment.available) {
File source = attachment.getFile(context);
diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java
index 7bb99fed9b..044d44e338 100644
--- a/app/src/main/java/eu/faircode/email/FragmentMessages.java
+++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java
@@ -2783,11 +2783,13 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
popupMenu.getMenu().findItem(R.id.menu_reply_hard_bounce).setVisible(experiments);
popupMenu.getMenu().findItem(R.id.menu_reply_hard_bounce).setEnabled(canBounce);
popupMenu.getMenu().findItem(R.id.menu_new_message).setVisible(to != null && to.length > 0);
+ popupMenu.getMenu().findItem(R.id.menu_resend).setVisible(experiments);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !ActivityBilling.isPro(context));
popupMenu.getMenu().findItem(R.id.menu_reply_to_sender).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_forward).setEnabled(message.content);
+ popupMenu.getMenu().findItem(R.id.menu_resend).setEnabled(message.headers != null);
popupMenu.getMenu().findItem(R.id.menu_editasnew).setEnabled(message.content);
popupMenu.getMenu().findItem(R.id.menu_reply_answer).setEnabled(message.content);
@@ -2836,6 +2838,9 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
} else if (itemId == R.id.menu_forward) {
onMenuReply(message, "forward");
return true;
+ } else if (itemId == R.id.menu_resend) {
+ onMenuReply(message, "resend");
+ return true;
} else if (itemId == R.id.menu_editasnew) {
onMenuReply(message, "editasnew");
return true;
diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java
index 975136be2f..5561930640 100644
--- a/app/src/main/java/eu/faircode/email/MessageHelper.java
+++ b/app/src/main/java/eu/faircode/email/MessageHelper.java
@@ -279,17 +279,92 @@ public class MessageHelper {
imessage.addHeader(HEADER_CORRELATION_ID, message.msgid);
// Addresses
- if (message.from != null && message.from.length > 0)
- imessage.setFrom(getFrom(message, identity));
+ if (message.headers == null) {
+ if (message.from != null && message.from.length > 0)
+ imessage.setFrom(getFrom(message, identity));
+
+ if (message.to != null && message.to.length > 0)
+ imessage.setRecipients(Message.RecipientType.TO, convertAddress(message.to, identity));
+
+ if (message.cc != null && message.cc.length > 0)
+ imessage.setRecipients(Message.RecipientType.CC, convertAddress(message.cc, identity));
+
+ if (message.bcc != null && message.bcc.length > 0)
+ imessage.setRecipients(Message.RecipientType.BCC, convertAddress(message.bcc, identity));
+
+ if (identity != null && identity.replyto != null)
+ imessage.setReplyTo(convertAddress(InternetAddress.parse(identity.replyto), identity));
+
+ MailDateFormat mdf = new MailDateFormat();
+ mdf.setTimeZone(hide_timezone ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault());
+ if (message.sent != null)
+ imessage.setHeader("Date", mdf.format(new Date(message.sent)));
+ else
+ imessage.setHeader("Date", mdf.format(new Date(message.received)));
+ } else {
+ ByteArrayInputStream bis = new ByteArrayInputStream(message.headers.getBytes());
+ Enumeration headers = new InternetHeaders(bis).getAllHeaders();
+ while (headers.hasMoreElements()) {
+ Header header = headers.nextElement();
+ String name = header.getName();
+ String value = header.getValue();
+ if (name == null || value == null)
+ continue;
+
+ switch (name) {
+ case "From":
+ imessage.setFrom(value);
+ break;
+ case "To":
+ imessage.setRecipients(Message.RecipientType.TO, value);
+ break;
+ case "Cc":
+ imessage.setRecipients(Message.RecipientType.CC, value);
+ break;
+ case "Bcc":
+ imessage.setRecipients(Message.RecipientType.BCC, value);
+ break;
+ case "Reply-To":
+ imessage.setReplyTo(InternetAddress.parse(value));
+ break;
+ case "Date":
+ imessage.setHeader("Date", value);
+ break;
+ default:
+ if (name.startsWith("Resent-"))
+ imessage.addHeader(name, value);
+ }
+ }
- if (message.to != null && message.to.length > 0)
- imessage.setRecipients(Message.RecipientType.TO, convertAddress(message.to, identity));
+ if (message.from != null && message.from.length > 0)
+ imessage.addHeader("Resent-From", getFrom(message, identity).toString());
- if (message.cc != null && message.cc.length > 0)
- imessage.setRecipients(Message.RecipientType.CC, convertAddress(message.cc, identity));
+ if (message.to != null && message.to.length > 0)
+ for (Address a : convertAddress(message.to, identity))
+ imessage.addHeader("Resent-To", a.toString());
- if (message.bcc != null && message.bcc.length > 0)
- imessage.setRecipients(Message.RecipientType.BCC, convertAddress(message.bcc, identity));
+ if (message.cc != null && message.cc.length > 0)
+ for (Address a : convertAddress(message.cc, identity))
+ imessage.addHeader("Resent-Cc", a.toString());
+
+ if (message.bcc != null && message.bcc.length > 0)
+ for (Address a : convertAddress(message.bcc, identity))
+ imessage.addHeader("Resent-Bcc", a.toString());
+
+ if (identity != null && identity.replyto != null)
+ for (Address a : convertAddress(InternetAddress.parse(identity.replyto), identity))
+ imessage.addHeader("Resent-Reply-To", a.toString());
+
+ MailDateFormat mdf = new MailDateFormat();
+ mdf.setTimeZone(hide_timezone ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault());
+ if (message.sent != null)
+ imessage.addHeader("Resent-Date", mdf.format(new Date(message.sent)));
+ else
+ imessage.addHeader("Resent-Date", mdf.format(new Date(message.received)));
+
+ // Resent-Sender
+ // Resent-Message-ID
+ }
if (message.subject != null) {
int maxlen = MAX_HEADER_LENGTH - "Subject: ".length();
@@ -300,10 +375,6 @@ public class MessageHelper {
// Send message
if (identity != null) {
- // Add reply to
- if (identity.replyto != null)
- imessage.setReplyTo(convertAddress(InternetAddress.parse(identity.replyto), identity));
-
// Add extra cc
if (identity.cc != null)
addAddress(identity.cc, Message.RecipientType.CC, imessage, identity);
@@ -337,13 +408,6 @@ public class MessageHelper {
if (message.auto_submitted != null && message.auto_submitted)
imessage.addHeader("Auto-Submitted", "auto-replied");
- MailDateFormat mdf = new MailDateFormat();
- mdf.setTimeZone(hide_timezone ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault());
- if (message.sent != null)
- imessage.setHeader("Date", mdf.format(new Date(message.sent)));
- else
- imessage.setHeader("Date", mdf.format(new Date(message.received)));
-
List attachments = db.attachment().getAttachments(message.id);
if (message.from != null && message.from.length > 0)
diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java
index a13f95e770..372e12a98e 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSend.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSend.java
@@ -45,6 +45,7 @@ import com.sun.mail.smtp.SMTPSendFailedException;
import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.TraceOutputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -711,6 +712,13 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
iservice.getTransport().sendMessage(imessage, to);
end = new Date().getTime();
EntityLog.log(this, "Sent " + via + " elapse=" + (end - start) + " ms");
+
+ if (BuildConfig.DEBUG) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ imessage.writeTo(bos);
+ for (String line : bos.toString().split("\n"))
+ Log.i("MMM " + line);
+ }
} catch (MessagingException ex) {
iservice.dump();
Log.e(ex);
diff --git a/app/src/main/res/menu/popup_reply.xml b/app/src/main/res/menu/popup_reply.xml
index 346bddbdc2..05a6ccf8cd 100644
--- a/app/src/main/res/menu/popup_reply.xml
+++ b/app/src/main/res/menu/popup_reply.xml
@@ -30,6 +30,11 @@
android:icon="@drawable/twotone_forward_24"
android:title="@string/title_forward" />
+
+
- High
Search in text …
Forward
+ Resend
New message
Edit as new
Edit local notes