Loading core/java/android/widget/SpellChecker.java +14 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ public class SpellChecker implements SpellCheckerSessionListener { mLength = 0; } /** * @return true if a spell checker session has successfully been created. Returns false if not, * for instance when spell checking has been disabled in settings. */ public boolean isSessionActive() { return mSpellCheckerSession != null; } public void closeSession() { if (mSpellCheckerSession != null) { mSpellCheckerSession.close(); } } public void addSpellCheckSpan(SpellCheckSpan spellCheckSpan) { int length = mIds.length; if (mLength >= length) { Loading core/java/android/widget/TextView.java +51 −18 Original line number Diff line number Diff line Loading @@ -3250,7 +3250,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener sendOnTextChanged(text, 0, oldlen, textLength); onTextChanged(text, 0, oldlen, textLength); if (startSpellCheck) { if (startSpellCheck && getSpellChecker().isSessionActive()) { updateSpellCheckSpans(0, textLength); } Loading Loading @@ -7599,10 +7599,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener sendOnTextChanged(buffer, start, before, after); onTextChanged(buffer, start, before, after); if (getSpellChecker().isSessionActive()) { // The WordIterator text change listener may be called after this one. // Make sure this changed text is rescanned before the iterator is used on it. getWordIterator().forceUpdate(); updateSpellCheckSpans(start, start + after); } // Hide the controllers if the amount of content changed if (before != after) { Loading Loading @@ -8254,6 +8256,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mBlink.uncancel(); makeBlink(); } if (getSpellChecker().isSessionActive() && (mSuggestionsPopupWindow == null || !mSuggestionsPopupWindow.mSuggestionPopupWindowVisible)) { updateSpellCheckSpans(0, mText.length()); } } else { if (mBlink != null) { mBlink.cancel(); Loading @@ -8265,6 +8271,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } hideControllers(); if (mSpellChecker != null && (mSuggestionsPopupWindow == null || !mSuggestionsPopupWindow.mSuggestionPopupWindowVisible)) { mSpellChecker.closeSession(); removeMisspelledSpans(); // Forces the creation of a new SpellChecker next time this window if focused. // Will handle the cases where the service has been enabled or disabled in // settings in the meantime. mSpellChecker = null; } } startStopMarquee(hasWindowFocus); Loading Loading @@ -8427,13 +8443,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int flags = suggestionSpans[i].getFlags(); if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0 && (flags & SuggestionSpan.FLAG_MISSPELLED) == 0) { flags = flags & ~SuggestionSpan.FLAG_EASY_CORRECT; flags &= ~SuggestionSpan.FLAG_EASY_CORRECT; suggestionSpans[i].setFlags(flags); } } } } /** * Removes the suggestion spans for misspelled words. */ private void removeMisspelledSpans() { if (mText instanceof Spannable) { Spannable spannable = (Spannable) mText; SuggestionSpan[] suggestionSpans = spannable.getSpans(0, spannable.length(), SuggestionSpan.class); for (int i = 0; i < suggestionSpans.length; i++) { int flags = suggestionSpans[i].getFlags(); if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0 && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) { spannable.removeSpan(suggestionSpans[i]); } } } } @Override public boolean onGenericMotionEvent(MotionEvent event) { if (mMovement != null && mText instanceof Spannable && mLayout != null) { Loading Loading @@ -9569,11 +9603,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private SuggestionInfo[] mSuggestionInfos; private int mNumberOfSuggestions; private boolean mCursorWasVisibleBeforeSuggestions; private boolean mSuggestionPopupWindowVisible; private SuggestionAdapter mSuggestionsAdapter; private final Comparator<SuggestionSpan> mSuggestionSpanComparator; private final HashMap<SuggestionSpan, Integer> mSpansLengths; private class CustomPopupWindow extends PopupWindow { public CustomPopupWindow(Context context, int defStyle) { super(context, null, defStyle); Loading @@ -9581,13 +9615,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void dismiss() { mSuggestionPopupWindowVisible = false; super.dismiss(); TextView.this.getPositionListener().removeSubscriber(SuggestionsPopupWindow.this); if ((mText instanceof Spannable)) { // Safe cast since show() checks that mText is an Editable ((Spannable) mText).removeSpan(mSuggestionRangeSpan); } setCursorVisible(mCursorWasVisibleBeforeSuggestions); if (hasInsertionController()) { Loading Loading @@ -9637,8 +9671,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener void removeMisspelledFlag() { int suggestionSpanFlags = suggestionSpan.getFlags(); if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) { suggestionSpanFlags &= ~(SuggestionSpan.FLAG_MISSPELLED); suggestionSpanFlags &= ~(SuggestionSpan.FLAG_EASY_CORRECT); suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED; suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT; suggestionSpan.setFlags(suggestionSpanFlags); } } Loading Loading @@ -9725,6 +9759,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (updateSuggestions()) { mCursorWasVisibleBeforeSuggestions = mCursorVisible; mSuggestionPopupWindowVisible = true; setCursorVisible(false); super.show(); } Loading Loading @@ -10520,9 +10555,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public abstract int getCurrentCursorOffset(); protected void updateSelection(int offset) { updateDrawable(); } protected abstract void updateSelection(int offset); public abstract void updatePosition(float x, float y); Loading Loading @@ -10796,8 +10829,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void updateSelection(int offset) { super.updateSelection(offset); Selection.setSelection((Spannable) mText, offset, getSelectionEnd()); updateDrawable(); } @Override Loading Loading @@ -10838,8 +10871,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void updateSelection(int offset) { super.updateSelection(offset); Selection.setSelection((Spannable) mText, getSelectionStart(), offset); updateDrawable(); } @Override Loading Loading
core/java/android/widget/SpellChecker.java +14 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ public class SpellChecker implements SpellCheckerSessionListener { mLength = 0; } /** * @return true if a spell checker session has successfully been created. Returns false if not, * for instance when spell checking has been disabled in settings. */ public boolean isSessionActive() { return mSpellCheckerSession != null; } public void closeSession() { if (mSpellCheckerSession != null) { mSpellCheckerSession.close(); } } public void addSpellCheckSpan(SpellCheckSpan spellCheckSpan) { int length = mIds.length; if (mLength >= length) { Loading
core/java/android/widget/TextView.java +51 −18 Original line number Diff line number Diff line Loading @@ -3250,7 +3250,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener sendOnTextChanged(text, 0, oldlen, textLength); onTextChanged(text, 0, oldlen, textLength); if (startSpellCheck) { if (startSpellCheck && getSpellChecker().isSessionActive()) { updateSpellCheckSpans(0, textLength); } Loading Loading @@ -7599,10 +7599,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener sendOnTextChanged(buffer, start, before, after); onTextChanged(buffer, start, before, after); if (getSpellChecker().isSessionActive()) { // The WordIterator text change listener may be called after this one. // Make sure this changed text is rescanned before the iterator is used on it. getWordIterator().forceUpdate(); updateSpellCheckSpans(start, start + after); } // Hide the controllers if the amount of content changed if (before != after) { Loading Loading @@ -8254,6 +8256,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mBlink.uncancel(); makeBlink(); } if (getSpellChecker().isSessionActive() && (mSuggestionsPopupWindow == null || !mSuggestionsPopupWindow.mSuggestionPopupWindowVisible)) { updateSpellCheckSpans(0, mText.length()); } } else { if (mBlink != null) { mBlink.cancel(); Loading @@ -8265,6 +8271,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } hideControllers(); if (mSpellChecker != null && (mSuggestionsPopupWindow == null || !mSuggestionsPopupWindow.mSuggestionPopupWindowVisible)) { mSpellChecker.closeSession(); removeMisspelledSpans(); // Forces the creation of a new SpellChecker next time this window if focused. // Will handle the cases where the service has been enabled or disabled in // settings in the meantime. mSpellChecker = null; } } startStopMarquee(hasWindowFocus); Loading Loading @@ -8427,13 +8443,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int flags = suggestionSpans[i].getFlags(); if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0 && (flags & SuggestionSpan.FLAG_MISSPELLED) == 0) { flags = flags & ~SuggestionSpan.FLAG_EASY_CORRECT; flags &= ~SuggestionSpan.FLAG_EASY_CORRECT; suggestionSpans[i].setFlags(flags); } } } } /** * Removes the suggestion spans for misspelled words. */ private void removeMisspelledSpans() { if (mText instanceof Spannable) { Spannable spannable = (Spannable) mText; SuggestionSpan[] suggestionSpans = spannable.getSpans(0, spannable.length(), SuggestionSpan.class); for (int i = 0; i < suggestionSpans.length; i++) { int flags = suggestionSpans[i].getFlags(); if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0 && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) { spannable.removeSpan(suggestionSpans[i]); } } } } @Override public boolean onGenericMotionEvent(MotionEvent event) { if (mMovement != null && mText instanceof Spannable && mLayout != null) { Loading Loading @@ -9569,11 +9603,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private SuggestionInfo[] mSuggestionInfos; private int mNumberOfSuggestions; private boolean mCursorWasVisibleBeforeSuggestions; private boolean mSuggestionPopupWindowVisible; private SuggestionAdapter mSuggestionsAdapter; private final Comparator<SuggestionSpan> mSuggestionSpanComparator; private final HashMap<SuggestionSpan, Integer> mSpansLengths; private class CustomPopupWindow extends PopupWindow { public CustomPopupWindow(Context context, int defStyle) { super(context, null, defStyle); Loading @@ -9581,13 +9615,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void dismiss() { mSuggestionPopupWindowVisible = false; super.dismiss(); TextView.this.getPositionListener().removeSubscriber(SuggestionsPopupWindow.this); if ((mText instanceof Spannable)) { // Safe cast since show() checks that mText is an Editable ((Spannable) mText).removeSpan(mSuggestionRangeSpan); } setCursorVisible(mCursorWasVisibleBeforeSuggestions); if (hasInsertionController()) { Loading Loading @@ -9637,8 +9671,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener void removeMisspelledFlag() { int suggestionSpanFlags = suggestionSpan.getFlags(); if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) { suggestionSpanFlags &= ~(SuggestionSpan.FLAG_MISSPELLED); suggestionSpanFlags &= ~(SuggestionSpan.FLAG_EASY_CORRECT); suggestionSpanFlags &= ~SuggestionSpan.FLAG_MISSPELLED; suggestionSpanFlags &= ~SuggestionSpan.FLAG_EASY_CORRECT; suggestionSpan.setFlags(suggestionSpanFlags); } } Loading Loading @@ -9725,6 +9759,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (updateSuggestions()) { mCursorWasVisibleBeforeSuggestions = mCursorVisible; mSuggestionPopupWindowVisible = true; setCursorVisible(false); super.show(); } Loading Loading @@ -10520,9 +10555,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public abstract int getCurrentCursorOffset(); protected void updateSelection(int offset) { updateDrawable(); } protected abstract void updateSelection(int offset); public abstract void updatePosition(float x, float y); Loading Loading @@ -10796,8 +10829,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void updateSelection(int offset) { super.updateSelection(offset); Selection.setSelection((Spannable) mText, offset, getSelectionEnd()); updateDrawable(); } @Override Loading Loading @@ -10838,8 +10871,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void updateSelection(int offset) { super.updateSelection(offset); Selection.setSelection((Spannable) mText, getSelectionStart(), offset); updateDrawable(); } @Override Loading