diff options
Diffstat (limited to 'src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r-- | src/com/android/inputmethod/latin/LatinIME.java | 143 |
1 files changed, 120 insertions, 23 deletions
diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java index 240668ebb..8b76dbd39 100644 --- a/src/com/android/inputmethod/latin/LatinIME.java +++ b/src/com/android/inputmethod/latin/LatinIME.java @@ -71,14 +71,22 @@ public class LatinIME extends InputMethodService private static final int MSG_UPDATE_SUGGESTIONS = 0; private static final int MSG_START_TUTORIAL = 1; + private static final int MSG_UPDATE_SHIFT_STATE = 2; // How many continuous deletes at which to start deleting at a higher speed. private static final int DELETE_ACCELERATE_AT = 20; // Key events coming any faster than this are long-presses. - private static final int QUICK_PRESS = 200; + private static final int QUICK_PRESS = 200; + // Weight added to a user picking a new word from the suggestion strip + static final int FREQUENCY_FOR_PICKED = 3; + // Weight added to a user typing a new word that doesn't get corrected (or is reverted) + static final int FREQUENCY_FOR_TYPED = 1; + // A word that is frequently typed and get's promoted to the user dictionary, uses this + // frequency. + static final int FREQUENCY_FOR_AUTO_ADD = 250; - private static final int KEYCODE_ENTER = 10; - private static final int KEYCODE_SPACE = ' '; + static final int KEYCODE_ENTER = '\n'; + static final int KEYCODE_SPACE = ' '; // Contextual menu positions private static final int POS_SETTINGS = 0; @@ -95,6 +103,8 @@ public class LatinIME extends InputMethodService KeyboardSwitcher mKeyboardSwitcher; private UserDictionary mUserDictionary; + private ContactsDictionary mContactsDictionary; + private ExpandableDictionary mAutoDictionary; private String mLocale; @@ -114,6 +124,8 @@ public class LatinIME extends InputMethodService private boolean mQuickFixes; private boolean mShowSuggestions; private int mCorrectionMode; + private int mOrientation; + // Indicates whether the suggestion strip is to be on in landscape private boolean mJustAccepted; private CharSequence mJustRevertedSeparator; @@ -126,7 +138,8 @@ public class LatinIME extends InputMethodService private long mVibrateDuration; private AudioManager mAudioManager; - private final float FX_VOLUME = 1.0f; + // Align sound effect volume on music volume + private final float FX_VOLUME = -1.0f; private boolean mSilentMode; private String mWordSeparators; @@ -150,6 +163,9 @@ public class LatinIME extends InputMethodService } } break; + case MSG_UPDATE_SHIFT_STATE: + updateShiftKeyState(getCurrentInputEditorInfo()); + break; } } }; @@ -158,10 +174,12 @@ public class LatinIME extends InputMethodService super.onCreate(); //setStatusIcon(R.drawable.ime_qwerty); mKeyboardSwitcher = new KeyboardSwitcher(this); - initSuggest(getResources().getConfiguration().locale.toString()); - + final Configuration conf = getResources().getConfiguration(); + initSuggest(conf.locale.toString()); + mOrientation = conf.orientation; + mVibrateDuration = getResources().getInteger(R.integer.vibrate_duration_ms); - + // register to receive ringer mode changes for silent mode IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); registerReceiver(mReceiver, filter); @@ -172,13 +190,18 @@ public class LatinIME extends InputMethodService mSuggest = new Suggest(this, R.raw.main); mSuggest.setCorrectionMode(mCorrectionMode); mUserDictionary = new UserDictionary(this); + mContactsDictionary = new ContactsDictionary(this); + mAutoDictionary = new AutoDictionary(this); mSuggest.setUserDictionary(mUserDictionary); + mSuggest.setContactsDictionary(mContactsDictionary); + mSuggest.setAutoDictionary(mAutoDictionary); mWordSeparators = getResources().getString(R.string.word_separators); mSentenceSeparators = getResources().getString(R.string.sentence_separators); } @Override public void onDestroy() { mUserDictionary.close(); + mContactsDictionary.close(); unregisterReceiver(mReceiver); super.onDestroy(); } @@ -188,15 +211,24 @@ public class LatinIME extends InputMethodService if (!TextUtils.equals(conf.locale.toString(), mLocale)) { initSuggest(conf.locale.toString()); } + // If orientation changed while predicting, commit the change + if (conf.orientation != mOrientation) { + commitTyped(getCurrentInputConnection()); + mOrientation = conf.orientation; + } + if (mKeyboardSwitcher == null) { + mKeyboardSwitcher = new KeyboardSwitcher(this); + } + mKeyboardSwitcher.makeKeyboards(true); super.onConfigurationChanged(conf); } - + @Override public View onCreateInputView() { mInputView = (LatinKeyboardView) getLayoutInflater().inflate( R.layout.input, null); mKeyboardSwitcher.setInputView(mInputView); - mKeyboardSwitcher.makeKeyboards(); + mKeyboardSwitcher.makeKeyboards(true); mInputView.setOnKeyboardActionListener(this); mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, 0); return mInputView; @@ -204,7 +236,7 @@ public class LatinIME extends InputMethodService @Override public View onCreateCandidatesView() { - mKeyboardSwitcher.makeKeyboards(); + mKeyboardSwitcher.makeKeyboards(true); mCandidateViewContainer = (CandidateViewContainer) getLayoutInflater().inflate( R.layout.candidates, null); mCandidateViewContainer.initViews(); @@ -221,7 +253,7 @@ public class LatinIME extends InputMethodService return; } - mKeyboardSwitcher.makeKeyboards(); + mKeyboardSwitcher.makeKeyboards(false); TextEntryState.newSession(this); @@ -233,9 +265,8 @@ public class LatinIME extends InputMethodService switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, + mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS, attribute.imeOptions); - mKeyboardSwitcher.toggleSymbols(); break; case EditorInfo.TYPE_CLASS_PHONE: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, @@ -278,6 +309,17 @@ public class LatinIME extends InputMethodService disableAutoCorrect = true; } } + + // If NO_SUGGESTIONS is set, don't do prediction. + if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { + mPredictionOn = false; + disableAutoCorrect = true; + } + // If it's not multiline and the autoCorrect flag is not set, then don't correct + if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && + (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { + disableAutoCorrect = true; + } if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { mPredictionOn = false; mCompletionOn = true && isFullscreenMode(); @@ -309,7 +351,7 @@ public class LatinIME extends InputMethodService } mPredictionOn = mPredictionOn && mCorrectionMode > 0; checkTutorial(attribute.privateImeOptions); - if (TRACE) Debug.startMethodTracing("latinime"); + if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } @Override @@ -344,6 +386,7 @@ public class LatinIME extends InputMethodService TextEntryState.reset(); } mJustAccepted = false; + postUpdateShiftKeyState(); } @Override @@ -465,11 +508,17 @@ public class LatinIME extends InputMethodService } mCommittedLength = mComposing.length(); TextEntryState.acceptedTyped(mComposing); + mAutoDictionary.addWord(mComposing.toString(), FREQUENCY_FOR_TYPED); } updateSuggestions(); } } + private void postUpdateShiftKeyState() { + mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE); + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300); + } + public void updateShiftKeyState(EditorInfo attr) { InputConnection ic = getCurrentInputConnection(); if (attr != null && mInputView != null && mKeyboardSwitcher.isAlphabetMode() @@ -571,6 +620,9 @@ public class LatinIME extends InputMethodService // Cancel the just reverted state mJustRevertedSeparator = null; } + if (mKeyboardSwitcher.onKey(primaryCode)) { + changeKeyboardMode(); + } } public void onText(CharSequence text) { @@ -606,7 +658,7 @@ public class LatinIME extends InputMethodService } else { deleteChar = true; } - updateShiftKeyState(getCurrentInputEditorInfo()); + postUpdateShiftKeyState(); TextEntryState.backspace(); if (TextEntryState.getState() == TextEntryState.STATE_UNDO_COMMIT) { revertLastWord(deleteChar); @@ -640,7 +692,12 @@ public class LatinIME extends InputMethodService } } if (mInputView.isShifted()) { - primaryCode = Character.toUpperCase(primaryCode); + // TODO: This doesn't work with ß, need to fix it in the next release. + if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT + || keyCodes[0] > Character.MAX_CODE_POINT) { + return; + } + primaryCode = new String(keyCodes, 0, 1).toUpperCase().charAt(0); } if (mPredicting) { if (mInputView.isShifted() && mComposing.length() == 0) { @@ -756,7 +813,9 @@ public class LatinIME extends InputMethodService if (mCorrectionMode == Suggest.CORRECTION_FULL) { correctionAvailable |= typedWordValid; } - + // Don't auto-correct words with multiple capital letter + correctionAvailable &= !mWord.isMostlyCaps(); + mCandidateView.setSuggestions(stringList, false, typedWordValid, correctionAvailable); if (stringList.size() > 0) { if (correctionAvailable && !typedWordValid && stringList.size() > 1) { @@ -813,13 +872,17 @@ public class LatinIME extends InputMethodService suggestion = suggestion.toString().toUpperCase(); } else if (preferCapitalization() || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted())) { - suggestion = Character.toUpperCase(suggestion.charAt(0)) + suggestion = suggestion.toString().toUpperCase().charAt(0) + suggestion.subSequence(1, suggestion.length()).toString(); } InputConnection ic = getCurrentInputConnection(); if (ic != null) { ic.commitText(suggestion, 1); } + // Add the word to the auto dictionary if it's not a known word + if (mAutoDictionary.isValidWord(suggestion) || !mSuggest.isValidWord(suggestion)) { + mAutoDictionary.addWord(suggestion.toString(), FREQUENCY_FOR_PICKED); + } mPredicting = false; mCommittedLength = suggestion.length(); if (mCandidateView != null) { @@ -907,7 +970,7 @@ public class LatinIME extends InputMethodService } public void swipeDown() { - //handleClose(); + handleClose(); } public void swipeUp() { @@ -973,7 +1036,7 @@ public class LatinIME extends InputMethodService return; } if (mVibrator == null) { - mVibrator = new Vibrator(); + mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); } mVibrator.vibrate(mVibrateDuration); } @@ -998,7 +1061,12 @@ public class LatinIME extends InputMethodService void tutorialDone() { mTutorial = null; } - + + void promoteToUserDictionary(String word, int frequency) { + if (mUserDictionary.isValidWord(word)) return; + mUserDictionary.addWord(word, frequency); + } + private void launchSettings() { handleClose(); Intent intent = new Intent(); @@ -1044,7 +1112,8 @@ public class LatinIME extends InputMethodService launchSettings(); break; case POS_METHOD: - InputMethodManager.getInstance(LatinIME.this).showInputMethodPicker(); + ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)) + .showInputMethodPicker(); break; } } @@ -1107,7 +1176,35 @@ public class LatinIME extends InputMethodService for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); } - + + class AutoDictionary extends ExpandableDictionary { + // If the user touches a typed word 2 times or more, it will become valid. + private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED; + // If the user touches a typed word 5 times or more, it will be added to the user dict. + private static final int PROMOTION_THRESHOLD = 5 * FREQUENCY_FOR_PICKED; + + public AutoDictionary(Context context) { + super(context); + } + + @Override + public boolean isValidWord(CharSequence word) { + final int frequency = getWordFrequency(word); + return frequency > VALIDITY_THRESHOLD; + } + + @Override + public void addWord(String word, int addFrequency) { + final int length = word.length(); + // Don't add very short or very long words. + if (length < 2 || length > getMaxWordLength()) return; + super.addWord(word, addFrequency); + final int freq = getWordFrequency(word); + if (freq > PROMOTION_THRESHOLD) { + LatinIME.this.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD); + } + } + } } |