Merge "Enable auto-correction only if there is a significant size main dictionary."
commit
a052b69b47
|
@ -38,6 +38,7 @@ using namespace android;
|
||||||
static jfieldID sDescriptorField;
|
static jfieldID sDescriptorField;
|
||||||
static jfieldID sAssetManagerNativeField;
|
static jfieldID sAssetManagerNativeField;
|
||||||
static jmethodID sAddWordMethod;
|
static jmethodID sAddWordMethod;
|
||||||
|
static jfieldID sDictLength;
|
||||||
|
|
||||||
//
|
//
|
||||||
// helper function to throw an exception
|
// helper function to throw an exception
|
||||||
|
@ -79,6 +80,7 @@ static jint latinime_BinaryDictionary_open
|
||||||
}
|
}
|
||||||
Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier);
|
Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier);
|
||||||
dictionary->setAsset(dictAsset);
|
dictionary->setAsset(dictAsset);
|
||||||
|
env->SetIntField(object, sDictLength, (jint) dictAsset->getLength());
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(resourceString, resourcePath);
|
env->ReleaseStringUTFChars(resourceString, resourcePath);
|
||||||
return (jint) dictionary;
|
return (jint) dictionary;
|
||||||
|
@ -176,6 +178,14 @@ static int registerNatives(JNIEnv *env)
|
||||||
}
|
}
|
||||||
sAssetManagerNativeField = env->GetFieldID(clazz, "mObject", "I");
|
sAssetManagerNativeField = env->GetFieldID(clazz, "mObject", "I");
|
||||||
|
|
||||||
|
// Get the field pointer for the dictionary length
|
||||||
|
clazz = env->FindClass(kClassPathName);
|
||||||
|
if (clazz == NULL) {
|
||||||
|
LOGE("Can't find %s", kClassPathName);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sDictLength = env->GetFieldID(clazz, "mDictLength", "I");
|
||||||
|
|
||||||
return registerNativeMethods(env,
|
return registerNativeMethods(env,
|
||||||
kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
|
kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Copyright (C) 2009 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string>
|
||||||
|
</resources>
|
|
@ -31,7 +31,9 @@
|
||||||
<Key android:keyLabel="ц"/>
|
<Key android:keyLabel="ц"/>
|
||||||
<Key android:keyLabel="у"/>
|
<Key android:keyLabel="у"/>
|
||||||
<Key android:keyLabel="к"/>
|
<Key android:keyLabel="к"/>
|
||||||
<Key android:keyLabel="е"/>
|
<Key android:keyLabel="е"
|
||||||
|
android:popupKeyboard="@xml/kbd_popup_template"
|
||||||
|
android:popupCharacters="ё" />
|
||||||
<Key android:keyLabel="н"/>
|
<Key android:keyLabel="н"/>
|
||||||
<Key android:keyLabel="г"/>
|
<Key android:keyLabel="г"/>
|
||||||
<Key android:keyLabel="ш"/>
|
<Key android:keyLabel="ш"/>
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class BinaryDictionary extends Dictionary {
|
||||||
private static final boolean ENABLE_MISSED_CHARACTERS = true;
|
private static final boolean ENABLE_MISSED_CHARACTERS = true;
|
||||||
|
|
||||||
private int mNativeDict;
|
private int mNativeDict;
|
||||||
|
private int mDictLength; // This value is set from native code, don't change the name!!!!
|
||||||
private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
|
private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
|
||||||
private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
|
private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
|
||||||
private int[] mFrequencies = new int[MAX_WORDS];
|
private int[] mFrequencies = new int[MAX_WORDS];
|
||||||
|
@ -125,6 +126,10 @@ public class BinaryDictionary extends Dictionary {
|
||||||
return isValidWordNative(mNativeDict, chars, chars.length);
|
return isValidWordNative(mNativeDict, chars, chars.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return mDictLength; // This value is initialized on the call to openNative()
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void close() {
|
public synchronized void close() {
|
||||||
if (mNativeDict != 0) {
|
if (mNativeDict != 0) {
|
||||||
|
|
|
@ -126,7 +126,9 @@ public class LatinIME extends InputMethodService
|
||||||
private CharSequence mBestWord;
|
private CharSequence mBestWord;
|
||||||
private boolean mPredictionOn;
|
private boolean mPredictionOn;
|
||||||
private boolean mCompletionOn;
|
private boolean mCompletionOn;
|
||||||
|
private boolean mHasDictionary;
|
||||||
private boolean mAutoSpace;
|
private boolean mAutoSpace;
|
||||||
|
private boolean mAutoCorrectEnabled;
|
||||||
private boolean mAutoCorrectOn;
|
private boolean mAutoCorrectOn;
|
||||||
private boolean mCapsLock;
|
private boolean mCapsLock;
|
||||||
private boolean mVibrateOn;
|
private boolean mVibrateOn;
|
||||||
|
@ -224,7 +226,6 @@ public class LatinIME extends InputMethodService
|
||||||
mSuggest.close();
|
mSuggest.close();
|
||||||
}
|
}
|
||||||
mSuggest = new Suggest(this, R.raw.main);
|
mSuggest = new Suggest(this, R.raw.main);
|
||||||
mSuggest.setCorrectionMode(mCorrectionMode);
|
|
||||||
mUserDictionary = new UserDictionary(this);
|
mUserDictionary = new UserDictionary(this);
|
||||||
if (mContactsDictionary == null) {
|
if (mContactsDictionary == null) {
|
||||||
mContactsDictionary = new ContactsDictionary(this);
|
mContactsDictionary = new ContactsDictionary(this);
|
||||||
|
@ -236,7 +237,7 @@ public class LatinIME extends InputMethodService
|
||||||
mSuggest.setUserDictionary(mUserDictionary);
|
mSuggest.setUserDictionary(mUserDictionary);
|
||||||
mSuggest.setContactsDictionary(mContactsDictionary);
|
mSuggest.setContactsDictionary(mContactsDictionary);
|
||||||
mSuggest.setAutoDictionary(mAutoDictionary);
|
mSuggest.setAutoDictionary(mAutoDictionary);
|
||||||
|
updateCorrectionMode();
|
||||||
mWordSeparators = mResources.getString(R.string.word_separators);
|
mWordSeparators = mResources.getString(R.string.word_separators);
|
||||||
mSentenceSeparators = mResources.getString(R.string.sentence_separators);
|
mSentenceSeparators = mResources.getString(R.string.sentence_separators);
|
||||||
|
|
||||||
|
@ -304,7 +305,7 @@ public class LatinIME extends InputMethodService
|
||||||
|
|
||||||
TextEntryState.newSession(this);
|
TextEntryState.newSession(this);
|
||||||
|
|
||||||
boolean disableAutoCorrect = false;
|
mInputTypeNoAutoCorrect = false;
|
||||||
mPredictionOn = false;
|
mPredictionOn = false;
|
||||||
mCompletionOn = false;
|
mCompletionOn = false;
|
||||||
mCompletions = null;
|
mCompletions = null;
|
||||||
|
@ -353,19 +354,19 @@ public class LatinIME extends InputMethodService
|
||||||
// If it's a browser edit field and auto correct is not ON explicitly, then
|
// If it's a browser edit field and auto correct is not ON explicitly, then
|
||||||
// disable auto correction, but keep suggestions on.
|
// disable auto correction, but keep suggestions on.
|
||||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
|
||||||
disableAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If NO_SUGGESTIONS is set, don't do prediction.
|
// If NO_SUGGESTIONS is set, don't do prediction.
|
||||||
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
|
||||||
mPredictionOn = false;
|
mPredictionOn = false;
|
||||||
disableAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
// If it's not multiline and the autoCorrect flag is not set, then don't correct
|
// 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 &&
|
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
|
||||||
(attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
(attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
|
||||||
disableAutoCorrect = true;
|
mInputTypeNoAutoCorrect = true;
|
||||||
}
|
}
|
||||||
if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
|
||||||
mPredictionOn = false;
|
mPredictionOn = false;
|
||||||
|
@ -385,17 +386,13 @@ public class LatinIME extends InputMethodService
|
||||||
setCandidatesViewShown(false);
|
setCandidatesViewShown(false);
|
||||||
if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false);
|
if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
// Override auto correct
|
|
||||||
if (disableAutoCorrect) {
|
// If the dictionary is not big enough, don't auto correct
|
||||||
mAutoCorrectOn = false;
|
mHasDictionary = mSuggest.hasMainDictionary();
|
||||||
if (mCorrectionMode == Suggest.CORRECTION_FULL) {
|
|
||||||
mCorrectionMode = Suggest.CORRECTION_BASIC;
|
updateCorrectionMode();
|
||||||
}
|
|
||||||
}
|
|
||||||
mInputView.setProximityCorrectionEnabled(true);
|
mInputView.setProximityCorrectionEnabled(true);
|
||||||
if (mSuggest != null) {
|
|
||||||
mSuggest.setCorrectionMode(mCorrectionMode);
|
|
||||||
}
|
|
||||||
mPredictionOn = mPredictionOn && mCorrectionMode > 0;
|
mPredictionOn = mPredictionOn && mCorrectionMode > 0;
|
||||||
checkTutorial(attribute.privateImeOptions);
|
checkTutorial(attribute.privateImeOptions);
|
||||||
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
|
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
|
||||||
|
@ -1150,6 +1147,18 @@ public class LatinIME extends InputMethodService
|
||||||
mUserDictionary.addWord(word, frequency);
|
mUserDictionary.addWord(word, frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateCorrectionMode() {
|
||||||
|
mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
|
||||||
|
mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
|
||||||
|
&& !mInputTypeNoAutoCorrect && mHasDictionary;
|
||||||
|
mCorrectionMode = mAutoCorrectOn
|
||||||
|
? Suggest.CORRECTION_FULL
|
||||||
|
: (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
|
||||||
|
if (mSuggest != null) {
|
||||||
|
mSuggest.setCorrectionMode(mCorrectionMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void launchSettings() {
|
private void launchSettings() {
|
||||||
handleClose();
|
handleClose();
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
|
@ -1169,12 +1178,9 @@ public class LatinIME extends InputMethodService
|
||||||
// will continue to work
|
// will continue to work
|
||||||
if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
|
if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
|
||||||
mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes;
|
mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes;
|
||||||
boolean autoComplete = sp.getBoolean(PREF_AUTO_COMPLETE,
|
mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE,
|
||||||
mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
|
mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
|
||||||
mAutoCorrectOn = mSuggest != null && (autoComplete || mQuickFixes);
|
updateCorrectionMode();
|
||||||
mCorrectionMode = autoComplete
|
|
||||||
? Suggest.CORRECTION_FULL
|
|
||||||
: (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
|
|
||||||
String languageList = sp.getString(PREF_SELECTED_LANGUAGES, null);
|
String languageList = sp.getString(PREF_SELECTED_LANGUAGES, null);
|
||||||
updateSelectedLanguages(languageList);
|
updateSelectedLanguages(languageList);
|
||||||
}
|
}
|
||||||
|
@ -1274,6 +1280,7 @@ public class LatinIME extends InputMethodService
|
||||||
private static final int CPS_BUFFER_SIZE = 16;
|
private static final int CPS_BUFFER_SIZE = 16;
|
||||||
private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
|
private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
|
||||||
private int mCpsIndex;
|
private int mCpsIndex;
|
||||||
|
private boolean mInputTypeNoAutoCorrect;
|
||||||
|
|
||||||
private void measureCps() {
|
private void measureCps() {
|
||||||
if (!LatinIME.PERF_DEBUG) return;
|
if (!LatinIME.PERF_DEBUG) return;
|
||||||
|
|
|
@ -37,7 +37,9 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
public static final int CORRECTION_BASIC = 1;
|
public static final int CORRECTION_BASIC = 1;
|
||||||
public static final int CORRECTION_FULL = 2;
|
public static final int CORRECTION_FULL = 2;
|
||||||
|
|
||||||
private Dictionary mMainDict;
|
private static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
|
||||||
|
|
||||||
|
private BinaryDictionary mMainDict;
|
||||||
|
|
||||||
private Dictionary mUserDictionary;
|
private Dictionary mUserDictionary;
|
||||||
|
|
||||||
|
@ -49,9 +51,7 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
|
|
||||||
private int[] mPriorities = new int[mPrefMaxSuggestions];
|
private int[] mPriorities = new int[mPrefMaxSuggestions];
|
||||||
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
|
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
|
||||||
private boolean mIncludeTypedWordIfValid;
|
|
||||||
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
|
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
|
||||||
private Context mContext;
|
|
||||||
private boolean mHaveCorrection;
|
private boolean mHaveCorrection;
|
||||||
private CharSequence mOriginalWord;
|
private CharSequence mOriginalWord;
|
||||||
private String mLowerOriginalWord;
|
private String mLowerOriginalWord;
|
||||||
|
@ -60,7 +60,6 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
|
|
||||||
|
|
||||||
public Suggest(Context context, int dictionaryResId) {
|
public Suggest(Context context, int dictionaryResId) {
|
||||||
mContext = context;
|
|
||||||
mMainDict = new BinaryDictionary(context, dictionaryResId);
|
mMainDict = new BinaryDictionary(context, dictionaryResId);
|
||||||
for (int i = 0; i < mPrefMaxSuggestions; i++) {
|
for (int i = 0; i < mPrefMaxSuggestions; i++) {
|
||||||
StringBuilder sb = new StringBuilder(32);
|
StringBuilder sb = new StringBuilder(32);
|
||||||
|
@ -76,6 +75,10 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
mCorrectionMode = mode;
|
mCorrectionMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasMainDictionary() {
|
||||||
|
return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
|
* Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
|
||||||
* before the main dictionary, if set.
|
* before the main dictionary, if set.
|
||||||
|
@ -155,7 +158,6 @@ public class Suggest implements Dictionary.WordCallback {
|
||||||
mHaveCorrection = false;
|
mHaveCorrection = false;
|
||||||
collectGarbage();
|
collectGarbage();
|
||||||
Arrays.fill(mPriorities, 0);
|
Arrays.fill(mPriorities, 0);
|
||||||
mIncludeTypedWordIfValid = includeTypedWordIfValid;
|
|
||||||
|
|
||||||
// Save a lowercase version of the original word
|
// Save a lowercase version of the original word
|
||||||
mOriginalWord = wordComposer.getTypedWord();
|
mOriginalWord = wordComposer.getTypedWord();
|
||||||
|
|
Loading…
Reference in New Issue