Loading core/java/android/widget/SpellChecker.java +100 −198 Original line number Diff line number Diff line Loading @@ -69,9 +69,7 @@ public class SpellChecker implements SpellCheckerSessionListener { private final TextView mTextView; SpellCheckerSession mSpellCheckerSession; // We assume that the sentence level spell check will always provide better results than words. // Although word SC has a sequential option. private boolean mIsSentenceSpellCheckSupported; final int mCookie; // Paired arrays for the (id, spellCheckSpan) pair. A negative id means the associated Loading Loading @@ -134,7 +132,6 @@ public class SpellChecker implements SpellCheckerSessionListener { | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR | SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS); mIsSentenceSpellCheckSupported = true; } // Restore SpellCheckSpans in pool Loading Loading @@ -318,13 +315,11 @@ public class SpellChecker implements SpellCheckerSessionListener { && WordIterator.isMidWordPunctuation( mCurrentLocale, Character.codePointBefore(editable, end + 1))) { isEditing = false; } else if (mIsSentenceSpellCheckSupported) { } else { // Allow the overlap of the cursor and the first boundary of the spell check span // no to skip the spell check of the following word because the // following word will never be spell-checked even if the user finishes composing isEditing = selectionEnd <= start || selectionStart > end; } else { isEditing = selectionEnd < start || selectionStart > end; } if (start >= 0 && end > start && (forceCheckWhenEditingWord || isEditing)) { spellCheckSpan.setSpellCheckInProgress(true); Loading @@ -346,13 +341,8 @@ public class SpellChecker implements SpellCheckerSessionListener { textInfos = textInfosCopy; } if (mIsSentenceSpellCheckSupported) { mSpellCheckerSession.getSentenceSuggestions( textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE); } else { mSpellCheckerSession.getSuggestions(textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE, false /* TODO Set sequentialWords to true for initial spell check */); } } } Loading Loading @@ -381,7 +371,6 @@ public class SpellChecker implements SpellCheckerSessionListener { editable, suggestionsInfo, spellCheckSpan, offset, length); } else { // Valid word -- isInDictionary || !looksLikeTypo if (mIsSentenceSpellCheckSupported) { // Allow the spell checker to remove existing misspelled span by // overwriting the span over the same place final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan); Loading Loading @@ -409,7 +398,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } } } } return spellCheckSpan; } } Loading Loading @@ -531,9 +519,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions, flags); // TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface // to share the logic of word level spell checker and sentence level spell checker if (mIsSentenceSpellCheckSupported) { final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end)); final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key); if (tempSuggestionSpan != null) { Loading @@ -544,7 +529,6 @@ public class SpellChecker implements SpellCheckerSessionListener { editable.removeSpan(tempSuggestionSpan); } mSuggestionSpanCache.put(key, suggestionSpan); } editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView.invalidateRegion(start, end, false /* No cursor involved */); Loading Loading @@ -599,15 +583,8 @@ public class SpellChecker implements SpellCheckerSessionListener { public void parse() { Editable editable = (Editable) mTextView.getText(); // Iterate over the newly added text and schedule new SpellCheckSpans final int start; if (mIsSentenceSpellCheckSupported) { // TODO: Find the start position of the sentence. // Set span with the context start = Math.max( final int start = Math.max( 0, editable.getSpanStart(mRange) - MIN_SENTENCE_LENGTH); } else { start = editable.getSpanStart(mRange); } final int end = editable.getSpanEnd(mRange); Loading @@ -633,17 +610,8 @@ public class SpellChecker implements SpellCheckerSessionListener { return; } // We need to expand by one character because we want to include the spans that // end/start at position start/end respectively. SpellCheckSpan[] spellCheckSpans = editable.getSpans(start - 1, end + 1, SpellCheckSpan.class); SuggestionSpan[] suggestionSpans = editable.getSpans(start - 1, end + 1, SuggestionSpan.class); int wordCount = 0; boolean scheduleOtherSpellCheck = false; if (mIsSentenceSpellCheckSupported) { if (wordIteratorWindowEnd < end) { if (DBG) { Log.i(TAG, "schedule other spell check."); Loading Loading @@ -716,72 +684,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } } while (false); wordStart = spellCheckEnd; } else { while (wordStart <= end) { if (wordEnd >= start && wordEnd > wordStart) { if (wordCount >= MAX_NUMBER_OF_WORDS) { scheduleOtherSpellCheck = true; break; } // A new word has been created across the interval boundaries with this // edit. The previous spans (that ended on start / started on end) are // not valid anymore and must be removed. if (wordStart < start && wordEnd > start) { removeSpansAt(editable, start, spellCheckSpans); removeSpansAt(editable, start, suggestionSpans); } if (wordStart < end && wordEnd > end) { removeSpansAt(editable, end, spellCheckSpans); removeSpansAt(editable, end, suggestionSpans); } // Do not create new boundary spans if they already exist boolean createSpellCheckSpan = true; if (wordEnd == start) { for (int i = 0; i < spellCheckSpans.length; i++) { final int spanEnd = editable.getSpanEnd(spellCheckSpans[i]); if (spanEnd == start) { createSpellCheckSpan = false; break; } } } if (wordStart == end) { for (int i = 0; i < spellCheckSpans.length; i++) { final int spanStart = editable.getSpanStart(spellCheckSpans[i]); if (spanStart == end) { createSpellCheckSpan = false; break; } } } if (createSpellCheckSpan) { addSpellCheckSpan(editable, wordStart, wordEnd); } wordCount++; } // iterate word by word int originalWordEnd = wordEnd; wordEnd = mWordIterator.following(wordEnd); if ((wordIteratorWindowEnd < end) && (wordEnd == BreakIterator.DONE || wordEnd >= wordIteratorWindowEnd)) { wordIteratorWindowEnd = Math.min(end, originalWordEnd + WORD_ITERATOR_INTERVAL); mWordIterator.setCharSequence( editable, originalWordEnd, wordIteratorWindowEnd); wordEnd = mWordIterator.following(originalWordEnd); } if (wordEnd == BreakIterator.DONE) break; wordStart = mWordIterator.getBeginning(wordEnd); if (wordStart == BreakIterator.DONE) { break; } } } if (scheduleOtherSpellCheck && wordStart != BreakIterator.DONE && wordStart <= end) { // Update range span: start new spell check from last wordStart Loading Loading
core/java/android/widget/SpellChecker.java +100 −198 Original line number Diff line number Diff line Loading @@ -69,9 +69,7 @@ public class SpellChecker implements SpellCheckerSessionListener { private final TextView mTextView; SpellCheckerSession mSpellCheckerSession; // We assume that the sentence level spell check will always provide better results than words. // Although word SC has a sequential option. private boolean mIsSentenceSpellCheckSupported; final int mCookie; // Paired arrays for the (id, spellCheckSpan) pair. A negative id means the associated Loading Loading @@ -134,7 +132,6 @@ public class SpellChecker implements SpellCheckerSessionListener { | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR | SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS); mIsSentenceSpellCheckSupported = true; } // Restore SpellCheckSpans in pool Loading Loading @@ -318,13 +315,11 @@ public class SpellChecker implements SpellCheckerSessionListener { && WordIterator.isMidWordPunctuation( mCurrentLocale, Character.codePointBefore(editable, end + 1))) { isEditing = false; } else if (mIsSentenceSpellCheckSupported) { } else { // Allow the overlap of the cursor and the first boundary of the spell check span // no to skip the spell check of the following word because the // following word will never be spell-checked even if the user finishes composing isEditing = selectionEnd <= start || selectionStart > end; } else { isEditing = selectionEnd < start || selectionStart > end; } if (start >= 0 && end > start && (forceCheckWhenEditingWord || isEditing)) { spellCheckSpan.setSpellCheckInProgress(true); Loading @@ -346,13 +341,8 @@ public class SpellChecker implements SpellCheckerSessionListener { textInfos = textInfosCopy; } if (mIsSentenceSpellCheckSupported) { mSpellCheckerSession.getSentenceSuggestions( textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE); } else { mSpellCheckerSession.getSuggestions(textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE, false /* TODO Set sequentialWords to true for initial spell check */); } } } Loading Loading @@ -381,7 +371,6 @@ public class SpellChecker implements SpellCheckerSessionListener { editable, suggestionsInfo, spellCheckSpan, offset, length); } else { // Valid word -- isInDictionary || !looksLikeTypo if (mIsSentenceSpellCheckSupported) { // Allow the spell checker to remove existing misspelled span by // overwriting the span over the same place final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan); Loading Loading @@ -409,7 +398,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } } } } return spellCheckSpan; } } Loading Loading @@ -531,9 +519,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions, flags); // TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface // to share the logic of word level spell checker and sentence level spell checker if (mIsSentenceSpellCheckSupported) { final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end)); final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key); if (tempSuggestionSpan != null) { Loading @@ -544,7 +529,6 @@ public class SpellChecker implements SpellCheckerSessionListener { editable.removeSpan(tempSuggestionSpan); } mSuggestionSpanCache.put(key, suggestionSpan); } editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView.invalidateRegion(start, end, false /* No cursor involved */); Loading Loading @@ -599,15 +583,8 @@ public class SpellChecker implements SpellCheckerSessionListener { public void parse() { Editable editable = (Editable) mTextView.getText(); // Iterate over the newly added text and schedule new SpellCheckSpans final int start; if (mIsSentenceSpellCheckSupported) { // TODO: Find the start position of the sentence. // Set span with the context start = Math.max( final int start = Math.max( 0, editable.getSpanStart(mRange) - MIN_SENTENCE_LENGTH); } else { start = editable.getSpanStart(mRange); } final int end = editable.getSpanEnd(mRange); Loading @@ -633,17 +610,8 @@ public class SpellChecker implements SpellCheckerSessionListener { return; } // We need to expand by one character because we want to include the spans that // end/start at position start/end respectively. SpellCheckSpan[] spellCheckSpans = editable.getSpans(start - 1, end + 1, SpellCheckSpan.class); SuggestionSpan[] suggestionSpans = editable.getSpans(start - 1, end + 1, SuggestionSpan.class); int wordCount = 0; boolean scheduleOtherSpellCheck = false; if (mIsSentenceSpellCheckSupported) { if (wordIteratorWindowEnd < end) { if (DBG) { Log.i(TAG, "schedule other spell check."); Loading Loading @@ -716,72 +684,6 @@ public class SpellChecker implements SpellCheckerSessionListener { } } while (false); wordStart = spellCheckEnd; } else { while (wordStart <= end) { if (wordEnd >= start && wordEnd > wordStart) { if (wordCount >= MAX_NUMBER_OF_WORDS) { scheduleOtherSpellCheck = true; break; } // A new word has been created across the interval boundaries with this // edit. The previous spans (that ended on start / started on end) are // not valid anymore and must be removed. if (wordStart < start && wordEnd > start) { removeSpansAt(editable, start, spellCheckSpans); removeSpansAt(editable, start, suggestionSpans); } if (wordStart < end && wordEnd > end) { removeSpansAt(editable, end, spellCheckSpans); removeSpansAt(editable, end, suggestionSpans); } // Do not create new boundary spans if they already exist boolean createSpellCheckSpan = true; if (wordEnd == start) { for (int i = 0; i < spellCheckSpans.length; i++) { final int spanEnd = editable.getSpanEnd(spellCheckSpans[i]); if (spanEnd == start) { createSpellCheckSpan = false; break; } } } if (wordStart == end) { for (int i = 0; i < spellCheckSpans.length; i++) { final int spanStart = editable.getSpanStart(spellCheckSpans[i]); if (spanStart == end) { createSpellCheckSpan = false; break; } } } if (createSpellCheckSpan) { addSpellCheckSpan(editable, wordStart, wordEnd); } wordCount++; } // iterate word by word int originalWordEnd = wordEnd; wordEnd = mWordIterator.following(wordEnd); if ((wordIteratorWindowEnd < end) && (wordEnd == BreakIterator.DONE || wordEnd >= wordIteratorWindowEnd)) { wordIteratorWindowEnd = Math.min(end, originalWordEnd + WORD_ITERATOR_INTERVAL); mWordIterator.setCharSequence( editable, originalWordEnd, wordIteratorWindowEnd); wordEnd = mWordIterator.following(originalWordEnd); } if (wordEnd == BreakIterator.DONE) break; wordStart = mWordIterator.getBeginning(wordEnd); if (wordStart == BreakIterator.DONE) { break; } } } if (scheduleOtherSpellCheck && wordStart != BreakIterator.DONE && wordStart <= end) { // Update range span: start new spell check from last wordStart Loading