Clean up: Remove mIsSentenceSpellCheckSupported since it is always true.
Bug: 179223118 Test: atest CtsInputMethodTestCases:SpellCheckerTest Change-Id: Ic47a6aee5fb29a9549ecd72c5a5a6aea889ad74b
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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 */);
|
||||
}
|
||||
mSpellCheckerSession.getSentenceSuggestions(
|
||||
textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,32 +371,30 @@ 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);
|
||||
final int spellCheckSpanEnd = editable.getSpanEnd(spellCheckSpan);
|
||||
final int start;
|
||||
final int end;
|
||||
if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
|
||||
start = spellCheckSpanStart + offset;
|
||||
end = start + length;
|
||||
} else {
|
||||
start = spellCheckSpanStart;
|
||||
end = spellCheckSpanEnd;
|
||||
}
|
||||
if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
|
||||
&& end > start) {
|
||||
final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
|
||||
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
|
||||
if (tempSuggestionSpan != null) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Remove existing misspelled span. "
|
||||
+ editable.subSequence(start, end));
|
||||
}
|
||||
editable.removeSpan(tempSuggestionSpan);
|
||||
mSuggestionSpanCache.remove(key);
|
||||
// Allow the spell checker to remove existing misspelled span by
|
||||
// overwriting the span over the same place
|
||||
final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan);
|
||||
final int spellCheckSpanEnd = editable.getSpanEnd(spellCheckSpan);
|
||||
final int start;
|
||||
final int end;
|
||||
if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
|
||||
start = spellCheckSpanStart + offset;
|
||||
end = start + length;
|
||||
} else {
|
||||
start = spellCheckSpanStart;
|
||||
end = spellCheckSpanEnd;
|
||||
}
|
||||
if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
|
||||
&& end > start) {
|
||||
final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
|
||||
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
|
||||
if (tempSuggestionSpan != null) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Remove existing misspelled span. "
|
||||
+ editable.subSequence(start, end));
|
||||
}
|
||||
editable.removeSpan(tempSuggestionSpan);
|
||||
mSuggestionSpanCache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -531,20 +519,16 @@ 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) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Cached span on the same position is cleard. "
|
||||
+ editable.subSequence(start, end));
|
||||
}
|
||||
editable.removeSpan(tempSuggestionSpan);
|
||||
final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
|
||||
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
|
||||
if (tempSuggestionSpan != null) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Cached span on the same position is cleard. "
|
||||
+ editable.subSequence(start, end));
|
||||
}
|
||||
mSuggestionSpanCache.put(key, suggestionSpan);
|
||||
editable.removeSpan(tempSuggestionSpan);
|
||||
}
|
||||
mSuggestionSpanCache.put(key, suggestionSpan);
|
||||
editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
mTextView.invalidateRegion(start, end, false /* No cursor involved */);
|
||||
@@ -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(
|
||||
0, editable.getSpanStart(mRange) - MIN_SENTENCE_LENGTH);
|
||||
} else {
|
||||
start = editable.getSpanStart(mRange);
|
||||
}
|
||||
final int start = Math.max(
|
||||
0, editable.getSpanStart(mRange) - MIN_SENTENCE_LENGTH);
|
||||
|
||||
final int end = editable.getSpanEnd(mRange);
|
||||
|
||||
@@ -633,155 +610,80 @@ 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.");
|
||||
}
|
||||
// Several batches needed on that region. Cut after last previous word
|
||||
scheduleOtherSpellCheck = true;
|
||||
}
|
||||
int spellCheckEnd = mWordIterator.preceding(wordIteratorWindowEnd);
|
||||
boolean correct = spellCheckEnd != BreakIterator.DONE;
|
||||
if (correct) {
|
||||
spellCheckEnd = mWordIterator.getEnd(spellCheckEnd);
|
||||
correct = spellCheckEnd != BreakIterator.DONE;
|
||||
}
|
||||
if (!correct) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Incorrect range span.");
|
||||
}
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
// TODO: Find the start position of the sentence.
|
||||
int spellCheckStart = wordStart;
|
||||
boolean createSpellCheckSpan = true;
|
||||
// Cancel or merge overlapped spell check spans
|
||||
for (int i = 0; i < mLength; ++i) {
|
||||
final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
|
||||
if (mIds[i] < 0 || spellCheckSpan.isSpellCheckInProgress()) {
|
||||
continue;
|
||||
}
|
||||
final int spanStart = editable.getSpanStart(spellCheckSpan);
|
||||
final int spanEnd = editable.getSpanEnd(spellCheckSpan);
|
||||
if (spanEnd < spellCheckStart || spellCheckEnd < spanStart) {
|
||||
// No need to merge
|
||||
continue;
|
||||
}
|
||||
if (spanStart <= spellCheckStart && spellCheckEnd <= spanEnd) {
|
||||
// There is a completely overlapped spell check span
|
||||
// skip this span
|
||||
createSpellCheckSpan = false;
|
||||
if (DBG) {
|
||||
Log.i(TAG, "The range is overrapped. Skip spell check.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// This spellCheckSpan is replaced by the one we are creating
|
||||
editable.removeSpan(spellCheckSpan);
|
||||
spellCheckStart = Math.min(spanStart, spellCheckStart);
|
||||
spellCheckEnd = Math.max(spanEnd, spellCheckEnd);
|
||||
}
|
||||
|
||||
if (DBG) {
|
||||
Log.d(TAG, "addSpellCheckSpan: "
|
||||
+ ", End = " + spellCheckEnd + ", Start = " + spellCheckStart
|
||||
+ ", next = " + scheduleOtherSpellCheck + "\n"
|
||||
+ editable.subSequence(spellCheckStart, spellCheckEnd));
|
||||
}
|
||||
|
||||
// Stop spell checking when there are no characters in the range.
|
||||
if (spellCheckEnd < start) {
|
||||
break;
|
||||
}
|
||||
if (spellCheckEnd <= spellCheckStart) {
|
||||
Log.w(TAG, "Trying to spellcheck invalid region, from "
|
||||
+ start + " to " + end);
|
||||
break;
|
||||
}
|
||||
if (createSpellCheckSpan) {
|
||||
addSpellCheckSpan(editable, spellCheckStart, spellCheckEnd);
|
||||
}
|
||||
} 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 (wordIteratorWindowEnd < end) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "schedule other spell check.");
|
||||
}
|
||||
// Several batches needed on that region. Cut after last previous word
|
||||
scheduleOtherSpellCheck = true;
|
||||
}
|
||||
int spellCheckEnd = mWordIterator.preceding(wordIteratorWindowEnd);
|
||||
boolean correct = spellCheckEnd != BreakIterator.DONE;
|
||||
if (correct) {
|
||||
spellCheckEnd = mWordIterator.getEnd(spellCheckEnd);
|
||||
correct = spellCheckEnd != BreakIterator.DONE;
|
||||
}
|
||||
if (!correct) {
|
||||
if (DBG) {
|
||||
Log.i(TAG, "Incorrect range span.");
|
||||
}
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
// TODO: Find the start position of the sentence.
|
||||
int spellCheckStart = wordStart;
|
||||
boolean createSpellCheckSpan = true;
|
||||
// Cancel or merge overlapped spell check spans
|
||||
for (int i = 0; i < mLength; ++i) {
|
||||
final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
|
||||
if (mIds[i] < 0 || spellCheckSpan.isSpellCheckInProgress()) {
|
||||
continue;
|
||||
}
|
||||
final int spanStart = editable.getSpanStart(spellCheckSpan);
|
||||
final int spanEnd = editable.getSpanEnd(spellCheckSpan);
|
||||
if (spanEnd < spellCheckStart || spellCheckEnd < spanStart) {
|
||||
// No need to merge
|
||||
continue;
|
||||
}
|
||||
if (spanStart <= spellCheckStart && spellCheckEnd <= spanEnd) {
|
||||
// There is a completely overlapped spell check span
|
||||
// skip this span
|
||||
createSpellCheckSpan = false;
|
||||
if (DBG) {
|
||||
Log.i(TAG, "The range is overrapped. Skip spell check.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// This spellCheckSpan is replaced by the one we are creating
|
||||
editable.removeSpan(spellCheckSpan);
|
||||
spellCheckStart = Math.min(spanStart, spellCheckStart);
|
||||
spellCheckEnd = Math.max(spanEnd, spellCheckEnd);
|
||||
}
|
||||
|
||||
if (DBG) {
|
||||
Log.d(TAG, "addSpellCheckSpan: "
|
||||
+ ", End = " + spellCheckEnd + ", Start = " + spellCheckStart
|
||||
+ ", next = " + scheduleOtherSpellCheck + "\n"
|
||||
+ editable.subSequence(spellCheckStart, spellCheckEnd));
|
||||
}
|
||||
|
||||
// Stop spell checking when there are no characters in the range.
|
||||
if (spellCheckEnd < start) {
|
||||
break;
|
||||
}
|
||||
if (spellCheckEnd <= spellCheckStart) {
|
||||
Log.w(TAG, "Trying to spellcheck invalid region, from "
|
||||
+ start + " to " + end);
|
||||
break;
|
||||
}
|
||||
if (createSpellCheckSpan) {
|
||||
addSpellCheckSpan(editable, spellCheckStart, spellCheckEnd);
|
||||
}
|
||||
} while (false);
|
||||
wordStart = spellCheckEnd;
|
||||
|
||||
if (scheduleOtherSpellCheck && wordStart != BreakIterator.DONE && wordStart <= end) {
|
||||
// Update range span: start new spell check from last wordStart
|
||||
|
||||
Reference in New Issue
Block a user