From c1d2748d442f06a7266be04b9e9c7d20609ad5cc Mon Sep 17 00:00:00 2001 From: Daisuke Miyakawa Date: Mon, 25 May 2009 17:37:41 +0900 Subject: [PATCH] Manual merge from cupcake_dcm. Need to be reviewed by enf. --- core/java/android/text/LoginFilter.java | 41 +++++++++---------- core/java/android/text/TextUtils.java | 11 +++++ .../android/widget/AutoCompleteTextView.java | 2 + .../widget/MultiAutoCompleteTextView.java | 2 + 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/core/java/android/text/LoginFilter.java b/core/java/android/text/LoginFilter.java index 27c703f1f083a..9045c09fb6600 100644 --- a/core/java/android/text/LoginFilter.java +++ b/core/java/android/text/LoginFilter.java @@ -49,10 +49,6 @@ public abstract class LoginFilter implements InputFilter { */ public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { - char[] out = new char[end - start]; // reserve enough space for whole string - int outidx = 0; - boolean changed = false; - onStart(); // Scan through beginning characters in dest, calling onInvalidCharacter() @@ -63,14 +59,26 @@ public abstract class LoginFilter implements InputFilter { } // Scan through changed characters rejecting disallowed chars + SpannableStringBuilder modification = null; + int modoff = 0; + for (int i = start; i < end; i++) { char c = source.charAt(i); if (isAllowed(c)) { - // Character allowed. Add it to the sequence. - out[outidx++] = c; + // Character allowed. + modoff++; } else { - if (mAppendInvalid) out[outidx++] = c; - else changed = true; // we changed the original string + if (mAppendInvalid) { + modoff++; + } else { + if (modification == null) { + modification = new SpannableStringBuilder(source, start, end); + modoff = i - start; + } + + modification.delete(modoff, modoff + 1); + } + onInvalidCharacter(c); } } @@ -84,20 +92,9 @@ public abstract class LoginFilter implements InputFilter { onStop(); - if (!changed) { - return null; - } - - String s = new String(out, 0, outidx); - - if (source instanceof Spanned) { - SpannableString sp = new SpannableString(s); - TextUtils.copySpansFrom((Spanned) source, - start, end, null, sp, 0); - return sp; - } else { - return s; - } + // Either returns null if we made no changes, + // or what we wanted to change it to if there were changes. + return modification; } /** diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 5b4c3802b3ceb..53096dddefb59 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -916,6 +916,17 @@ public class TextUtils { sp.setSpan(o, p.readInt(), p.readInt(), p.readInt()); } + /** + * Copies the spans from the region start...end in + * source to the region + * destoff...destoff+end-start in dest. + * Spans in source that begin before start + * or end after end but overlap this range are trimmed + * as if they began at start or ended at end. + * + * @throws IndexOutOfBoundsException if any of the copied spans + * are out of range in dest. + */ public static void copySpansFrom(Spanned source, int start, int end, Class kind, Spannable dest, int destoff) { diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index a1d16eadc0d83..f376ce5ae1076 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -950,6 +950,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe * @param text the selected suggestion in the drop down list */ protected void replaceText(CharSequence text) { + clearComposingText(); + setText(text); // make sure we keep the caret at the end of the text view Editable spannable = getText(); diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java index 05abc2661eb2b..ae8027784bc38 100644 --- a/core/java/android/widget/MultiAutoCompleteTextView.java +++ b/core/java/android/widget/MultiAutoCompleteTextView.java @@ -195,6 +195,8 @@ public class MultiAutoCompleteTextView extends AutoCompleteTextView { */ @Override protected void replaceText(CharSequence text) { + clearComposingText(); + int end = getSelectionEnd(); int start = mTokenizer.findTokenStart(getText(), end);