mirror of https://github.com/M66B/FairEmail.git
Added inserting lines
This commit is contained in:
parent
609086c9b7
commit
679c15017f
|
@ -8,6 +8,7 @@
|
|||
|
||||
* Added slider to change message column width
|
||||
* Added option for formal/informal DeepL translation
|
||||
* Added insert line to long press menu
|
||||
* Small improvements and minor bug fixes
|
||||
|
||||
### [Epidexipteryx](https://en.wikipedia.org/wiki/Epidexipteryx)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
* Added slider to change message column width
|
||||
* Added option for formal/informal DeepL translation
|
||||
* Added insert line to long press menu
|
||||
* Small improvements and minor bug fixes
|
||||
|
||||
### [Epidexipteryx](https://en.wikipedia.org/wiki/Epidexipteryx)
|
||||
|
|
|
@ -30,6 +30,7 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
|
@ -43,6 +44,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.view.inputmethod.EditorInfoCompat;
|
||||
import androidx.core.view.inputmethod.InputConnectionCompat;
|
||||
|
@ -95,6 +97,7 @@ public class EditTextCompose extends FixedEditText {
|
|||
menu.add(Menu.CATEGORY_ALTERNATIVE, R.string.title_undo, 1, getTitle(R.string.title_undo));
|
||||
if (can(android.R.id.redo))
|
||||
menu.add(Menu.CATEGORY_ALTERNATIVE, R.string.title_redo, 2, getTitle(R.string.title_redo));
|
||||
menu.add(Menu.CATEGORY_ALTERNATIVE, R.string.title_insert_line, 3, R.string.title_insert_line);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -117,6 +120,8 @@ public class EditTextCompose extends FixedEditText {
|
|||
return EditTextCompose.super.onTextContextMenuItem(android.R.id.undo);
|
||||
else if (id == R.string.title_redo)
|
||||
return EditTextCompose.super.onTextContextMenuItem(android.R.id.redo);
|
||||
else if (id == R.string.title_insert_line)
|
||||
return insertLine();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -125,6 +130,40 @@ public class EditTextCompose extends FixedEditText {
|
|||
public void onDestroyActionMode(ActionMode mode) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
private boolean insertLine() {
|
||||
try {
|
||||
int start = getSelectionStart();
|
||||
if (start < 0)
|
||||
return false;
|
||||
|
||||
Editable edit = getText();
|
||||
if (edit == null)
|
||||
return false;
|
||||
|
||||
if (start == 0 || edit.charAt(start - 1) != '\n')
|
||||
edit.insert(start++, "\n");
|
||||
if (start == edit.length() || edit.charAt(start) != '\n')
|
||||
edit.insert(start, "\n");
|
||||
|
||||
edit.insert(start, "\uFFFC"); // Object replacement character
|
||||
|
||||
int colorSeparator = Helper.resolveColor(getContext(), R.attr.colorSeparator);
|
||||
float stroke = context.getResources().getDisplayMetrics().density;
|
||||
edit.setSpan(
|
||||
new LineSpan(colorSeparator, stroke, 0f),
|
||||
start, start + 1,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
setSelection(start + 2);
|
||||
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
ToastEx.makeText(context, Log.formatThrowable(ex), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,6 +252,13 @@ public class HtmlEx {
|
|||
if (i != text.length())
|
||||
out.append("<br>\n");
|
||||
} else {
|
||||
eu.faircode.email.LineSpan[] line = text.getSpans(i, next, eu.faircode.email.LineSpan.class);
|
||||
if (line.length > 0) {
|
||||
for (int l = 0; l < line.length; l++)
|
||||
out.append("<hr>");
|
||||
continue;
|
||||
}
|
||||
|
||||
int level = 0;
|
||||
Boolean isBulletListItem = null;
|
||||
ParagraphStyle[] paragraphStyles = text.getSpans(i, next, ParagraphStyle.class);
|
||||
|
|
|
@ -1007,11 +1007,8 @@ public class HtmlHelper {
|
|||
|
||||
// Lines
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr
|
||||
if (!view)
|
||||
for (Element hr : document.select("hr")) {
|
||||
hr.tagName("div");
|
||||
hr.text(LINE);
|
||||
}
|
||||
for (Element hr : document.select("hr"))
|
||||
hr.attr("x-keep-line", "true");
|
||||
|
||||
// Descriptions
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl
|
||||
|
@ -2385,6 +2382,12 @@ public class HtmlHelper {
|
|||
}
|
||||
}
|
||||
|
||||
for (LineSpan span : ssb.getSpans(0, ssb.length(), LineSpan.class)) {
|
||||
int start = ssb.getSpanStart(span);
|
||||
int end = ssb.getSpanEnd(span);
|
||||
ssb.replace(start, end, LINE);
|
||||
}
|
||||
|
||||
return ssb.toString();
|
||||
}
|
||||
|
||||
|
@ -3001,32 +3004,34 @@ public class HtmlHelper {
|
|||
break;
|
||||
case "hr":
|
||||
// Suppress successive lines
|
||||
LineSpan[] lines = ssb.getSpans(0, ssb.length(), LineSpan.class);
|
||||
int last = -1;
|
||||
if (lines != null)
|
||||
for (LineSpan line : lines) {
|
||||
int e = ssb.getSpanEnd(line);
|
||||
if (e > last)
|
||||
last = e;
|
||||
}
|
||||
if (last >= 0) {
|
||||
boolean blank = true;
|
||||
for (int i = last; i < ssb.length(); i++) {
|
||||
char kar = ssb.charAt(i);
|
||||
if (kar != ' ' && kar != '\n' && kar != '\u00a0') {
|
||||
blank = false;
|
||||
break;
|
||||
if (!"true".equals(element.attr("x-keep-line"))) {
|
||||
LineSpan[] lines = ssb.getSpans(0, ssb.length(), LineSpan.class);
|
||||
int last = -1;
|
||||
if (lines != null)
|
||||
for (LineSpan line : lines) {
|
||||
int e = ssb.getSpanEnd(line);
|
||||
if (e > last)
|
||||
last = e;
|
||||
}
|
||||
if (last >= 0) {
|
||||
boolean blank = true;
|
||||
for (int i = last; i < ssb.length(); i++) {
|
||||
char kar = ssb.charAt(i);
|
||||
if (kar != ' ' && kar != '\n' && kar != '\u00a0') {
|
||||
blank = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blank)
|
||||
break;
|
||||
if (blank)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean dashed = "true".equals(element.attr("x-dashed"));
|
||||
float stroke = context.getResources().getDisplayMetrics().density;
|
||||
float dash = (dashed ? line_dash_length : 0f);
|
||||
ssb.append(LINE);
|
||||
ssb.append("\uFFFC"); // Object replacement character
|
||||
setSpan(ssb, new LineSpan(colorSeparator, stroke, dash), start, ssb.length());
|
||||
break;
|
||||
case "img":
|
||||
|
@ -3264,7 +3269,8 @@ public class HtmlHelper {
|
|||
.removeAttr("x-tracking")
|
||||
.removeAttr("x-border")
|
||||
.removeAttr("x-list-style")
|
||||
.removeAttr("x-plain");
|
||||
.removeAttr("x-plain")
|
||||
.remove("x-keep-line");
|
||||
}
|
||||
|
||||
static Spanned fromHtml(@NonNull String html, Context context) {
|
||||
|
@ -3358,6 +3364,12 @@ public class HtmlHelper {
|
|||
last.remove();
|
||||
}
|
||||
|
||||
for (Element line : doc.select("hr")) {
|
||||
Element next = line.nextElementSibling();
|
||||
if (next != null && "br".equals(next.tagName()))
|
||||
next.remove();
|
||||
}
|
||||
|
||||
return doc.html();
|
||||
}
|
||||
|
||||
|
|
|
@ -1736,6 +1736,7 @@
|
|||
<string name="title_later">Later</string>
|
||||
<string name="title_undo">Undo</string>
|
||||
<string name="title_redo">Redo</string>
|
||||
<string name="title_insert_line">Insert line</string>
|
||||
<string name="title_add">Add</string>
|
||||
<string name="title_browse">Open with</string>
|
||||
<string name="title_info">Info</string>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
* Added slider to change message column width
|
||||
* Added option for formal/informal DeepL translation
|
||||
* Added insert line to long press menu
|
||||
* Small improvements and minor bug fixes
|
||||
|
||||
### [Epidexipteryx](https://en.wikipedia.org/wiki/Epidexipteryx)
|
||||
|
|
Loading…
Reference in New Issue