mirror of https://github.com/M66B/FairEmail.git
Prepare extended styling
This commit is contained in:
parent
720ed20fc4
commit
6cc653ce77
|
@ -53,7 +53,6 @@ import android.provider.ContactsContract;
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.Spannable;
|
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
@ -65,6 +64,7 @@ import android.text.style.StyleSpan;
|
||||||
import android.text.style.URLSpan;
|
import android.text.style.URLSpan;
|
||||||
import android.text.style.UnderlineSpan;
|
import android.text.style.UnderlineSpan;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
import android.view.ActionMode;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
@ -341,6 +341,92 @@ public class FragmentCompose extends FragmentBase {
|
||||||
|
|
||||||
setZoom();
|
setZoom();
|
||||||
|
|
||||||
|
etBody.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
|
||||||
|
@Override
|
||||||
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
|
menu.add(1, R.string.title_style_bold, 1, R.string.title_style_bold).setIcon(R.drawable.baseline_format_bold_24);
|
||||||
|
menu.add(1, R.string.title_style_italic, 1, R.string.title_style_italic).setIcon(R.drawable.baseline_format_italic_24);
|
||||||
|
menu.add(1, R.string.title_style_underline, 1, R.string.title_style_underline).setIcon(R.drawable.baseline_format_underlined_24);
|
||||||
|
menu.add(1, R.string.title_style_size, 1, R.string.title_style_size).setIcon(R.drawable.baseline_format_size_24);
|
||||||
|
menu.add(1, R.string.title_style_color, 1, R.string.title_style_color).setIcon(R.drawable.baseline_format_color_text_24);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
|
Log.i("Action=" + item.getGroupId() + ":" + item.getItemId());
|
||||||
|
|
||||||
|
if (item.getGroupId() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int s = etBody.getSelectionStart();
|
||||||
|
int e = etBody.getSelectionEnd();
|
||||||
|
|
||||||
|
if (s < 0)
|
||||||
|
s = 0;
|
||||||
|
if (e < 0)
|
||||||
|
e = 0;
|
||||||
|
|
||||||
|
if (s > e) {
|
||||||
|
int tmp = s;
|
||||||
|
s = e;
|
||||||
|
e = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int start = s;
|
||||||
|
final int end = e;
|
||||||
|
|
||||||
|
final SpannableString ss = new SpannableString(etBody.getText());
|
||||||
|
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.string.title_style_bold:
|
||||||
|
case R.string.title_style_italic: {
|
||||||
|
int style = (item.getItemId() == R.string.title_style_bold ? Typeface.BOLD : Typeface.ITALIC);
|
||||||
|
boolean has = false;
|
||||||
|
for (StyleSpan span : ss.getSpans(start, end, StyleSpan.class))
|
||||||
|
if (span.getStyle() == style) {
|
||||||
|
has = true;
|
||||||
|
ss.removeSpan(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has)
|
||||||
|
ss.setSpan(new StyleSpan(style), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
etBody.setText(ss);
|
||||||
|
etBody.setSelection(end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case R.string.title_style_underline: {
|
||||||
|
boolean has = false;
|
||||||
|
for (UnderlineSpan span : ss.getSpans(start, end, UnderlineSpan.class)) {
|
||||||
|
has = true;
|
||||||
|
ss.removeSpan(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has)
|
||||||
|
ss.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
etBody.setText(ss);
|
||||||
|
etBody.setSelection(end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyActionMode(ActionMode mode) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ibReferenceEdit.setOnClickListener(new View.OnClickListener() {
|
ibReferenceEdit.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -364,8 +450,6 @@ public class FragmentCompose extends FragmentBase {
|
||||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||||
int action = item.getItemId();
|
int action = item.getItemId();
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case R.id.menu_bold:
|
|
||||||
case R.id.menu_italic:
|
|
||||||
case R.id.menu_clear:
|
case R.id.menu_clear:
|
||||||
case R.id.menu_link:
|
case R.id.menu_link:
|
||||||
onMenuStyle(item.getItemId());
|
onMenuStyle(item.getItemId());
|
||||||
|
@ -917,23 +1001,6 @@ public class FragmentCompose extends FragmentBase {
|
||||||
final SpannableString ss = new SpannableString(etBody.getText());
|
final SpannableString ss = new SpannableString(etBody.getText());
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case R.id.menu_bold:
|
|
||||||
case R.id.menu_italic:
|
|
||||||
if (start == end)
|
|
||||||
Snackbar.make(view, R.string.title_no_selection, Snackbar.LENGTH_LONG).show();
|
|
||||||
else {
|
|
||||||
int style = (id == R.id.menu_bold ? Typeface.BOLD : Typeface.ITALIC);
|
|
||||||
boolean has = false;
|
|
||||||
for (StyleSpan span : ss.getSpans(start, end, StyleSpan.class))
|
|
||||||
if (span.getStyle() == style) {
|
|
||||||
has = true;
|
|
||||||
ss.removeSpan(span);
|
|
||||||
}
|
|
||||||
if (!has)
|
|
||||||
ss.setSpan(new StyleSpan(style), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R.id.menu_clear:
|
case R.id.menu_clear:
|
||||||
for (Object span : ss.getSpans(0, ss.length(), Object.class))
|
for (Object span : ss.getSpans(0, ss.length(), Object.class))
|
||||||
if (!(span instanceof ImageSpan))
|
if (!(span instanceof ImageSpan))
|
||||||
|
@ -1735,10 +1802,7 @@ public class FragmentCompose extends FragmentBase {
|
||||||
EntityIdentity identity = (EntityIdentity) spIdentity.getSelectedItem();
|
EntityIdentity identity = (EntityIdentity) spIdentity.getSelectedItem();
|
||||||
|
|
||||||
// Workaround underlines left by Android
|
// Workaround underlines left by Android
|
||||||
Spannable spannable = etBody.getText();
|
etBody.clearComposingText();
|
||||||
UnderlineSpan[] uspans = spannable.getSpans(0, spannable.length(), UnderlineSpan.class);
|
|
||||||
for (UnderlineSpan uspan : uspans)
|
|
||||||
spannable.removeSpan(uspan);
|
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putLong("id", working);
|
args.putLong("id", working);
|
||||||
|
@ -1750,7 +1814,7 @@ public class FragmentCompose extends FragmentBase {
|
||||||
args.putString("cc", etCc.getText().toString().trim());
|
args.putString("cc", etCc.getText().toString().trim());
|
||||||
args.putString("bcc", etBcc.getText().toString().trim());
|
args.putString("bcc", etBcc.getText().toString().trim());
|
||||||
args.putString("subject", etSubject.getText().toString().trim());
|
args.putString("subject", etSubject.getText().toString().trim());
|
||||||
args.putString("body", HtmlHelper.toHtml(spannable));
|
args.putString("body", HtmlHelper.toHtml(etBody.getText()));
|
||||||
args.putBoolean("empty", isEmpty());
|
args.putBoolean("empty", isEmpty());
|
||||||
|
|
||||||
Log.i("Run execute id=" + working);
|
Log.i("Run execute id=" + working);
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M0,20h24v4H0z"
|
||||||
|
android:fillAlpha=".36"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M11,3L5.5,17h2.25l1.12,-3h6.25l1.12,3h2.25L13,3h-2zM9.62,12L12,5.67 14.38,12L9.62,12z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,17c3.31,0 6,-2.69 6,-6L18,3h-2.5v8c0,1.93 -1.57,3.5 -3.5,3.5S8.5,12.93 8.5,11L8.5,3L6,3v8c0,3.31 2.69,6 6,6zM5,19v2h14v-2L5,19z"/>
|
||||||
|
</vector>
|
|
@ -1,15 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item
|
|
||||||
android:id="@+id/menu_bold"
|
|
||||||
android:icon="@drawable/baseline_format_bold_24"
|
|
||||||
android:title="@string/title_style_bold" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_italic"
|
|
||||||
android:icon="@drawable/baseline_format_italic_24"
|
|
||||||
android:title="@string/title_style_italic" />
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_link"
|
android:id="@+id/menu_link"
|
||||||
android:icon="@drawable/baseline_insert_link_24"
|
android:icon="@drawable/baseline_insert_link_24"
|
||||||
|
|
|
@ -436,6 +436,9 @@
|
||||||
<string name="title_no_selection">Nothing selected</string>
|
<string name="title_no_selection">Nothing selected</string>
|
||||||
<string name="title_style_bold">Bold</string>
|
<string name="title_style_bold">Bold</string>
|
||||||
<string name="title_style_italic">Italic</string>
|
<string name="title_style_italic">Italic</string>
|
||||||
|
<string name="title_style_underline">Underline</string>
|
||||||
|
<string name="title_style_size">Size</string>
|
||||||
|
<string name="title_style_color">Color</string>
|
||||||
<string name="title_style_clear">Clear formatting</string>
|
<string name="title_style_clear">Clear formatting</string>
|
||||||
<string name="title_style_link">Insert link</string>
|
<string name="title_style_link">Insert link</string>
|
||||||
<string name="title_style_image">Insert image</string>
|
<string name="title_style_image">Insert image</string>
|
||||||
|
|
Loading…
Reference in New Issue