Chip focus/selection

pull/194/merge
M66B 4 years ago
parent a186451a51
commit ab54ad4688

@ -21,12 +21,12 @@ package eu.faircode.email;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
@ -104,12 +104,10 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
ctx = new ContextThemeWrapper(context, dark ? R.style.ChipDark : R.style.ChipLight); ctx = new ContextThemeWrapper(context, dark ? R.style.ChipDark : R.style.ChipLight);
addTextChangedListener(new TextWatcher() { addTextChangedListener(new TextWatcher() {
private boolean init;
private Integer backspace = null; private Integer backspace = null;
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { public void beforeTextChanged(CharSequence s, int start, int count, int after) {
init = (s.length() == 0 && after > 0);
backspace = (count - after == 1 ? start : null); backspace = (count - after == 1 ? start : null);
} }
@ -120,8 +118,6 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
@Override @Override
public void afterTextChanged(Editable edit) { public void afterTextChanged(Editable edit) {
if (init)
setSelection(edit.length());
if (backspace != null) { if (backspace != null) {
ClipImageSpan[] spans = edit.getSpans(backspace, backspace, ClipImageSpan.class); ClipImageSpan[] spans = edit.getSpans(backspace, backspace, ClipImageSpan.class);
if (spans.length == 1) { if (spans.length == 1) {
@ -140,14 +136,14 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
} }
@Override @Override
protected void onSelectionChanged(int start, int end) { protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onSelectionChanged(start, end); super.onFocusChanged(focused, direction, previouslyFocusedRect);
post(update);
final Editable edit = getText(); }
ClipImageSpan[] spans = edit.getSpans(start, end - 1, ClipImageSpan.class);
for (ClipImageSpan span : spans)
edit.removeSpan(span);
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);
post(update); post(update);
} }
@ -336,34 +332,44 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
final Editable edit = getText(); final Editable edit = getText();
final boolean send_chips = prefs.getBoolean("send_chips", false); final boolean send_chips = prefs.getBoolean("send_chips", false);
final boolean focus = hasFocus();
final int selStart = getSelectionStart();
final int selEnd = getSelectionEnd();
boolean added = false; boolean added = false;
int selstart = getSelectionStart(); List<ClipImageSpan> tbd = new ArrayList<>();
int selend = getSelectionEnd(); tbd.addAll(Arrays.asList(edit.getSpans(0, edit.length(), ClipImageSpan.class)));
List<ClipImageSpan> spans = new ArrayList<>();
spans.addAll(Arrays.asList(edit.getSpans(0, edit.length(), ClipImageSpan.class)));
if (send_chips) { if (send_chips) {
boolean quote = false;
int start = 0; int start = 0;
boolean space = true;
boolean quote = false;
for (int i = 0; i < edit.length(); i++) { for (int i = 0; i < edit.length(); i++) {
char kar = edit.charAt(i); char kar = edit.charAt(i);
if (space && kar == ' ') {
start++;
continue;
}
space = false;
if (kar == '"') if (kar == '"')
quote = !quote; quote = !quote;
else if (kar == ',' && !quote) { else if (kar == ',' && !quote) {
boolean found = false; boolean found = false;
for (ClipImageSpan span : new ArrayList<>(spans)) { for (ClipImageSpan span : new ArrayList<>(tbd)) {
int s = edit.getSpanStart(span); int s = edit.getSpanStart(span);
int e = edit.getSpanEnd(span); int e = edit.getSpanEnd(span);
if (s == start && e == i + 1) { if (s == start && e == i + 1) {
found = true; found = true;
spans.remove(span); if (!(focus && overlap(start, i, selStart, selEnd)))
tbd.remove(span);
break; break;
} }
} }
if (!found && start < i + 1 && if (!found && start < i + 1 &&
!(selstart >= start && selstart < i + 1) && !(focus && overlap(start, i, selStart, selEnd))) {
!(selend >= start && selend < i + 1)) {
String email = edit.subSequence(start, i + 1).toString(); String email = edit.subSequence(start, i + 1).toString();
InternetAddress[] parsed; InternetAddress[] parsed;
try { try {
@ -403,18 +409,16 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
} }
} }
if (i + 1 < edit.length() && edit.charAt(i + 1) == ' ')
start = i + 2;
else
start = i + 1; start = i + 1;
space = true;
} }
} }
} }
for (ClipImageSpan span : spans) for (ClipImageSpan span : tbd)
edit.removeSpan(span); edit.removeSpan(span);
if (spans.size() > 0 || added) if (tbd.size() > 0 || added)
invalidate(); invalidate();
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); Log.e(ex);
@ -422,6 +426,10 @@ public class EditTextMultiAutoComplete extends AppCompatMultiAutoCompleteTextVie
} }
}; };
private static boolean overlap(int start, int end, int selStart, int selEnd) {
return Math.max(start, selStart) <= Math.min(end, selEnd);
}
private static class ClipImageSpan extends ImageSpan { private static class ClipImageSpan extends ImageSpan {
public ClipImageSpan(@NonNull Drawable drawable) { public ClipImageSpan(@NonNull Drawable drawable) {
super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM); super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM);

Loading…
Cancel
Save