Straighten out magic space vs real spaces behavior.
Picking a suggestion inserts a space after the word. This change makes this space a magic space. Incidentally, do some minor cleanup: add CODE_DASH, CODE_SINGLE_QUOTE and CODE_DOUBLE_QUOTE to Keyboard and use them throughout the code, and remove a useless import directive in some unrelated file. Bug: 4319740 Change-Id: I245f396c34dd0af820bca91edc4ec363238a4ae4main
parent
3bf6fbb6b8
commit
0730bbfbf5
|
@ -23,6 +23,9 @@
|
||||||
<integer name="key_tab">9</integer>
|
<integer name="key_tab">9</integer>
|
||||||
<integer name="key_return">10</integer>
|
<integer name="key_return">10</integer>
|
||||||
<integer name="key_space">32</integer>
|
<integer name="key_space">32</integer>
|
||||||
|
<integer name="key_dash">45</integer>
|
||||||
|
<integer name="key_single_quote">39</integer>
|
||||||
|
<integer name="key_double_quote">34</integer>
|
||||||
<integer name="key_shift">-1</integer>
|
<integer name="key_shift">-1</integer>
|
||||||
<integer name="key_switch_alpha_symbol">-2</integer>
|
<integer name="key_switch_alpha_symbol">-2</integer>
|
||||||
<integer name="key_delete">-5</integer>
|
<integer name="key_delete">-5</integer>
|
||||||
|
|
|
@ -63,6 +63,9 @@ public class Keyboard {
|
||||||
public static final int CODE_TAB = '\t';
|
public static final int CODE_TAB = '\t';
|
||||||
public static final int CODE_SPACE = ' ';
|
public static final int CODE_SPACE = ' ';
|
||||||
public static final int CODE_PERIOD = '.';
|
public static final int CODE_PERIOD = '.';
|
||||||
|
public static final int CODE_DASH = '-';
|
||||||
|
public static final int CODE_SINGLE_QUOTE = '\'';
|
||||||
|
public static final int CODE_DOUBLE_QUOTE = '"';
|
||||||
|
|
||||||
/** Special keys code. These should be aligned with values/keycodes.xml */
|
/** Special keys code. These should be aligned with values/keycodes.xml */
|
||||||
public static final int CODE_DUMMY = 0;
|
public static final int CODE_DUMMY = 0;
|
||||||
|
|
|
@ -626,7 +626,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
|
|
||||||
private static boolean isQuoteCharacter(int c) {
|
private static boolean isQuoteCharacter(int c) {
|
||||||
// Apostrophe, quotation mark.
|
// Apostrophe, quotation mark.
|
||||||
if (c == '\'' || c == '"')
|
if (c == Keyboard.CODE_SINGLE_QUOTE || c == Keyboard.CODE_DOUBLE_QUOTE)
|
||||||
return true;
|
return true;
|
||||||
// \u2018: Left single quotation mark
|
// \u2018: Left single quotation mark
|
||||||
// \u2019: Right single quotation mark
|
// \u2019: Right single quotation mark
|
||||||
|
|
|
@ -26,6 +26,8 @@ import android.provider.ContactsContract.Contacts;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
|
||||||
public class ContactsDictionary extends ExpandableDictionary {
|
public class ContactsDictionary extends ExpandableDictionary {
|
||||||
|
|
||||||
private static final String[] PROJECTION = {
|
private static final String[] PROJECTION = {
|
||||||
|
@ -123,8 +125,9 @@ public class ContactsDictionary extends ExpandableDictionary {
|
||||||
for (j = i + 1; j < len; j++) {
|
for (j = i + 1; j < len; j++) {
|
||||||
char c = name.charAt(j);
|
char c = name.charAt(j);
|
||||||
|
|
||||||
if (!(c == '-' || c == '\'' ||
|
if (!(c == Keyboard.CODE_DASH
|
||||||
Character.isLetter(c))) {
|
|| c == Keyboard.CODE_SINGLE_QUOTE
|
||||||
|
|| Character.isLetter(c))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.android.inputmethod.latin;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.AssetFileDescriptor;
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ package com.android.inputmethod.latin;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +43,6 @@ public class ExpandableDictionary extends Dictionary {
|
||||||
private int mMaxDepth;
|
private int mMaxDepth;
|
||||||
private int mInputLength;
|
private int mInputLength;
|
||||||
|
|
||||||
private static final char QUOTE = '\'';
|
|
||||||
|
|
||||||
private boolean mRequiresReload;
|
private boolean mRequiresReload;
|
||||||
|
|
||||||
private boolean mUpdatingDictionary;
|
private boolean mUpdatingDictionary;
|
||||||
|
@ -304,7 +304,8 @@ public class ExpandableDictionary extends Dictionary {
|
||||||
getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
|
getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex,
|
||||||
skipPos, callback);
|
skipPos, callback);
|
||||||
}
|
}
|
||||||
} else if ((c == QUOTE && currentChars[0] != QUOTE) || depth == skipPos) {
|
} else if ((c == Keyboard.CODE_SINGLE_QUOTE
|
||||||
|
&& currentChars[0] != Keyboard.CODE_SINGLE_QUOTE) || depth == skipPos) {
|
||||||
// Skip the ' and continue deeper
|
// Skip the ' and continue deeper
|
||||||
word[depth] = c;
|
word[depth] = c;
|
||||||
if (children != null) {
|
if (children != null) {
|
||||||
|
|
|
@ -161,8 +161,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
private ContactsDictionary mContactsDictionary;
|
private ContactsDictionary mContactsDictionary;
|
||||||
private AutoDictionary mAutoDictionary;
|
private AutoDictionary mAutoDictionary;
|
||||||
|
|
||||||
|
// TODO: Create an inner class to group options and pseudo-options to improve readability.
|
||||||
// These variables are initialized according to the {@link EditorInfo#inputType}.
|
// These variables are initialized according to the {@link EditorInfo#inputType}.
|
||||||
private boolean mAutoSpace;
|
private boolean mShouldInsertMagicSpace;
|
||||||
private boolean mInputTypeNoAutoCorrect;
|
private boolean mInputTypeNoAutoCorrect;
|
||||||
private boolean mIsSettingsSuggestionStripOn;
|
private boolean mIsSettingsSuggestionStripOn;
|
||||||
private boolean mApplicationSpecifiedCompletionOn;
|
private boolean mApplicationSpecifiedCompletionOn;
|
||||||
|
@ -174,7 +175,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
private CharSequence mBestWord;
|
private CharSequence mBestWord;
|
||||||
private boolean mHasUncommittedTypedChars;
|
private boolean mHasUncommittedTypedChars;
|
||||||
private boolean mHasDictionary;
|
private boolean mHasDictionary;
|
||||||
private boolean mJustAddedAutoSpace;
|
// Magic space: a space that should disappear on space/apostrophe insertion, move after the
|
||||||
|
// punctuation on punctuation insertion, and become a real space on alpha char insertion.
|
||||||
|
private boolean mJustAddedMagicSpace; // This indicates whether the last char is a magic space.
|
||||||
private boolean mAutoCorrectEnabled;
|
private boolean mAutoCorrectEnabled;
|
||||||
private boolean mRecorrectionEnabled;
|
private boolean mRecorrectionEnabled;
|
||||||
// Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
|
// Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
|
||||||
|
@ -593,7 +596,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
mComposing.setLength(0);
|
mComposing.setLength(0);
|
||||||
mHasUncommittedTypedChars = false;
|
mHasUncommittedTypedChars = false;
|
||||||
mDeleteCount = 0;
|
mDeleteCount = 0;
|
||||||
mJustAddedAutoSpace = false;
|
mJustAddedMagicSpace = false;
|
||||||
|
|
||||||
loadSettings(attribute);
|
loadSettings(attribute);
|
||||||
if (mSubtypeSwitcher.isKeyboardMode()) {
|
if (mSubtypeSwitcher.isKeyboardMode()) {
|
||||||
|
@ -628,7 +631,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
return;
|
return;
|
||||||
final int inputType = attribute.inputType;
|
final int inputType = attribute.inputType;
|
||||||
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
|
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
|
||||||
mAutoSpace = false;
|
mShouldInsertMagicSpace = false;
|
||||||
mInputTypeNoAutoCorrect = false;
|
mInputTypeNoAutoCorrect = false;
|
||||||
mIsSettingsSuggestionStripOn = false;
|
mIsSettingsSuggestionStripOn = false;
|
||||||
mApplicationSpecifiedCompletionOn = false;
|
mApplicationSpecifiedCompletionOn = false;
|
||||||
|
@ -643,9 +646,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
}
|
}
|
||||||
if (InputTypeCompatUtils.isEmailVariation(variation)
|
if (InputTypeCompatUtils.isEmailVariation(variation)
|
||||||
|| variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
|
|| variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
|
||||||
mAutoSpace = false;
|
mShouldInsertMagicSpace = false;
|
||||||
} else {
|
} else {
|
||||||
mAutoSpace = true;
|
mShouldInsertMagicSpace = true;
|
||||||
}
|
}
|
||||||
if (InputTypeCompatUtils.isEmailVariation(variation)) {
|
if (InputTypeCompatUtils.isEmailVariation(variation)) {
|
||||||
mIsSettingsSuggestionStripOn = false;
|
mIsSettingsSuggestionStripOn = false;
|
||||||
|
@ -789,7 +792,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
|
if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
|
||||||
if (TextEntryState.isAcceptedDefault())
|
if (TextEntryState.isAcceptedDefault())
|
||||||
TextEntryState.reset();
|
TextEntryState.reset();
|
||||||
mJustAddedAutoSpace = false; // The user moved the cursor.
|
mJustAddedMagicSpace = false; // The user moved the cursor.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mJustAccepted = false;
|
mJustAccepted = false;
|
||||||
|
@ -1042,23 +1045,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
ic.commitText(lastTwo.charAt(1) + " ", 1);
|
ic.commitText(lastTwo.charAt(1) + " ", 1);
|
||||||
ic.endBatchEdit();
|
ic.endBatchEdit();
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
mJustAddedAutoSpace = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reswapPeriodAndSpace() {
|
|
||||||
final InputConnection ic = getCurrentInputConnection();
|
|
||||||
if (ic == null) return;
|
|
||||||
CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
|
|
||||||
if (lastThree != null && lastThree.length() == 3
|
|
||||||
&& lastThree.charAt(0) == Keyboard.CODE_PERIOD
|
|
||||||
&& lastThree.charAt(1) == Keyboard.CODE_SPACE
|
|
||||||
&& lastThree.charAt(2) == Keyboard.CODE_PERIOD) {
|
|
||||||
ic.beginBatchEdit();
|
|
||||||
ic.deleteSurroundingText(3, 0);
|
|
||||||
ic.commitText(" ..", 1);
|
|
||||||
ic.endBatchEdit();
|
|
||||||
mKeyboardSwitcher.updateShiftState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1078,7 +1064,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
ic.commitText(". ", 1);
|
ic.commitText(". ", 1);
|
||||||
ic.endBatchEdit();
|
ic.endBatchEdit();
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
mJustAddedAutoSpace = true;
|
|
||||||
} else {
|
} else {
|
||||||
mHandler.startDoubleSpacesTimer();
|
mHandler.startDoubleSpacesTimer();
|
||||||
}
|
}
|
||||||
|
@ -1205,9 +1190,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
handleTab();
|
handleTab();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (primaryCode != Keyboard.CODE_ENTER) {
|
|
||||||
mJustAddedAutoSpace = false;
|
|
||||||
}
|
|
||||||
if (isWordSeparator(primaryCode)) {
|
if (isWordSeparator(primaryCode)) {
|
||||||
handleSeparator(primaryCode, x, y);
|
handleSeparator(primaryCode, x, y);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1232,7 +1214,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
ic.endBatchEdit();
|
ic.endBatchEdit();
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
|
mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
|
||||||
mJustAddedAutoSpace = false;
|
mJustAddedMagicSpace = false;
|
||||||
mEnteredText = text;
|
mEnteredText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,6 +1324,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
|
private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
|
||||||
mVoiceProxy.handleCharacter();
|
mVoiceProxy.handleCharacter();
|
||||||
|
|
||||||
|
if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SINGLE_QUOTE) {
|
||||||
|
removeTrailingSpace();
|
||||||
|
}
|
||||||
|
if (primaryCode != Keyboard.CODE_ENTER) {
|
||||||
|
mJustAddedMagicSpace = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) {
|
if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) {
|
||||||
abortRecorrection(false);
|
abortRecorrection(false);
|
||||||
}
|
}
|
||||||
|
@ -1420,35 +1409,33 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
// not to auto correct, but accept the typed word. For instance,
|
// not to auto correct, but accept the typed word. For instance,
|
||||||
// in Italian dov' should not be expanded to dove' because the elision
|
// in Italian dov' should not be expanded to dove' because the elision
|
||||||
// requires the last vowel to be removed.
|
// requires the last vowel to be removed.
|
||||||
if (mAutoCorrectOn && primaryCode != '\'') {
|
if (mAutoCorrectOn && primaryCode != Keyboard.CODE_SINGLE_QUOTE) {
|
||||||
pickedDefault = pickDefaultSuggestion(primaryCode);
|
pickedDefault = pickDefaultSuggestion(primaryCode);
|
||||||
// Picked the suggestion by the space key. We consider this
|
|
||||||
// as "added an auto space".
|
|
||||||
if (primaryCode == Keyboard.CODE_SPACE) {
|
|
||||||
mJustAddedAutoSpace = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
commitTyped(ic);
|
commitTyped(ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) {
|
|
||||||
removeTrailingSpace();
|
|
||||||
mJustAddedAutoSpace = false;
|
|
||||||
}
|
|
||||||
sendKeyChar((char)primaryCode);
|
|
||||||
|
|
||||||
// Handle the case of ". ." -> " .." with auto-space if necessary
|
if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SPACE) {
|
||||||
// before changing the TextEntryState.
|
mJustAddedMagicSpace = false;
|
||||||
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) {
|
} else if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_ENTER) {
|
||||||
reswapPeriodAndSpace();
|
removeTrailingSpace();
|
||||||
|
mJustAddedMagicSpace = false;
|
||||||
|
sendKeyChar((char)primaryCode);
|
||||||
|
} else {
|
||||||
|
sendKeyChar((char)primaryCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEntryState.typedCharacter((char) primaryCode, true, x, y);
|
TextEntryState.typedCharacter((char) primaryCode, true, x, y);
|
||||||
|
|
||||||
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) {
|
if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER
|
||||||
|
&& mJustAddedMagicSpace) {
|
||||||
swapPunctuationAndSpace();
|
swapPunctuationAndSpace();
|
||||||
} else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
|
} else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
|
||||||
doubleSpace();
|
doubleSpace();
|
||||||
|
mJustAddedMagicSpace = false;
|
||||||
|
} else {
|
||||||
|
mJustAddedMagicSpace = false;
|
||||||
}
|
}
|
||||||
if (pickedDefault) {
|
if (pickedDefault) {
|
||||||
CharSequence typedWord = mWord.getTypedWord();
|
CharSequence typedWord = mWord.getTypedWord();
|
||||||
|
@ -1720,9 +1707,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
index, suggestions.mWords);
|
index, suggestions.mWords);
|
||||||
TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
|
TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
|
||||||
// Follow it with a space
|
// Follow it with a space
|
||||||
if (mAutoSpace && !recorrecting) {
|
if (mShouldInsertMagicSpace && !recorrecting) {
|
||||||
sendSpace();
|
sendMagicSpace();
|
||||||
mJustAddedAutoSpace = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should show the hint if the user pressed the first entry AND either:
|
// We should show the hint if the user pressed the first entry AND either:
|
||||||
|
@ -2005,8 +1991,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
return mSentenceSeparators.contains(String.valueOf((char)code));
|
return mSentenceSeparators.contains(String.valueOf((char)code));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSpace() {
|
private void sendMagicSpace() {
|
||||||
sendKeyChar((char)Keyboard.CODE_SPACE);
|
sendKeyChar((char)Keyboard.CODE_SPACE);
|
||||||
|
mJustAddedMagicSpace = true;
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2402,7 +2389,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
p.println(" mCorrectionMode=" + mCorrectionMode);
|
p.println(" mCorrectionMode=" + mCorrectionMode);
|
||||||
p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars);
|
p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars);
|
||||||
p.println(" mAutoCorrectOn=" + mAutoCorrectOn);
|
p.println(" mAutoCorrectOn=" + mAutoCorrectOn);
|
||||||
p.println(" mAutoSpace=" + mAutoSpace);
|
p.println(" mShouldInsertMagicSpace=" + mShouldInsertMagicSpace);
|
||||||
p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
|
p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn);
|
||||||
p.println(" TextEntryState.state=" + TextEntryState.getState());
|
p.println(" TextEntryState.state=" + TextEntryState.getState());
|
||||||
p.println(" mSoundOn=" + mSoundOn);
|
p.println(" mSoundOn=" + mSoundOn);
|
||||||
|
|
Loading…
Reference in New Issue