Fix some bugs in editing feature
- Fixed caching of words - some StringBuilders were being recycled while also being cached. Making copies now. - Fixed regression in revert - don't reset the word composer after saving the accepted word. - Removed flicker when cursoring through a word - delay the abortCorrection() until we need to and do the correction as an atomic operation. - Fixed replacing of "selected" words (double-tap to select a word) Still to do: - Remove flicker on highlighting a word - may need a framework change - Don't remove spans on text that's already in the text field - may require a framework change. - Figure out what to do about the punctuations that share the suggestion strip when in correction mode.main
parent
daf88d35e7
commit
b71547f2d0
|
@ -49,8 +49,8 @@ import android.view.HapticFeedbackConstants;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewParent;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewParent;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.CompletionInfo;
|
import android.view.inputmethod.CompletionInfo;
|
||||||
|
@ -693,12 +693,14 @@ public class LatinIME extends InputMethodService
|
||||||
|
|
||||||
|
|
||||||
// If a word is selected
|
// If a word is selected
|
||||||
if ((candidatesStart == candidatesEnd || newSelStart != oldSelStart)
|
if (isPredictionOn() && mJustRevertedSeparator == null
|
||||||
|
&& (candidatesStart == candidatesEnd || newSelStart != oldSelStart)
|
||||||
&& (newSelStart < newSelEnd - 1 || (!mPredicting))
|
&& (newSelStart < newSelEnd - 1 || (!mPredicting))
|
||||||
&& !mVoiceInputHighlighted) {
|
&& !mVoiceInputHighlighted) {
|
||||||
abortCorrection(false);
|
|
||||||
if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) {
|
if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) {
|
||||||
postUpdateOldSuggestions();
|
postUpdateOldSuggestions();
|
||||||
|
} else {
|
||||||
|
abortCorrection(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1083,6 +1085,8 @@ public class LatinIME extends InputMethodService
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
if (ic == null) return;
|
if (ic == null) return;
|
||||||
|
|
||||||
|
ic.beginBatchEdit();
|
||||||
|
|
||||||
if (mAfterVoiceInput) {
|
if (mAfterVoiceInput) {
|
||||||
// Don't log delete if the user is pressing delete at
|
// Don't log delete if the user is pressing delete at
|
||||||
// the beginning of the text box (hence not deleting anything)
|
// the beginning of the text box (hence not deleting anything)
|
||||||
|
@ -1115,6 +1119,7 @@ public class LatinIME extends InputMethodService
|
||||||
TextEntryState.backspace();
|
TextEntryState.backspace();
|
||||||
if (TextEntryState.getState() == TextEntryState.STATE_UNDO_COMMIT) {
|
if (TextEntryState.getState() == TextEntryState.STATE_UNDO_COMMIT) {
|
||||||
revertLastWord(deleteChar);
|
revertLastWord(deleteChar);
|
||||||
|
ic.endBatchEdit();
|
||||||
return;
|
return;
|
||||||
} else if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
|
} else if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
|
||||||
ic.deleteSurroundingText(mEnteredText.length(), 0);
|
ic.deleteSurroundingText(mEnteredText.length(), 0);
|
||||||
|
@ -1125,6 +1130,7 @@ public class LatinIME extends InputMethodService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mJustRevertedSeparator = null;
|
mJustRevertedSeparator = null;
|
||||||
|
ic.endBatchEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleShift() {
|
private void handleShift() {
|
||||||
|
@ -1277,9 +1283,10 @@ public class LatinIME extends InputMethodService
|
||||||
mWord.reset();
|
mWord.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TypedWordAlternatives entry = new TypedWordAlternatives(result, mWord);
|
// Make a copy of the CharSequence, since it is/could be a mutable CharSequence
|
||||||
// Create a new WordComposer as the old one is being saved for later use
|
final String resultCopy = result.toString();
|
||||||
mWord = new WordComposer(mWord);
|
TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy,
|
||||||
|
new WordComposer(mWord));
|
||||||
mWordHistory.add(entry);
|
mWordHistory.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1648,7 +1655,8 @@ public class LatinIME extends InputMethodService
|
||||||
|
|
||||||
// Fool the state watcher so that a subsequent backspace will not do a revert
|
// Fool the state watcher so that a subsequent backspace will not do a revert
|
||||||
TextEntryState.typedCharacter((char) KEYCODE_SPACE, true);
|
TextEntryState.typedCharacter((char) KEYCODE_SPACE, true);
|
||||||
if (index == 0 && mCorrectionMode > 0 && !mSuggest.isValidWord(suggestion)) {
|
if (index == 0 && mCorrectionMode > 0 && !mSuggest.isValidWord(suggestion)
|
||||||
|
&& !mSuggest.isValidWord(suggestion.toString().toLowerCase())) {
|
||||||
mCandidateView.showAddToDictionaryHint(suggestion);
|
mCandidateView.showAddToDictionaryHint(suggestion);
|
||||||
}
|
}
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
|
@ -1662,9 +1670,9 @@ public class LatinIME extends InputMethodService
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
EditingUtil.Range range = new EditingUtil.Range();
|
EditingUtil.Range range = new EditingUtil.Range();
|
||||||
String wordToBeReplaced = EditingUtil.getWordAtCursor(getCurrentInputConnection(),
|
String wordToBeReplaced = EditingUtil.getWordAtCursor(getCurrentInputConnection(),
|
||||||
mWordSeparators, range).trim();
|
mWordSeparators, range);
|
||||||
if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
if (!mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
||||||
wordToBeReplaced = wordToBeReplaced.toLowerCase();
|
wordToBeReplaced = wordToBeReplaced.toLowerCase();
|
||||||
}
|
}
|
||||||
if (mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
if (mWordToSuggestions.containsKey(wordToBeReplaced)) {
|
||||||
List<CharSequence> suggestions = mWordToSuggestions.get(wordToBeReplaced);
|
List<CharSequence> suggestions = mWordToSuggestions.get(wordToBeReplaced);
|
||||||
|
@ -1690,9 +1698,6 @@ public class LatinIME extends InputMethodService
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
rememberReplacedWord(suggestion);
|
rememberReplacedWord(suggestion);
|
||||||
if (mSuggestionShouldReplaceCurrentWord) {
|
|
||||||
EditingUtil.deleteWordAtCursor(ic, getWordSeparators());
|
|
||||||
}
|
|
||||||
if (!VoiceInput.DELETE_SYMBOL.equals(suggestion)) {
|
if (!VoiceInput.DELETE_SYMBOL.equals(suggestion)) {
|
||||||
ic.commitText(suggestion, 1);
|
ic.commitText(suggestion, 1);
|
||||||
}
|
}
|
||||||
|
@ -1719,9 +1724,8 @@ public class LatinIME extends InputMethodService
|
||||||
}
|
}
|
||||||
if (!mPredicting && isCursorTouchingWord()) {
|
if (!mPredicting && isCursorTouchingWord()) {
|
||||||
EditingUtil.Range range = new EditingUtil.Range();
|
EditingUtil.Range range = new EditingUtil.Range();
|
||||||
CharSequence touching =
|
CharSequence touching = EditingUtil.getWordAtCursor(getCurrentInputConnection(),
|
||||||
EditingUtil.getWordAtCursor(getCurrentInputConnection(), mWordSeparators,
|
mWordSeparators, range);
|
||||||
range);
|
|
||||||
if (touching != null && touching.length() > 1) {
|
if (touching != null && touching.length() > 1) {
|
||||||
if (mWordSeparators.indexOf(touching.charAt(touching.length() - 1)) > 0) {
|
if (mWordSeparators.indexOf(touching.charAt(touching.length() - 1)) > 0) {
|
||||||
touching = touching.toString().substring(0, touching.length() - 1);
|
touching = touching.toString().substring(0, touching.length() - 1);
|
||||||
|
@ -1782,7 +1786,7 @@ public class LatinIME extends InputMethodService
|
||||||
foundWord);
|
foundWord);
|
||||||
showCorrections(alternatives);
|
showCorrections(alternatives);
|
||||||
if (foundWord != null) {
|
if (foundWord != null) {
|
||||||
mWord = foundWord;
|
mWord = new WordComposer(foundWord);
|
||||||
} else {
|
} else {
|
||||||
mWord.reset();
|
mWord.reset();
|
||||||
}
|
}
|
||||||
|
@ -1815,6 +1819,7 @@ public class LatinIME extends InputMethodService
|
||||||
private void underlineWord(CharSequence word, int left, int right) {
|
private void underlineWord(CharSequence word, int left, int right) {
|
||||||
InputConnection ic = getCurrentInputConnection();
|
InputConnection ic = getCurrentInputConnection();
|
||||||
if (ic == null) return;
|
if (ic == null) return;
|
||||||
|
ic.finishComposingText();
|
||||||
ic.deleteSurroundingText(left, right);
|
ic.deleteSurroundingText(left, right);
|
||||||
ic.setComposingText(word, 1);
|
ic.setComposingText(word, 1);
|
||||||
ic.setSelection(mLastSelectionStart, mLastSelectionStart);
|
ic.setSelection(mLastSelectionStart, mLastSelectionStart);
|
||||||
|
@ -1859,7 +1864,6 @@ public class LatinIME extends InputMethodService
|
||||||
if (!mPredicting && length > 0) {
|
if (!mPredicting && length > 0) {
|
||||||
final InputConnection ic = getCurrentInputConnection();
|
final InputConnection ic = getCurrentInputConnection();
|
||||||
mPredicting = true;
|
mPredicting = true;
|
||||||
ic.beginBatchEdit();
|
|
||||||
mJustRevertedSeparator = ic.getTextBeforeCursor(1, 0);
|
mJustRevertedSeparator = ic.getTextBeforeCursor(1, 0);
|
||||||
if (deleteChar) ic.deleteSurroundingText(1, 0);
|
if (deleteChar) ic.deleteSurroundingText(1, 0);
|
||||||
int toDelete = mCommittedLength;
|
int toDelete = mCommittedLength;
|
||||||
|
@ -1871,7 +1875,6 @@ public class LatinIME extends InputMethodService
|
||||||
ic.deleteSurroundingText(toDelete, 0);
|
ic.deleteSurroundingText(toDelete, 0);
|
||||||
ic.setComposingText(mComposing, 1);
|
ic.setComposingText(mComposing, 1);
|
||||||
TextEntryState.backspace();
|
TextEntryState.backspace();
|
||||||
ic.endBatchEdit();
|
|
||||||
postUpdateSuggestions();
|
postUpdateSuggestions();
|
||||||
} else {
|
} else {
|
||||||
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
|
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
|
||||||
|
|
|
@ -55,7 +55,9 @@ public class WordComposer {
|
||||||
mTypedWord = new StringBuilder(copy.mTypedWord);
|
mTypedWord = new StringBuilder(copy.mTypedWord);
|
||||||
mCapsCount = copy.mCapsCount;
|
mCapsCount = copy.mCapsCount;
|
||||||
mAutoCapitalized = copy.mAutoCapitalized;
|
mAutoCapitalized = copy.mAutoCapitalized;
|
||||||
|
mIsCapitalized = copy.mIsCapitalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear out the keys registered so far.
|
* Clear out the keys registered so far.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue