diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 2afb1c9fc..d6d0329bd 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -68,7 +68,6 @@ import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; -import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.widget.LinearLayout; @@ -152,6 +151,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private KeyboardSwitcher mKeyboardSwitcher; private SubtypeSwitcher mSubtypeSwitcher; private VoiceProxy mVoiceProxy; + private Recorrection mRecorrection; private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; @@ -176,7 +176,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // 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 private boolean mBigramSuggestionEnabled; // Prediction: use bigrams to predict the next word when there is no input for it yet @@ -403,6 +402,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar SubtypeSwitcher.init(this, prefs); KeyboardSwitcher.init(this, prefs); AccessibilityUtils.init(this, prefs); + Recorrection.init(this, prefs); super.onCreate(); @@ -411,19 +411,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mSubtypeSwitcher = SubtypeSwitcher.getInstance(); mKeyboardSwitcher = KeyboardSwitcher.getInstance(); mAccessibilityUtils = AccessibilityUtils.getInstance(); + mRecorrection = Recorrection.getInstance(); final Resources res = getResources(); mResources = res; - // If the option should not be shown, do not read the recorrection preference - // but always use the default setting defined in the resources. - if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) { - mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED, - res.getBoolean(R.bool.config_default_recorrection_enabled)); - } else { - mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled); - } - mConfigEnableShowSubtypeSettings = res.getBoolean( R.bool.config_enable_show_subtype_settings); mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( @@ -624,7 +616,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar inputView.setProximityCorrectionEnabled(true); inputView.setAccessibilityEnabled(accessibilityEnabled); // If we just entered a text field, maybe it has some old text that requires correction - checkRecorrectionOnStart(); + mRecorrection.checkRecorrectionOnStart(); inputView.setForeground(true); voiceIme.onStartInputView(inputView.getWindowToken()); @@ -687,34 +679,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private void checkRecorrectionOnStart() { - if (!mRecorrectionEnabled) return; - - final InputConnection ic = getCurrentInputConnection(); - if (ic == null) return; - // There could be a pending composing span. Clean it up first. - ic.finishComposingText(); - - if (isShowingSuggestionsStrip() && isSuggestionsRequested()) { - // First get the cursor position. This is required by setOldSuggestions(), so that - // it can pass the correct range to setComposingRegion(). At this point, we don't - // have valid values for mLastSelectionStart/End because onUpdateSelection() has - // not been called yet. - ExtractedTextRequest etr = new ExtractedTextRequest(); - etr.token = 0; // anything is fine here - ExtractedText et = ic.getExtractedText(etr, 0); - if (et == null) return; - - mLastSelectionStart = et.startOffset + et.selectionStart; - mLastSelectionEnd = et.startOffset + et.selectionEnd; - - // Then look for possible corrections in a delayed fashion - if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { - mHandler.postUpdateOldSuggestions(); - } - } - } - @Override public void onFinishInput() { super.onFinishInput(); @@ -808,34 +772,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mLastSelectionStart = newSelStart; mLastSelectionEnd = newSelEnd; - if (mRecorrectionEnabled && isShowingSuggestionsStrip()) { - // Don't look for corrections if the keyboard is not visible - if (mKeyboardSwitcher.isInputViewShown()) { - // Check if we should go in or out of correction mode. - if (isSuggestionsRequested() - && (candidatesStart == candidatesEnd || newSelStart != oldSelStart - || TextEntryState.isRecorrecting()) - && (newSelStart < newSelEnd - 1 || !mHasUncommittedTypedChars)) { - if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { - mHandler.cancelUpdateBigramPredictions(); - mHandler.postUpdateOldSuggestions(); - } else { - abortRecorrection(false); - // If showing the "touch again to save" hint, do not replace it. Else, - // show the bigrams if we are at the end of the text, punctuation otherwise. - if (mCandidateView != null - && !mCandidateView.isShowingAddToDictionaryHint()) { - InputConnection ic = getCurrentInputConnection(); - if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) { - if (!isShowingPunctuationList()) setPunctuationSuggestions(); - } else { - mHandler.postUpdateBigramPredictions(); - } - } - } - } - } - } + mRecorrection.updateRecorrectionSelection(mKeyboardSwitcher, + mCandidateView, candidatesStart, candidatesEnd, newSelStart, + newSelEnd, oldSelStart, mLastSelectionStart, + mLastSelectionEnd, mHasUncommittedTypedChars); + } + + public void setLastSelection(int start, int end) { + mLastSelectionStart = start; + mLastSelectionEnd = end; } /** @@ -848,7 +793,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar */ @Override public void onExtractedTextClicked() { - if (mRecorrectionEnabled && isSuggestionsRequested()) return; + if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; super.onExtractedTextClicked(); } @@ -864,7 +809,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar */ @Override public void onExtractedCursorMovement(int dx, int dy) { - if (mRecorrectionEnabled && isSuggestionsRequested()) return; + if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; super.onExtractedCursorMovement(dx, dy); } @@ -1318,7 +1263,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private void abortRecorrection(boolean force) { + public void abortRecorrection(boolean force) { if (force || TextEntryState.isRecorrecting()) { TextEntryState.onAbortRecorrection(); setCandidatesViewShown(isCandidateStripVisible()); @@ -1495,16 +1440,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mWordHistory.add(entry); } - private boolean isSuggestionsRequested() { + public boolean isSuggestionsRequested() { return mIsSettingsSuggestionStripOn && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); } - private boolean isShowingPunctuationList() { + public boolean isShowingPunctuationList() { return mSuggestPuncList == mCandidateView.getSuggestions(); } - private boolean isShowingSuggestionsStrip() { + public boolean isShowingSuggestionsStrip() { return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE && mOrientation == Configuration.ORIENTATION_PORTRAIT); @@ -1877,7 +1822,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private void setPunctuationSuggestions() { + public void setPunctuationSuggestions() { setSuggestions(mSuggestPuncList); setCandidatesViewShown(isCandidateStripVisible()); } @@ -1925,7 +1870,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private boolean isCursorTouchingWord() { + public boolean isCursorTouchingWord() { InputConnection ic = getCurrentInputConnection(); if (ic == null) return false; CharSequence toLeft = ic.getTextBeforeCursor(1, 0); diff --git a/java/src/com/android/inputmethod/latin/Recorrection.java b/java/src/com/android/inputmethod/latin/Recorrection.java new file mode 100644 index 000000000..71d3bdddc --- /dev/null +++ b/java/src/com/android/inputmethod/latin/Recorrection.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2011 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. + */ + +package com.android.inputmethod.latin; + +import com.android.inputmethod.keyboard.KeyboardSwitcher; + +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.text.TextUtils; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Manager of re-correction functionalities + */ +public class Recorrection { + private static final Recorrection sInstance = new Recorrection(); + + private LatinIME mService; + private boolean mRecorrectionEnabled = false; + + public static Recorrection getInstance() { + return sInstance; + } + + public static void init(LatinIME context, SharedPreferences prefs) { + if (context == null || prefs == null) { + return; + } + sInstance.initInternal(context, prefs); + } + + private Recorrection() { + } + + public boolean isRecorrectionEnabled() { + return mRecorrectionEnabled; + } + + private void initInternal(LatinIME context, SharedPreferences prefs) { + final Resources res = context.getResources(); + // If the option should not be shown, do not read the re-correction preference + // but always use the default setting defined in the resources. + if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) { + mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED, + res.getBoolean(R.bool.config_default_recorrection_enabled)); + } else { + mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled); + } + mService = context; + } + + public void checkRecorrectionOnStart() { + if (!mRecorrectionEnabled) return; + + final InputConnection ic = mService.getCurrentInputConnection(); + if (ic == null) return; + // There could be a pending composing span. Clean it up first. + ic.finishComposingText(); + + if (mService.isShowingSuggestionsStrip() && mService.isSuggestionsRequested()) { + // First get the cursor position. This is required by setOldSuggestions(), so that + // it can pass the correct range to setComposingRegion(). At this point, we don't + // have valid values for mLastSelectionStart/End because onUpdateSelection() has + // not been called yet. + ExtractedTextRequest etr = new ExtractedTextRequest(); + etr.token = 0; // anything is fine here + ExtractedText et = ic.getExtractedText(etr, 0); + if (et == null) return; + mService.setLastSelection( + et.startOffset + et.selectionStart, et.startOffset + et.selectionEnd); + + // Then look for possible corrections in a delayed fashion + if (!TextUtils.isEmpty(et.text) && mService.isCursorTouchingWord()) { + mService.mHandler.postUpdateOldSuggestions(); + } + } + } + + public void updateRecorrectionSelection(KeyboardSwitcher keyboardSwitcher, + CandidateView candidateView, int candidatesStart, int candidatesEnd, int newSelStart, + int newSelEnd, int oldSelStart, int lastSelectionStart, + int lastSelectionEnd, boolean hasUncommittedTypedChars) { + if (mRecorrectionEnabled && mService.isShowingSuggestionsStrip()) { + // Don't look for corrections if the keyboard is not visible + if (keyboardSwitcher.isInputViewShown()) { + // Check if we should go in or out of correction mode. + if (mService.isSuggestionsRequested() + && (candidatesStart == candidatesEnd || newSelStart != oldSelStart + || TextEntryState.isRecorrecting()) + && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) { + if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) { + mService.mHandler.cancelUpdateBigramPredictions(); + mService.mHandler.postUpdateOldSuggestions(); + } else { + mService.abortRecorrection(false); + // If showing the "touch again to save" hint, do not replace it. Else, + // show the bigrams if we are at the end of the text, punctuation otherwise. + if (candidateView != null + && !candidateView.isShowingAddToDictionaryHint()) { + InputConnection ic = mService.getCurrentInputConnection(); + if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) { + if (!mService.isShowingPunctuationList()) { + mService.setPunctuationSuggestions(); + } + } else { + mService.mHandler.postUpdateBigramPredictions(); + } + } + } + } + } + } + } +}