diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml index 0f0a74aea..7145af574 100644 --- a/java/res/values/keycodes.xml +++ b/java/res/values/keycodes.xml @@ -23,6 +23,9 @@ 9 10 32 + 45 + 39 + 34 -1 -2 -5 diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index c02c22494..fa2e0855d 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -63,6 +63,9 @@ public class Keyboard { public static final int CODE_TAB = '\t'; public static final int CODE_SPACE = ' '; 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 */ public static final int CODE_DUMMY = 0; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index fbfde97ef..4f1ad576d 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -626,7 +626,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private static boolean isQuoteCharacter(int c) { // Apostrophe, quotation mark. - if (c == '\'' || c == '"') + if (c == Keyboard.CODE_SINGLE_QUOTE || c == Keyboard.CODE_DOUBLE_QUOTE) return true; // \u2018: Left single quotation mark // \u2019: Right single quotation mark diff --git a/java/src/com/android/inputmethod/latin/ContactsDictionary.java b/java/src/com/android/inputmethod/latin/ContactsDictionary.java index bdb68cac7..b057cf4e3 100644 --- a/java/src/com/android/inputmethod/latin/ContactsDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsDictionary.java @@ -26,6 +26,8 @@ import android.provider.ContactsContract.Contacts; import android.text.TextUtils; import android.util.Log; +import com.android.inputmethod.keyboard.Keyboard; + public class ContactsDictionary extends ExpandableDictionary { private static final String[] PROJECTION = { @@ -123,8 +125,9 @@ public class ContactsDictionary extends ExpandableDictionary { for (j = i + 1; j < len; j++) { char c = name.charAt(j); - if (!(c == '-' || c == '\'' || - Character.isLetter(c))) { + if (!(c == Keyboard.CODE_DASH + || c == Keyboard.CODE_SINGLE_QUOTE + || Character.isLetter(c))) { break; } } diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 2dbd582f3..fcb634371 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -18,7 +18,6 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.res.AssetFileDescriptor; -import android.content.res.Configuration; import android.content.res.Resources; import android.util.Log; diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java index be2c6b21b..26391fe46 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -19,6 +19,8 @@ package com.android.inputmethod.latin; import android.content.Context; import android.os.AsyncTask; +import com.android.inputmethod.keyboard.Keyboard; + import java.util.LinkedList; /** @@ -41,8 +43,6 @@ public class ExpandableDictionary extends Dictionary { private int mMaxDepth; private int mInputLength; - private static final char QUOTE = '\''; - private boolean mRequiresReload; private boolean mUpdatingDictionary; @@ -304,7 +304,8 @@ public class ExpandableDictionary extends Dictionary { getWordsRec(children, codes, word, depth + 1, completion, snr, inputIndex, 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 word[depth] = c; if (children != null) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 105ec5a62..17a78d590 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -161,8 +161,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private ContactsDictionary mContactsDictionary; 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}. - private boolean mAutoSpace; + private boolean mShouldInsertMagicSpace; private boolean mInputTypeNoAutoCorrect; private boolean mIsSettingsSuggestionStripOn; private boolean mApplicationSpecifiedCompletionOn; @@ -174,7 +175,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private CharSequence mBestWord; private boolean mHasUncommittedTypedChars; 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 mRecorrectionEnabled; // 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); mHasUncommittedTypedChars = false; mDeleteCount = 0; - mJustAddedAutoSpace = false; + mJustAddedMagicSpace = false; loadSettings(attribute); if (mSubtypeSwitcher.isKeyboardMode()) { @@ -628,7 +631,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return; final int inputType = attribute.inputType; final int variation = inputType & InputType.TYPE_MASK_VARIATION; - mAutoSpace = false; + mShouldInsertMagicSpace = false; mInputTypeNoAutoCorrect = false; mIsSettingsSuggestionStripOn = false; mApplicationSpecifiedCompletionOn = false; @@ -643,9 +646,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } if (InputTypeCompatUtils.isEmailVariation(variation) || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { - mAutoSpace = false; + mShouldInsertMagicSpace = false; } else { - mAutoSpace = true; + mShouldInsertMagicSpace = true; } if (InputTypeCompatUtils.isEmailVariation(variation)) { mIsSettingsSuggestionStripOn = false; @@ -789,7 +792,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) { if (TextEntryState.isAcceptedDefault()) TextEntryState.reset(); - mJustAddedAutoSpace = false; // The user moved the cursor. + mJustAddedMagicSpace = false; // The user moved the cursor. } } mJustAccepted = false; @@ -1042,23 +1045,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.commitText(lastTwo.charAt(1) + " ", 1); ic.endBatchEdit(); 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.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); - mJustAddedAutoSpace = true; } else { mHandler.startDoubleSpacesTimer(); } @@ -1205,9 +1190,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar handleTab(); break; default: - if (primaryCode != Keyboard.CODE_ENTER) { - mJustAddedAutoSpace = false; - } if (isWordSeparator(primaryCode)) { handleSeparator(primaryCode, x, y); } else { @@ -1232,7 +1214,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.endBatchEdit(); mKeyboardSwitcher.updateShiftState(); mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); - mJustAddedAutoSpace = false; + mJustAddedMagicSpace = false; mEnteredText = text; } @@ -1342,6 +1324,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { mVoiceProxy.handleCharacter(); + if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SINGLE_QUOTE) { + removeTrailingSpace(); + } + if (primaryCode != Keyboard.CODE_ENTER) { + mJustAddedMagicSpace = false; + } + if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) { abortRecorrection(false); } @@ -1420,35 +1409,33 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // not to auto correct, but accept the typed word. For instance, // in Italian dov' should not be expanded to dove' because the elision // requires the last vowel to be removed. - if (mAutoCorrectOn && primaryCode != '\'') { + if (mAutoCorrectOn && primaryCode != Keyboard.CODE_SINGLE_QUOTE) { 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 { commitTyped(ic); } } - if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) { - removeTrailingSpace(); - mJustAddedAutoSpace = false; - } - sendKeyChar((char)primaryCode); - // Handle the case of ". ." -> " .." with auto-space if necessary - // before changing the TextEntryState. - if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) { - reswapPeriodAndSpace(); + if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_SPACE) { + mJustAddedMagicSpace = false; + } else if (mJustAddedMagicSpace && primaryCode == Keyboard.CODE_ENTER) { + removeTrailingSpace(); + mJustAddedMagicSpace = false; + sendKeyChar((char)primaryCode); + } else { + sendKeyChar((char)primaryCode); } TextEntryState.typedCharacter((char) primaryCode, true, x, y); - if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) { + if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER + && mJustAddedMagicSpace) { swapPunctuationAndSpace(); } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { doubleSpace(); + mJustAddedMagicSpace = false; + } else { + mJustAddedMagicSpace = false; } if (pickedDefault) { CharSequence typedWord = mWord.getTypedWord(); @@ -1720,9 +1707,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar index, suggestions.mWords); TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); // Follow it with a space - if (mAutoSpace && !recorrecting) { - sendSpace(); - mJustAddedAutoSpace = true; + if (mShouldInsertMagicSpace && !recorrecting) { + sendMagicSpace(); } // 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)); } - private void sendSpace() { + private void sendMagicSpace() { sendKeyChar((char)Keyboard.CODE_SPACE); + mJustAddedMagicSpace = true; mKeyboardSwitcher.updateShiftState(); } @@ -2402,7 +2389,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar p.println(" mCorrectionMode=" + mCorrectionMode); p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars); p.println(" mAutoCorrectOn=" + mAutoCorrectOn); - p.println(" mAutoSpace=" + mAutoSpace); + p.println(" mShouldInsertMagicSpace=" + mShouldInsertMagicSpace); p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); p.println(" TextEntryState.state=" + TextEntryState.getState()); p.println(" mSoundOn=" + mSoundOn);