diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java b/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java
index f7ce36b861..789205542c 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java
@@ -51,6 +51,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
private SwitchCompat swExtendedReply;
private SwitchCompat swQuoteReply;
private SwitchCompat swPlainOnly;
+ private SwitchCompat swFormatFlowed;
private Spinner spSignatureLocation;
private SwitchCompat swUsenetSignature;
private SwitchCompat swRemoveSignatures;
@@ -67,7 +68,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
private final static String[] RESET_OPTIONS = new String[]{
"keyboard", "suggest_sent", "suggested_received",
"prefix_once", "extended_reply", "quote_reply",
- "plain_only", "signature_location", "usenet_signature", "remove_signatures",
+ "plain_only", "format_flowed", "signature_location", "usenet_signature", "remove_signatures",
"resize_images", "resize_attachments", "resize",
"send_reminders", "receipt_default", "receipt_type", "lookup_mx", "send_delayed"
};
@@ -90,6 +91,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
swExtendedReply = view.findViewById(R.id.swExtendedReply);
swQuoteReply = view.findViewById(R.id.swQuoteReply);
swPlainOnly = view.findViewById(R.id.swPlainOnly);
+ swFormatFlowed = view.findViewById(R.id.swFormatFlowed);
spSignatureLocation = view.findViewById(R.id.spSignatureLocation);
swUsenetSignature = view.findViewById(R.id.swUsenetSignature);
swRemoveSignatures = view.findViewById(R.id.swRemoveSignatures);
@@ -166,6 +168,13 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
}
});
+ swFormatFlowed.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("format_flowed", checked).apply();
+ }
+ });
+
spSignatureLocation.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> adapterView, View view, int position, long id) {
@@ -321,6 +330,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
swExtendedReply.setChecked(prefs.getBoolean("extended_reply", false));
swQuoteReply.setChecked(prefs.getBoolean("quote_reply", true));
swPlainOnly.setChecked(prefs.getBoolean("plain_only", false));
+ swFormatFlowed.setChecked(prefs.getBoolean("format_flowed", false));
int signature_location = prefs.getInt("signature_location", 1);
spSignatureLocation.setSelection(signature_location);
diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java
index 18f09d5587..644d36d01a 100644
--- a/app/src/main/java/eu/faircode/email/MessageHelper.java
+++ b/app/src/main/java/eu/faircode/email/MessageHelper.java
@@ -103,6 +103,7 @@ public class MessageHelper {
static final int MAX_MESSAGE_SIZE = 10 * 1024 * 1024; // bytes
static final int DEFAULT_ATTACHMENT_DOWNLOAD_SIZE = 256 * 1024; // bytes
static final long ATTACHMENT_PROGRESS_UPDATE = 1500L; // milliseconds
+ static final int FORMAT_FLOWED_LINE_LENGTH = 72;
// https://tools.ietf.org/html/rfc4021
@@ -569,6 +570,9 @@ public class MessageHelper {
}
}
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean format_flowed = prefs.getBoolean("format_flowed", false);
+
// multipart/mixed
// multipart/related
// multipart/alternative
@@ -578,13 +582,40 @@ public class MessageHelper {
// attachments
String htmlContent = document.html();
+ String htmlContentType = "text/html; charset=" + Charset.defaultCharset().name();
+
String plainContent = HtmlHelper.getText(htmlContent);
+ String plainContentType = "text/plain; charset=" + Charset.defaultCharset().name();
+
+ if (format_flowed) {
+ List flowed = new ArrayList<>();
+ for (String line : plainContent.split("\\r?\\n")) {
+ if (line.contains(" ")) {
+ StringBuffer sb = new StringBuffer();
+ for (String word : line.split(" ")) {
+ if (sb.length() + word.length() > FORMAT_FLOWED_LINE_LENGTH) {
+ sb.append(' ');
+ flowed.add(sb.toString());
+ sb = new StringBuffer();
+ }
+ if (sb.length() > 0)
+ sb.append(' ');
+ sb.append(word);
+ }
+ if (sb.length() > 0)
+ flowed.add(sb.toString());
+ } else
+ flowed.add(line);
+ }
+ plainContent = TextUtils.join("\r\n", flowed);
+ plainContentType += "; format=flowed";
+ }
BodyPart plainPart = new MimeBodyPart();
- plainPart.setContent(plainContent, "text/plain; charset=" + Charset.defaultCharset().name());
+ plainPart.setContent(plainContent, plainContentType);
BodyPart htmlPart = new MimeBodyPart();
- htmlPart.setContent(htmlContent, "text/html; charset=" + Charset.defaultCharset().name());
+ htmlPart.setContent(htmlContent, htmlContentType);
Multipart altMultiPart = new MimeMultipart("alternative");
altMultiPart.addBodyPart(plainPart);
@@ -601,7 +632,7 @@ public class MessageHelper {
if (availableAttachments == 0)
if (message.plain_only != null && message.plain_only)
- imessage.setContent(plainContent, "text/plain; charset=" + Charset.defaultCharset().name());
+ imessage.setContent(plainContent, plainContentType);
else
imessage.setContent(altMultiPart);
else {
diff --git a/app/src/main/res/layout/fragment_options_send.xml b/app/src/main/res/layout/fragment_options_send.xml
index cd5445b9ed..aec951a95c 100644
--- a/app/src/main/res/layout/fragment_options_send.xml
+++ b/app/src/main/res/layout/fragment_options_send.xml
@@ -134,6 +134,17 @@
app:layout_constraintTop_toBottomOf="@id/swQuoteReply"
app:switchPadding="12dp" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/swFormatFlowed" />
Signature position
Add signature after quoted/forwarded message
Send plain text only by default
+ \'format flowed\' for plain text
When requesting a receipt
Usenet signature convention
Remove recognized signatures