Loading core/java/android/text/style/SuggestionSpan.java +7 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.SystemClock; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import java.util.Arrays; Loading Loading @@ -114,7 +115,7 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { * @param context Context for the application * @param locale locale Locale of the suggestions * @param suggestions Suggestions for the string under the span. Only the first up to * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. Null values not permitted. * @param flags Additional flags indicating how this span is handled in TextView * @param notificationTargetClass if not null, this class will get notified when the user * selects one of the suggestions. Loading @@ -124,10 +125,13 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length); mSuggestions = Arrays.copyOf(suggestions, N); mFlags = flags; if (context != null && locale == null) { if (locale != null) { mLocaleString = locale.toString(); } else if (context != null) { mLocaleString = context.getResources().getConfiguration().locale.toString(); } else { mLocaleString = locale.toString(); Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor"); mLocaleString = ""; } if (notificationTargetClass != null) { Loading core/java/android/widget/SpellChecker.java +5 −46 Original line number Diff line number Diff line Loading @@ -342,56 +342,15 @@ public class SpellChecker implements SpellCheckerSessionListener { final int end = editable.getSpanEnd(spellCheckSpan); if (start < 0 || end <= start) return; // span was removed in the meantime // Other suggestion spans may exist on that region, with identical suggestions, filter // them out to avoid duplicates. SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class); final int length = suggestionSpans.length; for (int i = 0; i < length; i++) { final int spanStart = editable.getSpanStart(suggestionSpans[i]); final int spanEnd = editable.getSpanEnd(suggestionSpans[i]); if (spanStart != start || spanEnd != end) { // Nulled (to avoid new array allocation) if not on that exact same region suggestionSpans[i] = null; } } final int suggestionsCount = suggestionsInfo.getSuggestionsCount(); String[] suggestions; if (suggestionsCount <= 0) { // A negative suggestion count is possible suggestions = ArrayUtils.emptyArray(String.class); } else { int numberOfSuggestions = 0; suggestions = new String[suggestionsCount]; for (int i = 0; i < suggestionsCount; i++) { final String spellSuggestion = suggestionsInfo.getSuggestionAt(i); if (spellSuggestion == null) break; boolean suggestionFound = false; for (int j = 0; j < length && !suggestionFound; j++) { if (suggestionSpans[j] == null) break; String[] suggests = suggestionSpans[j].getSuggestions(); for (int k = 0; k < suggests.length; k++) { if (spellSuggestion.equals(suggests[k])) { // The suggestion is already provided by an other SuggestionSpan suggestionFound = true; break; } } } if (!suggestionFound) { suggestions[numberOfSuggestions++] = spellSuggestion; } return; } if (numberOfSuggestions != suggestionsCount) { String[] newSuggestions = new String[numberOfSuggestions]; System.arraycopy(suggestions, 0, newSuggestions, 0, numberOfSuggestions); suggestions = newSuggestions; } String[] suggestions = new String[suggestionsCount]; for (int i = 0; i < suggestionsCount; i++) { suggestions[i] = suggestionsInfo.getSuggestionAt(i); } SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions, Loading core/java/android/widget/TextView.java +31 −13 Original line number Diff line number Diff line Loading @@ -9844,13 +9844,29 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener String[] suggestions = suggestionSpan.getSuggestions(); int nbSuggestions = suggestions.length; for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) { String suggestion = suggestions[suggestionIndex]; boolean suggestionIsDuplicate = false; for (int i = 0; i < mNumberOfSuggestions; i++) { if (mSuggestionInfos[i].text.toString().equals(suggestion)) { SuggestionSpan otherSuggestionSpan = mSuggestionInfos[i].suggestionSpan; final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan); final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan); if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) { suggestionIsDuplicate = true; break; } } } if (!suggestionIsDuplicate) { SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions]; suggestionInfo.suggestionSpan = suggestionSpan; suggestionInfo.suggestionIndex = suggestionIndex; suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestions[suggestionIndex]); suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestion); mNumberOfSuggestions++; if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) { // Also end outer for loop spanIndex = nbSpans; Loading @@ -9858,12 +9874,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } } for (int i = 0; i < mNumberOfSuggestions; i++) { highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd); } // Add to dictionary item if there is a span with the misspelled flag // Add "Add to dictionary" item if there is a span with the misspelled flag if (misspelledSpan != null) { final int misspelledStart = spannable.getSpanStart(misspelledSpan); final int misspelledEnd = spannable.getSpanEnd(misspelledSpan); Loading Loading @@ -9921,8 +9938,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // Add the text before and after the span. suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart)); suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd)); final String textAsString = text.toString(); suggestionInfo.text.insert(0, textAsString.substring(unionStart, spanStart)); suggestionInfo.text.append(textAsString.substring(spanEnd, unionEnd)); } @Override Loading Loading
core/java/android/text/style/SuggestionSpan.java +7 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.os.SystemClock; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import java.util.Arrays; Loading Loading @@ -114,7 +115,7 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { * @param context Context for the application * @param locale locale Locale of the suggestions * @param suggestions Suggestions for the string under the span. Only the first up to * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. Null values not permitted. * @param flags Additional flags indicating how this span is handled in TextView * @param notificationTargetClass if not null, this class will get notified when the user * selects one of the suggestions. Loading @@ -124,10 +125,13 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length); mSuggestions = Arrays.copyOf(suggestions, N); mFlags = flags; if (context != null && locale == null) { if (locale != null) { mLocaleString = locale.toString(); } else if (context != null) { mLocaleString = context.getResources().getConfiguration().locale.toString(); } else { mLocaleString = locale.toString(); Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor"); mLocaleString = ""; } if (notificationTargetClass != null) { Loading
core/java/android/widget/SpellChecker.java +5 −46 Original line number Diff line number Diff line Loading @@ -342,56 +342,15 @@ public class SpellChecker implements SpellCheckerSessionListener { final int end = editable.getSpanEnd(spellCheckSpan); if (start < 0 || end <= start) return; // span was removed in the meantime // Other suggestion spans may exist on that region, with identical suggestions, filter // them out to avoid duplicates. SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class); final int length = suggestionSpans.length; for (int i = 0; i < length; i++) { final int spanStart = editable.getSpanStart(suggestionSpans[i]); final int spanEnd = editable.getSpanEnd(suggestionSpans[i]); if (spanStart != start || spanEnd != end) { // Nulled (to avoid new array allocation) if not on that exact same region suggestionSpans[i] = null; } } final int suggestionsCount = suggestionsInfo.getSuggestionsCount(); String[] suggestions; if (suggestionsCount <= 0) { // A negative suggestion count is possible suggestions = ArrayUtils.emptyArray(String.class); } else { int numberOfSuggestions = 0; suggestions = new String[suggestionsCount]; for (int i = 0; i < suggestionsCount; i++) { final String spellSuggestion = suggestionsInfo.getSuggestionAt(i); if (spellSuggestion == null) break; boolean suggestionFound = false; for (int j = 0; j < length && !suggestionFound; j++) { if (suggestionSpans[j] == null) break; String[] suggests = suggestionSpans[j].getSuggestions(); for (int k = 0; k < suggests.length; k++) { if (spellSuggestion.equals(suggests[k])) { // The suggestion is already provided by an other SuggestionSpan suggestionFound = true; break; } } } if (!suggestionFound) { suggestions[numberOfSuggestions++] = spellSuggestion; } return; } if (numberOfSuggestions != suggestionsCount) { String[] newSuggestions = new String[numberOfSuggestions]; System.arraycopy(suggestions, 0, newSuggestions, 0, numberOfSuggestions); suggestions = newSuggestions; } String[] suggestions = new String[suggestionsCount]; for (int i = 0; i < suggestionsCount; i++) { suggestions[i] = suggestionsInfo.getSuggestionAt(i); } SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions, Loading
core/java/android/widget/TextView.java +31 −13 Original line number Diff line number Diff line Loading @@ -9844,13 +9844,29 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener String[] suggestions = suggestionSpan.getSuggestions(); int nbSuggestions = suggestions.length; for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) { String suggestion = suggestions[suggestionIndex]; boolean suggestionIsDuplicate = false; for (int i = 0; i < mNumberOfSuggestions; i++) { if (mSuggestionInfos[i].text.toString().equals(suggestion)) { SuggestionSpan otherSuggestionSpan = mSuggestionInfos[i].suggestionSpan; final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan); final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan); if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) { suggestionIsDuplicate = true; break; } } } if (!suggestionIsDuplicate) { SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions]; suggestionInfo.suggestionSpan = suggestionSpan; suggestionInfo.suggestionIndex = suggestionIndex; suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestions[suggestionIndex]); suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestion); mNumberOfSuggestions++; if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) { // Also end outer for loop spanIndex = nbSpans; Loading @@ -9858,12 +9874,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } } for (int i = 0; i < mNumberOfSuggestions; i++) { highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd); } // Add to dictionary item if there is a span with the misspelled flag // Add "Add to dictionary" item if there is a span with the misspelled flag if (misspelledSpan != null) { final int misspelledStart = spannable.getSpanStart(misspelledSpan); final int misspelledEnd = spannable.getSpanEnd(misspelledSpan); Loading Loading @@ -9921,8 +9938,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // Add the text before and after the span. suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart)); suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd)); final String textAsString = text.toString(); suggestionInfo.text.insert(0, textAsString.substring(unionStart, spanStart)); suggestionInfo.text.append(textAsString.substring(spanEnd, unionEnd)); } @Override Loading