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: I245f396c34dd0af820bca91edc4ec363238a4ae4
main
Jean Chalard 2011-04-28 15:39:39 +09:00
parent 3bf6fbb6b8
commit 0730bbfbf5
7 changed files with 53 additions and 57 deletions

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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) {

View File

@ -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);