LatinIME.java revision 85996b472a0ec5fc31e57c52aa46c8c7794689bb
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * 4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at 7a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker * 10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under 14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License. 15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 195a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 205a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener; 215a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardId; 22571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardSwitcher; 235a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardView; 24de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboard; 255a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboardView; 269502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaokaimport com.android.inputmethod.latin.Utils.RingCharBuffer; 27409220583333bdf06290dd9fd42f91b5c0d1b11asatokimport com.android.inputmethod.voice.VoiceIMEConnector; 28388ce92ab8a635c5ad44620dad59baf05dfea510Amith Yamasani 29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.app.AlertDialog; 30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.BroadcastReceiver; 31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context; 32923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.DialogInterface; 33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Intent; 34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.IntentFilter; 35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.SharedPreferences; 36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.res.Configuration; 3736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.InputMethodService; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.media.AudioManager; 40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Debug; 41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler; 42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message; 43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.SystemClock; 444174655e23734563775acb9e1e644b31b9e72fa5Ken Wakasaimport android.os.Vibrator; 45bf96661d33d0126adb60a48880ceba1ff055d4a4satokimport android.preference.PreferenceActivity; 46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.preference.PreferenceManager; 47e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaokaimport android.text.InputType; 48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.text.TextUtils; 49979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.util.DisplayMetrics; 50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Log; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.PrintWriterPrinter; 52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Printer; 53e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.view.Gravity; 5466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasaniimport android.view.HapticFeedbackConstants; 55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.KeyEvent; 56e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.view.LayoutInflater; 57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 588e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewGroup; 598e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewParent; 60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.Window; 61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.WindowManager; 62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 631b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaokaimport android.view.inputmethod.CorrectionInfo; 64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.EditorInfo; 65466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport android.view.inputmethod.ExtractedText; 66466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport android.view.inputmethod.ExtractedTextRequest; 67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.InputConnection; 68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 690ed7191b4d1013a0b9d2fd1f26733dee7364871dsatokimport android.view.inputmethod.InputMethodSubtype; 709e347d3d448e48229c46aad394ec9bd60cd5807bsatokimport android.widget.FrameLayout; 71e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.widget.HorizontalScrollView; 7240ac45ebdcd71940394dda00371d4847f7db0f26Ken Wakasaimport android.widget.LinearLayout; 73923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 74466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.FileDescriptor; 75466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.PrintWriter; 76466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.ArrayList; 77b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimodaimport java.util.Arrays; 78466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.Locale; 79466741d8a78965b8509bf527344f289e50873092Mike LeBeau 80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Input method implementation for Qwerty'ish keyboard. 82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 8355b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaokapublic class LatinIME extends InputMethodService implements KeyboardActionListener, 84e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka SharedPreferences.OnSharedPreferenceChangeListener { 85466741d8a78965b8509bf527344f289e50873092Mike LeBeau private static final String TAG = "LatinIME"; 86979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final boolean PERF_DEBUG = false; 87409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean TRACE = false; 88910b73127fa207dd26ec8124000262523b0aac0csatok private static boolean DEBUG = LatinImeLogger.sDBG; 89a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 90fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_SUGGESTIONS = 180; 91fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300; 92d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int DELAY_UPDATE_SHIFT_STATE = 300; 939e347d3d448e48229c46aad394ec9bd60cd5807bsatok private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; 94fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa 95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // How many continuous deletes at which to start deleting at a higher speed. 96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int DELETE_ACCELERATE_AT = 20; 97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Key events coming any faster than this are long-presses. 98d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani private static final int QUICK_PRESS = 200; 99a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1007599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private int mSuggestionVisibility; 1017599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE 1027599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_value; 1037599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 1047599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_only_portrait_value; 1057599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_HIDE_VALUE 1067599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_hide_value; 1077599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1087599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int[] SUGGESTION_VISIBILITY_VALUE_ARRAY = new int[] { 1097599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_VALUE, 1107599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE, 1117599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_HIDE_VALUE 1127599cfea4a2d56f4779452ec8e8742f7b9629cc0satok }; 1137599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 114e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka private View mCandidateViewContainer; 115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CandidateView mCandidateView; 116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Suggest mSuggest; 1171b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private CompletionInfo[] mApplicationSpecifiedCompletions; 118a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AlertDialog mOptionsDialog; 120a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 12179efbed76f638be298493107fa2d0cd1b5eb529esatok private InputMethodManager mImm; 1222fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private Resources mResources; 1232fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private SharedPreferences mPrefs; 1242fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private String mInputMethodId; 12571c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private KeyboardSwitcher mKeyboardSwitcher; 1260ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 127409220583333bdf06290dd9fd42f91b5c0d1b11asatok private VoiceIMEConnector mVoiceConnector; 128a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private UserDictionary mUserDictionary; 130979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private UserBigramDictionary mUserBigramDictionary; 1312bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer private ContactsDictionary mContactsDictionary; 1324ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani private AutoDictionary mAutoDictionary; 13336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 134c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // These variables are initialized according to the {@link EditorInfo#inputType}. 135c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mAutoSpace; 136c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mInputTypeNoAutoCorrect; 137c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mIsSettingsSuggestionStripOn; 138c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mApplicationSpecifiedCompletionOn; 139c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 14071c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final StringBuilder mComposing = new StringBuilder(); 141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private WordComposer mWord = new WordComposer(); 142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CharSequence mBestWord; 1439fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean mHasValidSuggestions; 144e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mHasDictionary; 1459a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private boolean mJustAddedAutoSpace; 146e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mAutoCorrectEnabled; 14766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok private boolean mReCorrectionEnabled; 148979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mBigramSuggestionEnabled; 149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCorrectOn; 150923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mVibrateOn; 151923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSoundOn; 152979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mPopupOn; 153923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCap; 1546e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani private boolean mQuickFixes; 1552fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private boolean mConfigEnableShowSubtypeSettings; 156363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka private boolean mConfigSwipeDownDismissKeyboardEnabled; 157de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; 158de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDurationOfFadeoutLanguageOnSpacebar; 159d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; 160de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka // For example, to deal with status bar on tablet. 161de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka private int mKeyboardBottomRowVerticalCorrection; 162409220583333bdf06290dd9fd42f91b5c0d1b11asatok 16379efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCorrectionMode; 16479efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCommittedLength; 16579efbed76f638be298493107fa2d0cd1b5eb529esatok private int mOrientation; 166979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Keep track of the last selection range to decide if we need to show word alternatives 16779efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionStart; 16879efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionEnd; 1697e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords mSuggestPuncList; 170979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Indicates whether the suggestion strip is to be on in landscape 172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mJustAccepted; 173c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa private boolean mJustReverted; 174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mDeleteCount; 175923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastKeyTime; 176a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AudioManager mAudioManager; 1782296317b8f0209789f797ac8a2fcb70e03f6d001Eric Laurent // Align sound effect volume on music volume 17971c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private static final float FX_VOLUME = -1.0f; 180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSilentMode; 181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 182979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /* package */ String mWordSeparators; 183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private String mSentenceSeparators; 184979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private String mSuggestPuncs; 185409220583333bdf06290dd9fd42f91b5c0d1b11asatok // TODO: Move this flag to VoiceIMEConnector 18681c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani private boolean mConfigurationChanging; 187466741d8a78965b8509bf527344f289e50873092Mike LeBeau 188dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Keeps track of most recently inserted text (multi-character key) for reverting 189dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private CharSequence mEnteredText; 190979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mRefreshKeyboardRequired; 191dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 19271c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>(); 193979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 194979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public abstract static class WordAlternatives { 195979f8690967ff5409fe18f5085858ccdb8e0ccf1satok protected CharSequence mChosenWord; 1964f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 197979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public WordAlternatives() { 198979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Nothing 199979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 200979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 201979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public WordAlternatives(CharSequence chosenWord) { 202979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mChosenWord = chosenWord; 203979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 204979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 205979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 206979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public int hashCode() { 207979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mChosenWord.hashCode(); 208979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 209979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 210979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public abstract CharSequence getOriginalWord(); 211979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 212979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public CharSequence getChosenWord() { 213979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mChosenWord; 214979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 215979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2167e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public abstract SuggestedWords.Builder getAlternatives(); 217979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 218979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 219979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public class TypedWordAlternatives extends WordAlternatives { 220979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private WordComposer word; 221979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 222979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public TypedWordAlternatives() { 223979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Nothing 224979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 225979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 226979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) { 227979f8690967ff5409fe18f5085858ccdb8e0ccf1satok super(chosenWord); 228979f8690967ff5409fe18f5085858ccdb8e0ccf1satok word = wordComposer; 229979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 230979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 231979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 232979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public CharSequence getOriginalWord() { 233979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return word.getTypedWord(); 234979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 235979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 236979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 2377e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public SuggestedWords.Builder getAlternatives() { 238979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return getTypedSuggestions(word); 239979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 240979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 24136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 242571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka public final UIHandler mHandler = new UIHandler(); 243d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 244409220583333bdf06290dd9fd42f91b5c0d1b11asatok public class UIHandler extends Handler { 245d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SUGGESTIONS = 0; 246d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; 247d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SHIFT_STATE = 2; 248d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_VOICE_RESULTS = 3; 249de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; 250de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; 251d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 252923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 253923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void handleMessage(Message msg) { 254de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 255de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = switcher.getInputView(); 256923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 257d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SUGGESTIONS: 258d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka updateSuggestions(); 259d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 260d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_OLD_SUGGESTIONS: 261d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka setOldSuggestions(); 262d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 263d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SHIFT_STATE: 264de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka switcher.updateShiftState(); 265d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 266d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_VOICE_RESULTS: 267e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mVoiceConnector.handleVoiceResults(preferCapitalization() 268de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); 269de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 270de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: 271de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 27266432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 273d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, 27466432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka (LatinKeyboard)msg.obj); 275de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), 276de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar); 277de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 278de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: 279de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 28066432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 281d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); 282d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 283923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 285d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 286d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateSuggestions() { 287d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 288d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), DELAY_UPDATE_SUGGESTIONS); 289d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 290d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 291d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateSuggestions() { 292d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 293d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 294d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 295d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public boolean hasPendingUpdateSuggestions() { 296d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka return hasMessages(MSG_UPDATE_SUGGESTIONS); 297d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 298d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 299d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateOldSuggestions() { 300d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 301d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 302d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka DELAY_UPDATE_OLD_SUGGESTIONS); 303d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 304d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 305d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateOldSuggestions() { 306d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 307d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 308d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 309d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateShiftKeyState() { 310d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 311d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), DELAY_UPDATE_SHIFT_STATE); 312d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 313d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 314d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateShiftState() { 315d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 316d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 317d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 318d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void updateVoiceResults() { 319d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessage(obtainMessage(MSG_VOICE_RESULTS)); 320d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 321de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka 322d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka public void startDisplayLanguageOnSpacebar(boolean localeChanged) { 323de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); 324de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); 325de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 326de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) { 327de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboard keyboard = inputView.getLatinKeyboard(); 328de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is never displayed when the delay is zero. 329de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) 330d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f 331d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); 332de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is always displayed when the delay is negative. 333d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { 334de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), 335de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar); 336de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 337de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 338de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 339d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3417e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 3427e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka public void onCreate() { 34327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 34427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mPrefs = prefs; 34527d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa LatinImeLogger.init(this, prefs); 34627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.init(this, prefs); 34727d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa KeyboardSwitcher.init(this, prefs); 348363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 349923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onCreate(); 350363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 35179efbed76f638be298493107fa2d0cd1b5eb529esatok mImm = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)); 3522fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mInputMethodId = Utils.getInputMethodId(mImm, getApplicationInfo().packageName); 3530ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 3540ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mKeyboardSwitcher = KeyboardSwitcher.getInstance(); 355363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 356363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka final Resources res = getResources(); 357363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mResources = res; 358fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard 359fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard // If the option should not be shown, do not read the recorrection preference 360fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard // but always use the default setting defined in the resources. 361fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) { 362fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard mReCorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED, 363fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard res.getBoolean(R.bool.default_recorrection_enabled)); 364fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard } else { 365fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard mReCorrectionEnabled = res.getBoolean(R.bool.default_recorrection_enabled); 366fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard } 367fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard 3682fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mConfigEnableShowSubtypeSettings = res.getBoolean( 3692fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka R.bool.config_enable_show_subtype_settings); 370363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( 371363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka R.bool.config_swipe_down_dismiss_keyboard_enabled); 372de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( 373de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_delay_before_fadeout_language_on_spacebar); 374de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( 375de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_duration_of_fadeout_language_on_spacebar); 376d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( 37766432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; 378de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka mKeyboardBottomRowVerticalCorrection = (int)res.getDimension( 379de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka R.dimen.keyboard_bottom_row_vertical_correction); 380979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3819502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 382979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 3839502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 384979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 3850ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 386979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 387979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 3889502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait("InitSuggest", e); 389979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 390979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 391979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 392363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mOrientation = res.getConfiguration().orientation; 3936a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani initSuggestPuncList(); 394b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 395923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // register to receive ringer mode changes for silent mode 396923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); 397923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project registerReceiver(mReceiver, filter); 39827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mVoiceConnector = VoiceIMEConnector.init(this, prefs, mHandler); 3993f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani prefs.registerOnSharedPreferenceChangeListener(this); 400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 40136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 402979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 403458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa * Returns a main dictionary resource id 404458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa * @return main dictionary resource id 405979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 406458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa public static int getMainDictionaryResourceId(Resources res) { 407458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final String MAIN_DIC_NAME = "main"; 408979f8690967ff5409fe18f5085858ccdb8e0ccf1satok String packageName = LatinIME.class.getPackage().getName(); 409458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); 410979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 411979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4120ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void initSuggest() { 4130ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 4144ab730dbd34fad323063f2ffd31ce33de746668dsatok String locale = mSubtypeSwitcher.getInputLocaleStr(); 41536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4160ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale)); 41736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mSuggest != null) { 41836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mSuggest.close(); 41936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 42027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 42189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 422979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 423458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 424458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa int mainDicResId = getMainDictionaryResourceId(res); 425458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mSuggest = new Suggest(this, mainDicResId); 4261b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 427e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 4280ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mUserDictionary = new UserDictionary(this, locale); 429923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggest.setUserDictionary(mUserDictionary); 430e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 431e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); 4322bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer mSuggest.setContactsDictionary(mContactsDictionary); 433e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 434e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mAutoDictionary = new AutoDictionary(this, this, locale, Suggest.DIC_AUTO); 43534386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mSuggest.setAutoDictionary(mAutoDictionary); 436e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 437e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mUserBigramDictionary = new UserBigramDictionary(this, this, locale, Suggest.DIC_USER); 438e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.setUserBigramDictionary(mUserBigramDictionary); 439e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 440e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 441458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mWordSeparators = res.getString(R.string.word_separators); 442458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mSentenceSeparators = res.getString(R.string.sentence_separators); 44336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4440ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.changeSystemLocale(savedLocale); 445923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 44636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 447466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 448466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onDestroy() { 449e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa if (mSuggest != null) { 450e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.close(); 451e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest = null; 452979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 453923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project unregisterReceiver(mReceiver); 454409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.destroy(); 455979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 456979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.onDestroy(); 457923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDestroy(); 458923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 459923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 460923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 461923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onConfigurationChanged(Configuration conf) { 462dc64b138b5e3fb3706c0818d0a308fe6e36985b0Tadashi G. Takaoka mSubtypeSwitcher.onConfigurationChanged(conf); 463b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani // If orientation changed while predicting, commit the change 464b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani if (conf.orientation != mOrientation) { 465466741d8a78965b8509bf527344f289e50873092Mike LeBeau InputConnection ic = getCurrentInputConnection(); 466466741d8a78965b8509bf527344f289e50873092Mike LeBeau commitTyped(ic); 467466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (ic != null) ic.finishComposingText(); // For voice input 468b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mOrientation = conf.orientation; 4692fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (isShowingOptionDialog()) 4702fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mOptionsDialog.dismiss(); 471b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 4728b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 47381c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = true; 474923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onConfigurationChanged(conf); 475bbd651a00898dabf6b2ae0e715d99953ea81063fLuca Zanolin mVoiceConnector.onConfigurationChanged(conf); 47681c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = false; 477923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 478b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 479923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateInputView() { 4818d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka return mKeyboardSwitcher.onCreateInputView(); 482923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 484923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 485923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateCandidatesView() { 486e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LayoutInflater inflater = getLayoutInflater(); 487e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); 488e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateViewContainer = container; 489e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka if (container.getPaddingRight() != 0) { 490e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka HorizontalScrollView scrollView = 491e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view); 492e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); 493e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka container.setGravity(Gravity.CENTER_HORIZONTAL); 494e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka } 495e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateView = (CandidateView) container.findViewById(R.id.candidates); 496923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.setService(this); 497923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setCandidatesViewShown(true); 498e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka return container; 499923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 500923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 50147f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins private static boolean isPasswordVariation(int variation) { 502e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD 503e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD 504e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD; 50547f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins } 50647f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins 50747f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins private static boolean isEmailVariation(int variation) { 508e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 509e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; 51047f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins } 51147f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins 512a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker @Override 513923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onStartInputView(EditorInfo attribute, boolean restarting) { 51445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 51545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka LatinKeyboardView inputView = switcher.getInputView(); 5168e09172df1bb176cc899940862c56bed9b9aec4esatok 517910b73127fa207dd26ec8124000262523b0aac0csatok if(DEBUG) { 518910b73127fa207dd26ec8124000262523b0aac0csatok Log.d(TAG, "onStartInputView: " + inputView); 519910b73127fa207dd26ec8124000262523b0aac0csatok } 520923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In landscape mode, this method gets called without the input view being created. 521979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (inputView == null) { 522923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 523923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 524923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 5258d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka mSubtypeSwitcher.updateParametersOnStartInputView(); 5264ab730dbd34fad323063f2ffd31ce33de746668dsatok 52736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mRefreshKeyboardRequired) { 52836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mRefreshKeyboardRequired = false; 529c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka onRefreshKeyboard(); 53036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 53136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 532923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.newSession(this); 5336c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani 534c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to 535c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // know now whether this is a password text field, because we need to know now whether we 536c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // want to enable the voice button. 537c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.resetVoiceStates(isPasswordVariation( 538c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka attribute.inputType & InputType.TYPE_MASK_VARIATION)); 539c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 540c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int mode = initializeInputAttributesAndGetMode(attribute.inputType); 541c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 542c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.closing(); 543c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mEnteredText = null; 544c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mComposing.setLength(0); 545c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHasValidSuggestions = false; 546c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mDeleteCount = 0; 547c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mJustAddedAutoSpace = false; 548c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 549c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka loadSettings(attribute); 550c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (mSubtypeSwitcher.isKeyboardMode()) { 551c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.loadKeyboard(mode, attribute.imeOptions, 552c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.isVoiceButtonEnabled(), 553c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.isVoiceButtonOnPrimary()); 554c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.updateShiftState(); 555c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 556c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 557c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka setCandidatesViewShownInternal(isCandidateStripVisible(), 558c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka false /* needsInputViewShown */ ); 559c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Delay updating suggestions because keyboard input view may not be shown at this point. 560c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHandler.postUpdateSuggestions(); 561c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 562c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka updateCorrectionMode(); 563c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 564c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setPreviewEnabled(mPopupOn); 565c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setProximityCorrectionEnabled(true); 566c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // If we just entered a text field, maybe it has some old text that requires correction 567c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka checkReCorrectionOnStart(); 568c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setForeground(true); 569c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 570c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.onStartInputView(inputView.getWindowToken()); 571c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 572de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka if (mKeyboardBottomRowVerticalCorrection > 0) { 573de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka final Window window = getWindow().getWindow(); 574de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka if (!(window.getCallback() instanceof ClipTouchEventWindowCallback)) { 575de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka window.setCallback(new ClipTouchEventWindowCallback( 576de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka window, mKeyboardBottomRowVerticalCorrection)); 577de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka } 578de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka } 579de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka 580c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); 581c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 582c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 583c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private int initializeInputAttributesAndGetMode(int inputType) { 584c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int variation = inputType & InputType.TYPE_MASK_VARIATION; 585c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mAutoSpace = false; 586e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = false; 5879fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 5881b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = false; 5891b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = null; 590dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 591f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka final int mode; 592c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switch (inputType & InputType.TYPE_MASK_CLASS) { 593e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_NUMBER: 594e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_DATETIME: 5955a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_NUMBER; 5962c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka break; 597e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_PHONE: 5985a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_PHONE; 599923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 600e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_TEXT: 6019fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = true; 602923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Make sure that passwords are not displayed in candidate view 60347f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isPasswordVariation(variation)) { 6049fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 605923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 60647f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isEmailVariation(variation) 607e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { 608923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAutoSpace = false; 609923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 610923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAutoSpace = true; 611923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 61247f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isEmailVariation(variation)) { 6139fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6145a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_EMAIL; 615e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { 6169fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6175a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_URL; 618e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { 6195a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_IM; 620e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { 6219fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6225a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 623e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { 6245a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_WEB; 6256c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani // If it's a browser edit field and auto correct is not ON explicitly, then 6266c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani // disable auto correction, but keep suggestions on. 627c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { 628e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 6296c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani } 630f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka } else { 6315a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 632923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 63336ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani 63436ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani // If NO_SUGGESTIONS is set, don't do prediction. 635c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { 6369fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 637e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 63836ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 63936ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani // If it's not multiline and the autoCorrect flag is not set, then don't correct 640c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && 641c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { 642e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 64336ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 644c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { 6459fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6461b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = isFullscreenMode(); 647923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 648923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 649923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project default: 6505a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 651f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka break; 652923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 653c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mode; 654923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 655923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 656b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani private void checkReCorrectionOnStart() { 657d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (!mReCorrectionEnabled) return; 658d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 659d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa final InputConnection ic = getCurrentInputConnection(); 660d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (ic == null) return; 661d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa // There could be a pending composing span. Clean it up first. 662d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa ic.finishComposingText(); 663d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 6649fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isShowingSuggestionsStrip() && isSuggestionsRequested()) { 665b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // First get the cursor position. This is required by setOldSuggestions(), so that 666b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // it can pass the correct range to setComposingRegion(). At this point, we don't 6674ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka // have valid values for mLastSelectionStart/End because onUpdateSelection() has 668b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // not been called yet. 669b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedTextRequest etr = new ExtractedTextRequest(); 670b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani etr.token = 0; // anything is fine here 671b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedText et = ic.getExtractedText(etr, 0); 672b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani if (et == null) return; 673b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 674b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionStart = et.startOffset + et.selectionStart; 675b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionEnd = et.startOffset + et.selectionEnd; 676b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 677b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // Then look for possible corrections in a delayed fashion 67855b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { 679d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 68055b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 681b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 682b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 683b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 684923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 685923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onFinishInput() { 686923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onFinishInput(); 687a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 688979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 6891b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 690979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 691409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging); 692409220583333bdf06290dd9fd42f91b5c0d1b11asatok 6935a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 694d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.closing(); 6954ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); 696979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); 697466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 698466741d8a78965b8509bf527344f289e50873092Mike LeBeau 699466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 7006495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa public void onFinishInputView(boolean finishingInput) { 7016495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa super.onFinishInputView(finishingInput); 7025a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 703d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.setForeground(false); 704d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka // Remove pending messages related to update suggestions 705d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 706d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateOldSuggestions(); 7076495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa } 7086495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa 7096495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa @Override 710466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onUpdateExtractedText(int token, ExtractedText text) { 711466741d8a78965b8509bf527344f289e50873092Mike LeBeau super.onUpdateExtractedText(token, text); 712409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.showPunctuationHintIfNecessary(); 713923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 714923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 715923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 716923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onUpdateSelection(int oldSelStart, int oldSelEnd, 717923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int newSelStart, int newSelEnd, 718923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int candidatesStart, int candidatesEnd) { 719923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 720923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project candidatesStart, candidatesEnd); 721466741d8a78965b8509bf527344f289e50873092Mike LeBeau 722466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (DEBUG) { 723466741d8a78965b8509bf527344f289e50873092Mike LeBeau Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart 724466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ose=" + oldSelEnd 725466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nss=" + newSelStart 726466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nse=" + newSelEnd 727466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", cs=" + candidatesStart 728466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ce=" + candidatesEnd); 729466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 730466741d8a78965b8509bf527344f289e50873092Mike LeBeau 731409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setCursorAndSelection(newSelEnd, newSelStart); 7324f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 733923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If the current selection in the text view changes, we should 734923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // clear whatever candidate text we have. 7359fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((((mComposing.length() > 0 && mHasValidSuggestions) 7368e09172df1bb176cc899940862c56bed9b9aec4esatok || mVoiceConnector.isVoiceInputHighlighted()) && (newSelStart != candidatesEnd 7378e09172df1bb176cc899940862c56bed9b9aec4esatok || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) { 738923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 7399fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 740d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 741923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.reset(); 742923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 743923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 744923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.finishComposingText(); 745923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 746409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setVoiceInputHighlighted(false); 7479fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (!mHasValidSuggestions && !mJustAccepted) { 7489a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa switch (TextEntryState.getState()) { 749e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case ACCEPTED_DEFAULT: 750e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka TextEntryState.reset(); 751e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // $FALL-THROUGH$ 752e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case SPACE_AFTER_PICKED: 753e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mJustAddedAutoSpace = false; // The user moved the cursor. 754e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 755e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka default: 756e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 7579a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 758923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 759923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = false; 760d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 761466741d8a78965b8509bf527344f289e50873092Mike LeBeau 762979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a note of the cursor position 763979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionStart = newSelStart; 764979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionEnd = newSelEnd; 765466741d8a78965b8509bf527344f289e50873092Mike LeBeau 7669fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isShowingSuggestionsStrip()) { 76766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Don't look for corrections if the keyboard is not visible 7681679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown()) { 76966b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Check if we should go in or out of correction mode. 7709fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isSuggestionsRequested() && !mJustReverted 77166b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok && (candidatesStart == candidatesEnd || newSelStart != oldSelStart 77266b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok || TextEntryState.isCorrecting()) 7739fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) { 77466b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { 775d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 77666b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } else { 77766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok abortCorrection(false); 77855b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Show the punctuation suggestions list if the current one is not 779364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // and if not showing "Touch again to save". 7807599cfea4a2d56f4779452ec8e8742f7b9629cc0satok if (mCandidateView != null && !isShowingPunctuationList() 7817599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && !mCandidateView.isShowingAddToDictionaryHint()) { 782ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 78355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 78466b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } 785b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 786466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 787466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 788923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 789923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 790c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 791c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has clicked on the extracted text view, 792c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * when running in fullscreen mode. The default implementation hides 793c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * the candidates view when this happens, but only if the extracted text 794c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * editor has a vertical scroll bar because its text doesn't fit. 795c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 796c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 797c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 798c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 799c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedTextClicked() { 8009fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isSuggestionsRequested()) return; 801c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 802c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedTextClicked(); 803c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 804c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 805c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 806c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has performed a cursor movement in the 807c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * extracted text view, when it is running in fullscreen mode. The default 808c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * implementation hides the candidates view when a vertical movement 809c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * happens, but only if the extracted text editor has a vertical scroll bar 810c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * because its text doesn't fit. 811c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 812c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 813c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 814c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 815c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedCursorMovement(int dx, int dy) { 8169fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isSuggestionsRequested()) return; 817c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 818c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedCursorMovement(dx, dy); 819c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 820c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 821923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 822923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void hideWindow() { 823979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 8241b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 825979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 826923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (TRACE) Debug.stopMethodTracing(); 8276e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani if (mOptionsDialog != null && mOptionsDialog.isShowing()) { 8286e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog.dismiss(); 8296e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog = null; 8306e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 831409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.hideVoiceWindow(mConfigurationChanging); 832979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.clear(); 833923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.hideWindow(); 834923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.endSession(); 835923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 836923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 837923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 8381b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) { 839979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (DEBUG) { 840a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, "Received completions:"); 8411b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int count = (applicationSpecifiedCompletions != null) 8421b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka ? applicationSpecifiedCompletions.length : 0; 8431b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka for (int i = 0; i < count; i++) { 844a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]); 845923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 846923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 8471b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) { 8481b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = applicationSpecifiedCompletions; 8491b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (applicationSpecifiedCompletions == null) { 850b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 851923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 852923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 853a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 8547e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder() 8551b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka .setApplicationSpecifiedCompletions(applicationSpecifiedCompletions) 8567e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setTypedWordValid(true) 8577e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setHasMinimalSuggestion(true); 858979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // When in fullscreen mode, show completions generated by the application 8597e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(builder.build()); 860923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 861543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShown(true); 862923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 863923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 864923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 865543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { 866923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // TODO: Remove this if we support candidates with hard keyboard 867923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (onEvaluateInputViewShown()) { 8681679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka super.setCandidatesViewShown(shown 8691679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); 870923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 871923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 872a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 873923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 874543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa public void setCandidatesViewShown(boolean shown) { 875543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); 876543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa } 877543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa 878543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa @Override 879923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onComputeInsets(InputMethodService.Insets outInsets) { 880923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onComputeInsets(outInsets); 881264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project if (!isFullscreenMode()) { 882264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project outInsets.contentTopInsets = outInsets.visibleTopInsets; 883264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project } 8849e347d3d448e48229c46aad394ec9bd60cd5807bsatok KeyboardView inputView = mKeyboardSwitcher.getInputView(); 8859e347d3d448e48229c46aad394ec9bd60cd5807bsatok // Need to set touchable region only if input view is being shown 8869e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (inputView != null && mKeyboardSwitcher.isInputViewShown()) { 8879e347d3d448e48229c46aad394ec9bd60cd5807bsatok final int x = 0; 8889e347d3d448e48229c46aad394ec9bd60cd5807bsatok int y = 0; 8899e347d3d448e48229c46aad394ec9bd60cd5807bsatok final int width = inputView.getWidth(); 8909e347d3d448e48229c46aad394ec9bd60cd5807bsatok int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT; 8919e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (mCandidateViewContainer != null) { 8929e347d3d448e48229c46aad394ec9bd60cd5807bsatok ViewParent candidateParent = mCandidateViewContainer.getParent(); 8939e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (candidateParent instanceof FrameLayout) { 894de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka final FrameLayout fl = (FrameLayout) candidateParent; 895de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka // Check frame layout's visibility 896de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka if (fl.getVisibility() == View.INVISIBLE) { 897de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka y = fl.getHeight(); 898de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka height += y; 899de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka } else if (fl.getVisibility() == View.VISIBLE) { 900de59a84029d3d3ec114b5b0f2eca0b3752982fefTadashi G. Takaoka height += fl.getHeight(); 9019e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9029e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9039e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9049e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (DEBUG) { 9059e347d3d448e48229c46aad394ec9bd60cd5807bsatok Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height); 9069e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9076845da8d7b940018c4ef77646f0028d131ed2753satok outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; 9089e347d3d448e48229c46aad394ec9bd60cd5807bsatok outInsets.touchableRegion.set(x, y, width, height); 9099e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 910923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 911a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 912923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 913979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public boolean onEvaluateFullscreenMode() { 914458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 915458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa DisplayMetrics dm = res.getDisplayMetrics(); 916979f8690967ff5409fe18f5085858ccdb8e0ccf1satok float displayHeight = dm.heightPixels; 917979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // If the display is more than X inches high, don't go to fullscreen mode 918458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa float dimen = res.getDimension(R.dimen.max_height_for_fullscreen); 919979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (displayHeight > dimen) { 920979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 921979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 922979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return super.onEvaluateFullscreenMode(); 923979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 924979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 925979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 926979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 927923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 928923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 929e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_BACK: 930e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { 931e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.getInputView().handleBack()) { 9326e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani return true; 9336e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 934e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 935e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 936923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 937923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyDown(keyCode, event); 938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 939923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 940923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 941923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 942923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 943e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_DOWN: 944e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_UP: 945e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_LEFT: 946e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_RIGHT: 947e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Enable shift key and DPAD to do selections 948e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown() 949e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && mKeyboardSwitcher.isShiftedOrShiftLocked()) { 950e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(), 951e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getAction(), event.getKeyCode(), event.getRepeatCount(), 952e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getDeviceId(), event.getScanCode(), 953e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON); 954e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka InputConnection ic = getCurrentInputConnection(); 955e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (ic != null) 956e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka ic.sendKeyEvent(newEvent); 957e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return true; 958e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 959e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 960923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 961923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyUp(keyCode, event); 962923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 963923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 964409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void commitTyped(InputConnection inputConnection) { 9659fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 9669fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 967923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() > 0) { 968923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (inputConnection != null) { 969923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project inputConnection.commitText(mComposing, 1); 970923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 971923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = mComposing.length(); 972923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedTyped(mComposing); 973979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); 974923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 975923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 976923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 977923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 978923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 979b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public boolean getCurrentAutoCapsState() { 980923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 9811c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani EditorInfo ei = getCurrentInputEditorInfo(); 982e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) { 983b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return ic.getCursorCapsMode(ei.inputType) != 0; 9841c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 985b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 9861c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 9871c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 988923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void swapPunctuationAndSpace() { 989923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 990923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 991923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); 992923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastTwo != null && lastTwo.length() == 2 993571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastTwo.charAt(0) == Keyboard.CODE_SPACE 994571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && isSentenceSeparator(lastTwo.charAt(1))) { 995923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 997923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(lastTwo.charAt(1) + " ", 1); 998923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 999b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10009a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1001923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1002923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 10031c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 10044ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa private void reswapPeriodAndSpace() { 10054ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa final InputConnection ic = getCurrentInputConnection(); 10064ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (ic == null) return; 10074ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 10084ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastThree != null && lastThree.length() == 3 1009571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(0) == Keyboard.CODE_PERIOD 1010571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 1011571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_PERIOD) { 10124ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.beginBatchEdit(); 10134ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.deleteSurroundingText(3, 0); 10144ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.commitText(" ..", 1); 10154ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.endBatchEdit(); 1016b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10174ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 10184ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 10194ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1020923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void doubleSpace() { 1021923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project //if (!mAutoPunctuate) return; 1022923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCorrectionMode == Suggest.CORRECTION_NONE) return; 1023923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1024923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1025923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 1026923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastThree != null && lastThree.length() == 3 1027923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project && Character.isLetterOrDigit(lastThree.charAt(0)) 1028571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 1029571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_SPACE) { 1030923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1031923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 1032923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(". ", 1); 1033923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1034b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10359a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1036923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1037923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1038a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 103941a519729505a877844f2c57a33509c302dddbceKen Wakasa private void maybeRemovePreviousPeriod(CharSequence text) { 104041a519729505a877844f2c57a33509c302dddbceKen Wakasa final InputConnection ic = getCurrentInputConnection(); 104141a519729505a877844f2c57a33509c302dddbceKen Wakasa if (ic == null) return; 104241a519729505a877844f2c57a33509c302dddbceKen Wakasa 104341a519729505a877844f2c57a33509c302dddbceKen Wakasa // When the text's first character is '.', remove the previous period 104441a519729505a877844f2c57a33509c302dddbceKen Wakasa // if there is one. 104541a519729505a877844f2c57a33509c302dddbceKen Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10464ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastOne != null && lastOne.length() == 1 1047571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_PERIOD 1048571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && text.charAt(0) == Keyboard.CODE_PERIOD) { 104941a519729505a877844f2c57a33509c302dddbceKen Wakasa ic.deleteSurroundingText(1, 0); 105041a519729505a877844f2c57a33509c302dddbceKen Wakasa } 105141a519729505a877844f2c57a33509c302dddbceKen Wakasa } 105241a519729505a877844f2c57a33509c302dddbceKen Wakasa 10539a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private void removeTrailingSpace() { 10549a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa final InputConnection ic = getCurrentInputConnection(); 10559a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic == null) return; 10569a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 10579a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10589a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (lastOne != null && lastOne.length() == 1 1059571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_SPACE) { 10609a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.deleteSurroundingText(1, 0); 10619a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10629a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10639a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 1064923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean addWordToDictionary(String word) { 1065923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mUserDictionary.addWord(word, 128); 10666558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Suggestion strip should be updated after the operation of adding word to the 10676558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // user dictionary 1068d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1069923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1070923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1071923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1072923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isAlphabet(int code) { 1073923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (Character.isLetter(code)) { 1074923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1075923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1076923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1077923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1078923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1079a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1080e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyPressed() { 10819a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10822fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (!mConfigEnableShowSubtypeSettings) { 10832fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka showSubtypeSelectorAndSettings(); 10842fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 10859a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok showOptionsMenu(); 10869a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10879a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10889a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10899a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10909a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10919a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1092e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyLongPressed() { 10939a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10949502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 109579efbed76f638be298493107fa2d0cd1b5eb529esatok mImm.showInputMethodPicker(); 10969a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10979a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10989a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10999a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11009a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11019a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 11029a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok private boolean isShowingOptionDialog() { 11039a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok return mOptionsDialog != null && mOptionsDialog.isShowing(); 11049a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11059a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 11065f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka // Implementation of {@link KeyboardActionListener}. 11075a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11088aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { 1109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long when = SystemClock.uptimeMillis(); 1110571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { 1111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDeleteCount = 0; 1112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastKeyTime = when; 1114b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1115b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1117571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 11184189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleBackspace(); 11194189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mDeleteCount++; 11204189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnDelete(); 11214189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1122571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SHIFT: 11234189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Shift key is handled in onPress() when device has distinct multi-touch panel. 11244189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!distinctMultiTouch) 1125b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleShift(); 11264189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1127e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: 11284189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Symbol key is handled in onPress() when device has distinct multi-touch panel. 11294189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!distinctMultiTouch) 1130b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.changeKeyboardMode(); 11314189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1132571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CANCEL: 11334189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!isShowingOptionDialog()) { 11344189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleClose(); 11354189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11364189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1137e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS: 1138e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyPressed(); 11394189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1140e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS_LONGPRESS: 1141e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyLongPressed(); 11424189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1143571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_NEXT_LANGUAGE: 11444189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka toggleLanguage(false, true); 11454189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1146571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_PREV_LANGUAGE: 11474189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka toggleLanguage(false, false); 11484189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1149571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CAPSLOCK: 1150b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleCapsLock(); 11514189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 115220cdb37bd062ae6cb6d42ad6229a19733476cd55satok case Keyboard.CODE_VOICE: 115320cdb37bd062ae6cb6d42ad6229a19733476cd55satok mSubtypeSwitcher.switchToShortcutIME(); 11544189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1155571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_TAB: 115645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka handleTab(); 11574189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 11584189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka default: 1159571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_ENTER) { 11604189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mJustAddedAutoSpace = false; 11614189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11624189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka RingCharBuffer.getInstance().push((char)primaryCode, x, y); 11634189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnInputChar(); 11644189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (isWordSeparator(primaryCode)) { 11654189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleSeparator(primaryCode); 11664189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } else { 11674189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleCharacter(primaryCode, keyCodes); 11684189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11694189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Cancel the just reverted state 1170c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1172b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onKey(primaryCode); 1173dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Reset after any single keystroke 1174dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = null; 1175923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1176a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 11775a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11788aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onTextInput(CharSequence text) { 1179409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.commitVoiceInput(); 1180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1182979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(false); 1183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 118455b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka commitTyped(ic); 118541a519729505a877844f2c57a33509c302dddbceKen Wakasa maybeRemovePreviousPeriod(text); 1186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(text, 1); 1187923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1188b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 11895f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); 1190c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 11919a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 1192dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = text; 1193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1194923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 11955a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11968aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCancelInput() { 119783e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka // User released a finger outside any key 11985f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onCancelInput(); 119983e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka } 120083e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka 1201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleBackspace() { 1202409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (mVoiceConnector.logAndRevertVoiceInput()) return; 12034f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1204504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1205504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (ic == null) return; 1206979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.beginBatchEdit(); 1207979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1208409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleBackspace(); 12094f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1210504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka boolean deleteChar = false; 12119fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 1213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (length > 0) { 1214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.delete(length - 1, length); 1215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.deleteLast(); 1216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() == 0) { 12189fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1220d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(1, 0); 1223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project deleteChar = true; 1226923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1227d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 1228504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1229923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.backspace(); 1230979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) { 1231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project revertLastWord(deleteChar); 1232979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1233923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1234504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1235504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1236504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { 1237dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani ic.deleteSurroundingText(mEnteredText.length(), 0); 1238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else if (deleteChar) { 12396558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 12406558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Go back to the suggestion mode if the user canceled the 124155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // "Touch again to save". 12426558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // NOTE: In gerenal, we don't revert the word when backspacing 12436558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // from a manual suggestion pick. We deliberately chose a 12446558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // different behavior only in the case of picking the first 12456558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // suggestion (typed word). It's intentional to have made this 12466558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // inconsistent with backspacing after selecting other suggestions. 12476558253160e2039c87f424bd814f402ecd31de3bKen Wakasa revertLastWord(deleteChar); 12486558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } else { 1249923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 12506558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mDeleteCount > DELETE_ACCELERATE_AT) { 12516558253160e2039c87f424bd814f402ecd31de3bKen Wakasa sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 12526558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 1253923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1254923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1255c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1256979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1257923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1258923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 125945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka private void handleTab() { 126045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int imeOptions = getCurrentInputEditorInfo().imeOptions; 126145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int navigationFlags = 126245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka EditorInfo.IME_FLAG_NAVIGATE_NEXT | EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS; 126345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if ((imeOptions & navigationFlags) == 0) { 126445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); 126545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 126645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 126745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 126845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 126945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (ic == null) 127045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 127145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 127245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // True if keyboard is in either chording shift or manual temporary upper case mode. 127345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase(); 127445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0 127545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && !isManualTemporaryUpperCase) { 127645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); 127745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0 127845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && isManualTemporaryUpperCase) { 127945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_PREVIOUS); 128045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 128145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 128245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 1283979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void abortCorrection(boolean force) { 1284979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (force || TextEntryState.isCorrecting()) { 1285ca26f20fa4903de46e374babbfba8c8a1a5cac93satok TextEntryState.onAbortCorrection(); 1286ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1287979f8690967ff5409fe18f5085858ccdb8e0ccf1satok getCurrentInputConnection().finishComposingText(); 1288b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1290923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1291a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1292923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleCharacter(int primaryCode, int[] keyCodes) { 1293409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleCharacter(); 12944f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1295b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isCorrecting()) { 1296b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani abortCorrection(false); 1297b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 12984f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1299e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int code = primaryCode; 13009fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) { 13019fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 13029fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = true; 1303923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 1304979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(mBestWord); 1305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.reset(); 1306923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13081679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1309f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (switcher.isShiftedOrShiftLocked()) { 1310eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT 1311eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani || keyCodes[0] > Character.MAX_CODE_POINT) { 1312eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani return; 1313eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani } 1314e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = keyCodes[0]; 1315e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (switcher.isAlphabetMode() && Character.isLowerCase(code)) { 1316e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int upperCaseCode = Character.toUpperCase(code); 1317e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (upperCaseCode != code) { 1318e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = upperCaseCode; 131912a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } else { 132012a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka // Some keys, such as [eszett], have upper case as multi-characters. 1321e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka String upperCase = new String(new int[] {code}, 0, 1).toUpperCase(); 13228aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka onTextInput(upperCase); 132312a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka return; 132412a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } 1325979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1326923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13279fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1328f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (mComposing.length() == 0 && switcher.isAlphabetMode() 1329f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka && switcher.isShiftedOrShiftLocked()) { 13300b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa mWord.setFirstCharCapitalized(true); 1331923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1332e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mComposing.append((char) code); 1333e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mWord.add(code, keyCodes); 1334923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1335923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 13361c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani // If it's the first letter, make note of auto-caps state 13371c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani if (mWord.size() == 1) { 1338b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mWord.setAutoCapitalized(getCurrentAutoCapsState()); 13391c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 1340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1341923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1342d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1343923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1344e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka sendKeyChar((char)code); 1345923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1346b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 1347979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (LatinIME.PERF_DEBUG) measureCps(); 1348e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka TextEntryState.typedCharacter((char) code, isWordSeparator(code)); 1349923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1350923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1351923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleSeparator(int primaryCode) { 1352409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleSeparator(); 13534f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 135455b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Should dismiss the "Touch again to save" message when handling separator 13556558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 1356d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 13576558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 13586558253160e2039c87f424bd814f402ecd31de3bKen Wakasa 1359923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project boolean pickedDefault = false; 1360923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Handle separator 13611b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1362923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1363923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1364979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(false); 1365923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13669fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1367923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In certain languages where single quote is a separator, it's better 1368a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker // not to auto correct, but accept the typed word. For instance, 1369923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // in Italian dov' should not be expanded to dove' because the elision 1370923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // requires the last vowel to be removed. 1371c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa if (mAutoCorrectOn && primaryCode != '\'' && !mJustReverted) { 1372979f8690967ff5409fe18f5085858ccdb8e0ccf1satok pickedDefault = pickDefaultSuggestion(); 13739a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // Picked the suggestion by the space key. We consider this 13749a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // as "added an auto space". 1375571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode == Keyboard.CODE_SPACE) { 13769a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 13779a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1378923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1379923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(ic); 1380923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1382571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) { 13839a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa removeTrailingSpace(); 13849a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 13859a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendKeyChar((char)primaryCode); 13874ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 13884ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // Handle the case of ". ." -> " .." with auto-space if necessary 13894ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // before changing the TextEntryState. 1390979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED 1391571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && primaryCode == Keyboard.CODE_PERIOD) { 13924ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa reswapPeriodAndSpace(); 13934ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 13944ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1395923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.typedCharacter((char) primaryCode, true); 1396979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED 1397571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && primaryCode != Keyboard.CODE_ENTER) { 1398923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project swapPunctuationAndSpace(); 13999fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { 1400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project doubleSpace(); 1401923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1402979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (pickedDefault) { 140355b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka CharSequence typedWord = mWord.getTypedWord(); 140455b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka TextEntryState.backToAcceptedDefault(typedWord); 140555b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { 14064ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka if (ic != null) { 14074ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka CorrectionInfo correctionInfo = new CorrectionInfo( 14084ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); 14094ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka ic.commitCorrection(correctionInfo); 14104ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka } 141155b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (mCandidateView != null) 141255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka mCandidateView.onAutoCorrectionInverted(mBestWord); 141355b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka } 141455b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka setPunctuationSuggestions(); 1415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1416b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1419923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1420923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1421466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1422923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleClose() { 1423923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(getCurrentInputConnection()); 1424409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleClose(); 1425923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestHideSelf(0); 14261679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 14271679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) 14281679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.closing(); 1429923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.endSession(); 1430923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1431923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1432979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void saveWordInHistory(CharSequence result) { 1433979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mWord.size() <= 1) { 1434979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWord.reset(); 1435979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1436923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1437979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Skip if result is null. It happens in some edge case. 1438979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextUtils.isEmpty(result)) { 1439979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1440923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1441979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1442979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a copy of the CharSequence, since it is/could be a mutable CharSequence 1443979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final String resultCopy = result.toString(); 1444979f8690967ff5409fe18f5085858ccdb8e0ccf1satok TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy, 1445979f8690967ff5409fe18f5085858ccdb8e0ccf1satok new WordComposer(mWord)); 1446979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.add(entry); 1447923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1448923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 14499fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isSuggestionsRequested() { 1450c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mIsSettingsSuggestionStripOn 1451c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); 1452923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1453a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 14547599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private boolean isShowingPunctuationList() { 14557e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return mSuggestPuncList == mCandidateView.getSuggestions(); 14567599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14577599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 14589fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isShowingSuggestionsStrip() { 14597599cfea4a2d56f4779452ec8e8742f7b9629cc0satok return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) 14607599cfea4a2d56f4779452ec8e8742f7b9629cc0satok || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 14617599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && mOrientation == Configuration.ORIENTATION_PORTRAIT); 14627599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14637599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1464923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCandidateStripVisible() { 14659fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isCorrecting()) 14669fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14679fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!isShowingSuggestionsStrip()) 14689fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return false; 14699fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) 14709fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14719fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return isSuggestionsRequested(); 1472923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1473923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1474409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void switchToKeyboardView() { 14755a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mHandler.post(new Runnable() { 14765a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 14775a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka public void run() { 14785a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (DEBUG) { 14795a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka Log.d(TAG, "Switch to keyboard view."); 14805a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14815a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka View v = mKeyboardSwitcher.getInputView(); 14825a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (v != null) { 14835a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka // Confirms that the keyboard view doesn't have parent view. 14845a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka ViewParent p = v.getParent(); 14855a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (p != null && p instanceof ViewGroup) { 14865a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka ((ViewGroup) p).removeView(v); 14875a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14885a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka setInputView(v); 14895a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14905a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 14915a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka updateInputViewShown(); 14925a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 14935a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14945a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka }); 1495466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1496466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1497409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void clearSuggestions() { 14987e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(SuggestedWords.EMPTY); 1499466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1500466741d8a78965b8509bf527344f289e50873092Mike LeBeau 15017e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public void setSuggestions(SuggestedWords words) { 1502409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (mVoiceConnector.getAndResetIsShowingHint()) { 1503466741d8a78965b8509bf527344f289e50873092Mike LeBeau setCandidatesView(mCandidateViewContainer); 1504466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1505466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1506466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (mCandidateView != null) { 15077e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mCandidateView.setSuggestions(words); 15089ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka if (mCandidateView.isConfigCandidateHighlightFontColorEnabled()) { 15099ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged( 15109ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka words.hasWordAboveAutoCorrectionScoreThreshold()); 15119ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka } 1512466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1513466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1514466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1515409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void updateSuggestions() { 15161679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(null); 15171b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani 1518923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Check if we have a suggestion engine attached. 15199fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((mSuggest == null || !isSuggestionsRequested()) 1520409220583333bdf06290dd9fd42f91b5c0d1b11asatok && !mVoiceConnector.isVoiceInputHighlighted()) { 1521923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1522923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1523466741d8a78965b8509bf527344f289e50873092Mike LeBeau 15249fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1525ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1526923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1527923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1528979f8690967ff5409fe18f5085858ccdb8e0ccf1satok showSuggestions(mWord); 1529979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1530979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 15317e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords.Builder getTypedSuggestions(WordComposer word) { 15329ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka return mSuggest.getSuggestedWordBuilder(mKeyboardSwitcher.getInputView(), word, null); 1533979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1534979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1535979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showCorrections(WordAlternatives alternatives) { 15361679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(null); 15377e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = alternatives.getAlternatives(); 15387e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.setTypedWordValid(false).setHasMinimalSuggestion(false); 15397e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), alternatives.getOriginalWord()); 1540979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1541979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1542979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showSuggestions(WordComposer word) { 1543979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // TODO Maybe need better way of retrieving previous word 1544e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1545979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordSeparators); 15467e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 15479ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.getInputView(), word, prevWord); 1548923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 15491b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies(); 15501679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(nextLettersFrequencies); 15511b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani 1552378a1b516d867671d292900c5d42aef3a0dc1556Ken Wakasa boolean correctionAvailable = !mInputTypeNoAutoCorrect && !mJustReverted 15536f7218627eda110a8454053f8ecb7b80edfdc8cesatok && mSuggest.hasAutoCorrection(); 1554a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final CharSequence typedWord = word.getTypedWord(); 1555923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If we're in basic correct 1556a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final boolean typedWordValid = mSuggest.isValidWord(typedWord) || 1557979f8690967ff5409fe18f5085858ccdb8e0ccf1satok (preferCapitalization() 1558979f8690967ff5409fe18f5085858ccdb8e0ccf1satok && mSuggest.isValidWord(typedWord.toString().toLowerCase())); 1559979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mCorrectionMode == Suggest.CORRECTION_FULL 1560979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { 1561923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project correctionAvailable |= typedWordValid; 1562923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15634a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani // Don't auto-correct words with multiple capital letter 1564979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !word.isMostlyCaps(); 1565979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !TextEntryState.isCorrecting(); 1566979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1567a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // Basically, we update the suggestion strip only when suggestion count > 1. However, 1568a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // there is an exception: We update the suggestion strip whenever typed word's length 1569f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // is 1 or typed word is found in dictionary, regardless of suggestion count. Actually, 1570f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // in most cases, suggestion count is 1 when typed word's length is 1, but we do always 1571f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // need to clear the previous state when the user starts typing a word (i.e. typed word's 1572f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // length == 1). 1573f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid 1574a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa || mCandidateView.isShowingAddToDictionaryHint()) { 15759fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable); 15769fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else { 15779fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); 15789fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (previousSuggestions == mSuggestPuncList) 15799fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return; 15809fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); 15819fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } 15827e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), typedWord); 1583979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 15844a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani 15857e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { 15867e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(suggestedWords); 15877e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (suggestedWords.size() > 0) { 158882411d47ba7e8133ed2390c6920945e139a738cesatok if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords)) { 158982411d47ba7e8133ed2390c6920945e139a738cesatok mBestWord = typedWord; 159082411d47ba7e8133ed2390c6920945e139a738cesatok } else if (suggestedWords.hasAutoCorrectionWord()) { 15917e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mBestWord = suggestedWords.getWord(1); 1592923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1593923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = typedWord; 1594923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1595923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1596923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 1597923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1598ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1599923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1600923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1601979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean pickDefaultSuggestion() { 1602923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Complete any pending candidate query first 1603d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka if (mHandler.hasPendingUpdateSuggestions()) { 1604d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 1605923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 1606923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 16076780b898ec2647a21319601a03ae1c393c0e1b29Amith Yamasani if (mBestWord != null && mBestWord.length() > 0) { 1608923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); 1609923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = true; 161055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(mBestWord); 16119468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 1612979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); 1613979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return true; 1614979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1615923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1616979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 1617923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1618923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1619923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void pickSuggestionManually(int index, CharSequence suggestion) { 16207e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords suggestions = mCandidateView.getSuggestions(); 1621409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators); 16224f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1623979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final boolean correcting = TextEntryState.isCorrecting(); 16249a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa InputConnection ic = getCurrentInputConnection(); 16259a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16269a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.beginBatchEdit(); 16279a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 16281b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null 16291b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka && index >= 0 && index < mApplicationSpecifiedCompletions.length) { 16301b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka CompletionInfo ci = mApplicationSpecifiedCompletions[index]; 1631923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1632923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitCompletion(ci); 1633923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1634923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1635923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCandidateView != null) { 1636923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.clear(); 1637923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1638b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 16399a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16409a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16419a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1642923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1643923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 16446a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 16456a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani // If this is a punctuation, apply it through the normal key press 1646979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) 1647979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || isSuggestedPunctuation(suggestion.charAt(0)))) { 1648979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Word separators are suggested before the user inputs something. 1649979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // So, LatinImeLogger logs "" as a user's input. 1650979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion( 16517e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka "", suggestion.toString(), index, suggestions.mWords); 165255b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa final char primaryCode = suggestion.charAt(0); 1653a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka onCodeInput(primaryCode, new int[] { primaryCode }, 1654a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE, 1655a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE); 16569a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16579a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16589a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 16596a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani return; 16606a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 16619a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAccepted = true; 166255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(suggestion); 16639468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 16640c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani if (index == 0) { 1665979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); 1666979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1667979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToBigramDictionary(suggestion, 1); 16680c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani } 1669979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(), 16707e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka index, suggestions.mWords); 1671923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); 1672923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Follow it with a space 1673979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mAutoSpace && !correcting) { 1674923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendSpace(); 16759a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1676923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1677979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1678b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani final boolean showingAddToDictionaryHint = index == 0 && mCorrectionMode > 0 1679b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani && !mSuggest.isValidWord(suggestion) 1680b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani && !mSuggest.isValidWord(suggestion.toString().toLowerCase()); 1681b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1682979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!correcting) { 1683b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Fool the state watcher so that a subsequent backspace will not do a revert, unless 1684b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // we just did a correction, in which case we need to stay in 1685b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // TextEntryState.State.PICKED_SUGGESTION state. 1686571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true); 1687ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1688b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else if (!showingAddToDictionaryHint) { 1689364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // If we're not showing the "Touch again to save", then show corrections again. 1690979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // In case the cursor position doesn't change, make sure we show the suggestions again. 1691b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1692d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 1693979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1694b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (showingAddToDictionaryHint) { 169566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mCandidateView.showAddToDictionaryHint(suggestion); 169666a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 16979a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16989a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16999a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1700923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1701a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1702979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1703979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Commits the chosen word to the text field and saves it for later 1704979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * retrieval. 1705979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param suggestion the suggestion picked by the user to be committed to 1706979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * the text field 1707979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 170855b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka private void pickSuggestion(CharSequence suggestion) { 1709b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1710b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!switcher.isKeyboardAvailable()) 17111679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return; 1712923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1713923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1714409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators); 1715979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.commitText(suggestion, 1); 1716923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1717979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(suggestion); 17189fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1719923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1720b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.setPreferredLetters(null); 1721923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1722923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1723b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani /** 1724b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * Tries to apply any typed alternatives for the word if we have any cached alternatives, 1725b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * otherwise tries to find new corrections and completions for the word. 1726b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @param touching The word that the cursor is touching, with position information 1727b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @return true if an alternative was found, false otherwise. 1728b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani */ 1729e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) { 1730b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // If we didn't find a match, search for result in typed word history 1731b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordComposer foundWord = null; 1732b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordAlternatives alternatives = null; 1733b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani for (WordAlternatives entry : mWordHistory) { 1734e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) { 1735b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (entry instanceof TypedWordAlternatives) { 1736b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani foundWord = ((TypedWordAlternatives) entry).word; 1737b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1738b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani alternatives = entry; 1739b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani break; 1740b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1741b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 17421b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // If we didn't find a match, at least suggest corrections. 1743b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord == null 1744e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && (mSuggest.isValidWord(touching.mWord) 1745e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || mSuggest.isValidWord(touching.mWord.toString().toLowerCase()))) { 1746b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani foundWord = new WordComposer(); 1747e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka for (int i = 0; i < touching.mWord.length(); i++) { 1748e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.add(touching.mWord.charAt(i), new int[] { 1749e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka touching.mWord.charAt(i) 1750b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani }); 1751b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1752e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0))); 1753b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1754b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Found a match, show suggestions 1755b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null || alternatives != null) { 1756b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (alternatives == null) { 1757e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka alternatives = new TypedWordAlternatives(touching.mWord, foundWord); 1758b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1759b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani showCorrections(alternatives); 1760b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null) { 1761b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord = new WordComposer(foundWord); 1762b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1763b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord.reset(); 1764b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1765b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return true; 1766b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1767b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return false; 1768b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1769b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1770979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void setOldSuggestions() { 1771409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setShowingVoiceSuggestions(false); 1772b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) { 1773b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return; 1774b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1775979f8690967ff5409fe18f5085858ccdb8e0ccf1satok InputConnection ic = getCurrentInputConnection(); 1776979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (ic == null) return; 17779fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1778b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Extract the selected or touching text 1779e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic, 1780b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mLastSelectionStart, mLastSelectionEnd, mWordSeparators); 1781979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1782e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (touching != null && touching.mWord.length() > 1) { 1783b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.beginBatchEdit(); 1784979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1785409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (!mVoiceConnector.applyVoiceAlternatives(touching) 1786409220583333bdf06290dd9fd42f91b5c0d1b11asatok && !applyTypedAlternatives(touching)) { 1787b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani abortCorrection(true); 1788b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1789979f8690967ff5409fe18f5085858ccdb8e0ccf1satok TextEntryState.selectedForCorrection(); 1790e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka EditingUtils.underlineWord(ic, touching); 1791979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1792b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1793b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.endBatchEdit(); 1794979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1795979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(true); 1796ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); // Show the punctuation suggestions list 1797979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1798979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1799979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(true); 1800979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1801979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1802979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1803ca26f20fa4903de46e374babbfba8c8a1a5cac93satok private void setPunctuationSuggestions() { 18047e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(mSuggestPuncList); 18059fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 18066a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 18076a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 1808979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void addToDictionaries(CharSequence suggestion, int frequencyDelta) { 1809979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, false); 1810979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1811979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1812979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void addToBigramDictionary(CharSequence suggestion, int frequencyDelta) { 1813979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, true); 1814979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1815979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1816979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1817979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Adds to the UserBigramDictionary and/or AutoDictionary 1818979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param addToBigramDictionary true if it should be added to bigram dictionary if possible 1819979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 1820979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta, 1821979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean addToBigramDictionary) { 1822979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion == null || suggestion.length() < 1) return; 18230c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be 18240c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // adding words in situations where the user or application really didn't 18250c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // want corrections enabled or learned. 1826979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!(mCorrectionMode == Suggest.CORRECTION_FULL 1827979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) { 1828979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1829979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1830e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion) 1831e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || (!mSuggest.isValidWord(suggestion.toString()) 1832e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) { 1833e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); 1834e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 1835979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1836e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mUserBigramDictionary != null) { 1837e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1838e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mSentenceSeparators); 1839e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!TextUtils.isEmpty(prevWord)) { 1840e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); 1841979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 184232e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 184332e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 184432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 1845923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCursorTouchingWord() { 1846923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1847923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return false; 1848923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toLeft = ic.getTextBeforeCursor(1, 0); 1849923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toRight = ic.getTextAfterCursor(1, 0); 1850923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!TextUtils.isEmpty(toLeft) 185155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toLeft.charAt(0)) 185255b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toLeft.charAt(0))) { 1853923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1854923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1855a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker if (!TextUtils.isEmpty(toRight) 185655b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toRight.charAt(0)) 185755b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toRight.charAt(0))) { 1858923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1859923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1860923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1861923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1862a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1863dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) { 1864dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); 1865dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani return TextUtils.equals(text, beforeText); 1866dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani } 1867dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 1868923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void revertLastWord(boolean deleteChar) { 1869923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 18709fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions && length > 0) { 1871923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1872c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = true; 1873504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); 1874923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (deleteChar) ic.deleteSurroundingText(1, 0); 1875923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int toDelete = mCommittedLength; 1876504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); 1877504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { 1878923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project toDelete--; 1879923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1880923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(toDelete, 0); 188130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Re-insert punctuation only when the deleted character was word separator and the 188230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // composing text wasn't equal to the auto-corrected text. 188330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka if (deleteChar 188430be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) 188530be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.equals(mComposing, toTheLeft)) { 1886504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.commitText(mComposing, 1); 1887504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.acceptedTyped(mComposing); 188830be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka ic.commitText(punctuation, 1); 188930be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka TextEntryState.typedCharacter(punctuation.charAt(0), true); 189030be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Clear composing text 189130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mComposing.setLength(0); 1892504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } else { 189330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mHasValidSuggestions = true; 1894504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.setComposingText(mComposing, 1); 1895504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.backspace(); 1896504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1897d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1898923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1899923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 1900c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1901923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1902923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1903923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1904923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected String getWordSeparators() { 1905923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mWordSeparators; 1906923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1907a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1908923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean isWordSeparator(int code) { 1909923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project String separators = getWordSeparators(); 1910923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return separators.contains(String.valueOf((char)code)); 1911923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1912923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1913979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSentenceSeparator(int code) { 1914923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mSentenceSeparators.contains(String.valueOf((char)code)); 1915923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1916923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1917923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void sendSpace() { 1918571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka sendKeyChar((char)Keyboard.CODE_SPACE); 1919b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1920923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1921923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1922923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean preferCapitalization() { 19230b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return mWord.isFirstCharCapitalized(); 1924923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1925923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1926c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID 1927c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // according to new language or mode. 1928c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka public void onRefreshKeyboard() { 19294ab730dbd34fad323063f2ffd31ce33de746668dsatok toggleLanguage(true, true); 19304ab730dbd34fad323063f2ffd31ce33de746668dsatok } 19314ab730dbd34fad323063f2ffd31ce33de746668dsatok 19324ab730dbd34fad323063f2ffd31ce33de746668dsatok // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. 19333f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani private void toggleLanguage(boolean reset, boolean next) { 1934de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { 19354ab730dbd34fad323063f2ffd31ce33de746668dsatok mSubtypeSwitcher.toggleLanguage(reset, next); 19364ab730dbd34fad323063f2ffd31ce33de746668dsatok } 19374ab730dbd34fad323063f2ffd31ce33de746668dsatok // Reload keyboard because the current language has been changed. 1938b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 19398b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final EditorInfo attribute = getCurrentInputEditorInfo(); 1940c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int mode = initializeInputAttributesAndGetMode((attribute != null) 1941c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka ? attribute.inputType : 0); 1942d98c20b036ff02f99406dabb8cc4fdf4a51cd6c4Tadashi G. Takaoka final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; 1943409220583333bdf06290dd9fd42f91b5c0d1b11asatok switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(), 1944409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.isVoiceButtonOnPrimary()); 19450ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 1946b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 194736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 194836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 19495a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 195036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 195136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String key) { 19520ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.onSharedPreferenceChanged(sharedPreferences, key); 19539502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) { 195436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mRefreshKeyboardRequired = true; 19559502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka } else if (Settings.PREF_RECORRECTION_ENABLED.equals(key)) { 19569502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mReCorrectionEnabled = sharedPreferences.getBoolean( 19579502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_RECORRECTION_ENABLED, 1958458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mResources.getBoolean(R.bool.default_recorrection_enabled)); 195936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 196036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 196136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 19625a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 19638aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onSwipeDown() { 1964363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka if (mConfigSwipeDownDismissKeyboardEnabled) 1965363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka handleClose(); 1966923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1967923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19685a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1969923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onPress(int primaryCode) { 1970cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) { 1971cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka vibrate(); 1972cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka playKeyClick(primaryCode); 1973cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 19741679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 19751679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1976571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1977b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onPressShift(); 1978e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 19796c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onPressSymbol(); 198040a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } else { 19816c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onOtherKeyPressed(); 1982681b102a492b7d5301c1ca87985b4c391eb5eb14Tadashi G. Takaoka } 1983923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1984923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19855a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1986923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onRelease(int primaryCode) { 19871679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 19883f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani // Reset any drag flags in the keyboard 19891679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka switcher.keyReleased(); 19901679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1991571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1992889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka switcher.onReleaseShift(); 1993e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 19946c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onReleaseSymbol(); 199540a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } 1996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1997a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1998a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1999923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // receive ringer mode changes to detect silent mode 2000923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private BroadcastReceiver mReceiver = new BroadcastReceiver() { 2001923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 2002923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onReceive(Context context, Intent intent) { 2003923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 2004923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2005923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 2006923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2007923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // update flags for silent mode 2008923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void updateRingerMode() { 2009923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 2010923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 2011923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2012923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager != null) { 2013923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); 2014923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2015923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2016923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2017923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void playKeyClick(int primaryCode) { 2018923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // if mAudioManager is null, we don't have the ringer state yet 2019923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // mAudioManager will be set by updateRingerMode 2020923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 2021979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mKeyboardSwitcher.getInputView() != null) { 2022923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 2023923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2024923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2025923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSoundOn && !mSilentMode) { 2026923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: Volume and enable should come from UI settings 2027923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: These should be triggered after auto-repeat logic 2028923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int sound = AudioManager.FX_KEYPRESS_STANDARD; 2029923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 2030571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 2031923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_DELETE; 2032923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2033571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_ENTER: 2034923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_RETURN; 2035923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2036571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SPACE: 2037923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_SPACEBAR; 2038923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2039923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2040923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager.playSoundEffect(sound, FX_VOLUME); 2041923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2042923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2043923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2044409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void vibrate() { 2045923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mVibrateOn) { 2046923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 2047923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 20481679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 20491679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) { 20501679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.performHapticFeedback( 2051979f8690967ff5409fe18f5085858ccdb8e0ccf1satok HapticFeedbackConstants.KEYBOARD_TAP, 205266a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); 2053923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2054923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2055923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 205671c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public void promoteToUserDictionary(String word, int frequency) { 205734386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani if (mUserDictionary.isValidWord(word)) return; 205834386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mUserDictionary.addWord(word, frequency); 205934386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani } 206034386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 206171c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public WordComposer getCurrentWord() { 20626516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani return mWord; 20636516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani } 20646516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani 206571c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public boolean getPopupOn() { 2066979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mPopupOn; 2067979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2068979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2069e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private void updateCorrectionMode() { 2070e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; 2071e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) 2072e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani && !mInputTypeNoAutoCorrect && mHasDictionary; 207332e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) 2074e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani ? Suggest.CORRECTION_FULL 207532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); 2076979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) 2077979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; 2078e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani if (mSuggest != null) { 2079e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mSuggest.setCorrectionMode(mCorrectionMode); 2080e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2081e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2082e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani 20830ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void updateAutoTextEnabled() { 208432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani if (mSuggest == null) return; 20850ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSuggest.setAutoTextEnabled(mQuickFixes 20864ab730dbd34fad323063f2ffd31ce33de746668dsatok && SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage()); 208732e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 208832e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 20897599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private void updateSuggestionVisibility(SharedPreferences prefs) { 2090458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 20917599cfea4a2d56f4779452ec8e8742f7b9629cc0satok final String suggestionVisiblityStr = prefs.getString( 20929502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_SHOW_SUGGESTIONS_SETTING, 2093458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa res.getString(R.string.prefs_suggestion_visibility_default_value)); 20947599cfea4a2d56f4779452ec8e8742f7b9629cc0satok for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { 2095458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa if (suggestionVisiblityStr.equals(res.getString(visibility))) { 20967599cfea4a2d56f4779452ec8e8742f7b9629cc0satok mSuggestionVisibility = visibility; 20977599cfea4a2d56f4779452ec8e8742f7b9629cc0satok break; 20987599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 20997599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 21007599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 21017599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 2102466741d8a78965b8509bf527344f289e50873092Mike LeBeau protected void launchSettings() { 21039502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(Settings.class); 2104466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 2105466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2106bf96661d33d0126adb60a48880ceba1ff055d4a4satok public void launchDebugSettings() { 21079502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(DebugSettings.class); 2108bf96661d33d0126adb60a48880ceba1ff055d4a4satok } 2109bf96661d33d0126adb60a48880ceba1ff055d4a4satok 2110507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka protected void launchSettings(Class<? extends PreferenceActivity> settingsClass) { 2111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project handleClose(); 2112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Intent intent = new Intent(); 2113466741d8a78965b8509bf527344f289e50873092Mike LeBeau intent.setClass(LatinIME.this, settingsClass); 2114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project startActivity(intent); 2116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2118507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private void loadSettings(EditorInfo attribute) { 2119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Get the settings preferences 212027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 21214174655e23734563775acb9e1e644b31b9e72fa5Ken Wakasa Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 21224174655e23734563775acb9e1e644b31b9e72fa5Ken Wakasa mVibrateOn = vibrator != null && vibrator.hasVibrator() 21239502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); 21249502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, false); 21259502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mPopupOn = prefs.getBoolean(Settings.PREF_POPUP_ON, 21269b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka mResources.getBoolean(R.bool.config_default_popup_preview)); 21279502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); 212889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 2129a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 213027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mAutoCorrectEnabled = isAutoCorrectEnabled(prefs); 213127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs); 21321b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 2133466741d8a78965b8509bf527344f289e50873092Mike LeBeau 213427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mVoiceConnector.loadSettings(attribute, prefs); 2135409220583333bdf06290dd9fd42f91b5c0d1b11asatok 2136e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 21370ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 213827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa updateSuggestionVisibility(prefs); 213927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.getInstance().loadSettings(); 214036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 214136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 2142b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda /** 21431b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold. 2144b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda */ 21451b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) { 2146b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // When mSuggest is not initialized, cannnot modify mSuggest's threshold. 2147b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (mSuggest == null) return; 21481b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When auto correction setting is turned off, the threshold is ignored. 2149b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (!isAutoCorrectEnabled(sp)) return; 2150b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 21511b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 21521b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 21539ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 21541b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String[] autoCorrectionThresholdValues = mResources.getStringArray( 21559ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.array.auto_correction_threshold_values); 21561b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned off. 21571b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka double autoCorrectionThreshold = Double.MAX_VALUE; 2158b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda try { 21591b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); 21601b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { 21611b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.parseDouble( 21621b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThresholdValues[arrayIndex]); 2163b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2164b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } catch (NumberFormatException e) { 21651b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // Whenever the threshold settings are correct, never come here. 21661b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.MAX_VALUE; 21671b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Log.w(TAG, "Cannot load auto correction threshold setting." 21681b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting 21691b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + ", autoCorrectionThresholdValues: " 21701b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + Arrays.toString(autoCorrectionThresholdValues)); 2171b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2172b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // TODO: This should be refactored : 21731b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // setAutoCorrectionThreshold should be called outside of this method. 21741b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold); 2175b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2176b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 217789764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard private boolean isQuickFixesEnabled(SharedPreferences sp) { 217889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showQuickFixesOption = mResources.getBoolean( 217989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_quick_fixes_option); 218089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showQuickFixesOption) { 218189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 218289764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 218389764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_QUICK_FIXES, mResources.getBoolean( 218489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_quick_fixes)); 218589764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 218689764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard 2187b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isAutoCorrectEnabled(SharedPreferences sp) { 21881b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 21891b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 21909ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 21911b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String autoCorrectionOff = mResources.getString( 21929ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.string.auto_correction_threshold_mode_index_off); 21931b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka return !currentAutoCorrectionSetting.equals(autoCorrectionOff); 2194b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2195b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2196b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isBigramSuggestionEnabled(SharedPreferences sp) { 219789764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showBigramSuggestionsOption = mResources.getBoolean( 219889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_bigram_suggestions_option); 219989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showBigramSuggestionsOption) { 220089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 220189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 220289764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, mResources.getBoolean( 220389764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_bigram_suggestions)); 2204b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2205b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 22066a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani private void initSuggestPuncList() { 22077e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (mSuggestPuncs != null || mSuggestPuncList != null) 22087e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return; 22097e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder(); 22107e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka String puncs = mResources.getString(R.string.suggested_punctuations); 22117e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (puncs != null) { 22127e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka for (int i = 0; i < puncs.length(); i++) { 22137e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.addWord(puncs.subSequence(i, i + 1)); 22146a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 22156a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 22167e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncList = builder.build(); 22177e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncs = puncs; 22186a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 22196a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 2220979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSuggestedPunctuation(int code) { 2221979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mSuggestPuncs.contains(String.valueOf((char)code)); 2222979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2223979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 22242fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showSubtypeSelectorAndSettings() { 222585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 222685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 222785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka // TODO: Should use new string "Select active input modes". 222885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.language_selection_title), 222985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 223085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 223185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 22322fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka @Override 22332fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka public void onClick(DialogInterface di, int position) { 22342fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka di.dismiss(); 22352fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka switch (position) { 223685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 22372fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka launchSettings(); 22382fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 223985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 1: 22402fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka Intent intent = new Intent( 22412fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS); 22422fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 22432fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 22442fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_CLEAR_TOP); 22452fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka intent.putExtra(android.provider.Settings.EXTRA_INPUT_METHOD_ID, 22462fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mInputMethodId); 22472fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka startActivity(intent); 22482fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 22492fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 22502fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 225185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 225285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 22532fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 2254923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 22552fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showOptionsMenu() { 225685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 225785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 225885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.selectInputMethod), 225985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 226085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 226185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 22625a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2263923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onClick(DialogInterface di, int position) { 2264923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project di.dismiss(); 2265923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (position) { 226685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 22672fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka launchSettings(); 22682fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 226985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 1: 22702fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mImm.showInputMethodPicker(); 22712fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 2272923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2273923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 227485996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 227585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 22762fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 22772fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka 227885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka private void showOptionsMenuInternal(CharSequence title, CharSequence[] items, 227985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka DialogInterface.OnClickListener listener) { 22802fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka AlertDialog.Builder builder = new AlertDialog.Builder(this); 22812fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setCancelable(true); 22822fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setIcon(R.drawable.ic_dialog_keyboard); 22832fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setNegativeButton(android.R.string.cancel, null); 228485996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setItems(items, listener); 228585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setTitle(title); 2286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog = builder.create(); 2287a2ad96d95986eb61c3d2d5abce154fb4c3803cacTadashi G. Takaoka mOptionsDialog.setCanceledOnTouchOutside(true); 2288923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Window window = mOptionsDialog.getWindow(); 2289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project WindowManager.LayoutParams lp = window.getAttributes(); 2290979f8690967ff5409fe18f5085858ccdb8e0ccf1satok lp.token = mKeyboardSwitcher.getInputView().getWindowToken(); 2291923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2292923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.setAttributes(lp); 2293923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2294923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog.show(); 2295923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2296923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 22977e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 22987e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2299923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.dump(fd, fout, args); 2300a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2301923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 2302923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println("LatinIME state :"); 2303923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode()); 2304923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mComposing=" + mComposing.toString()); 23059fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn); 2306923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mCorrectionMode=" + mCorrectionMode); 23079fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mHasValidSuggestions=" + mHasValidSuggestions); 2308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoCorrectOn=" + mAutoCorrectOn); 2309923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoSpace=" + mAutoSpace); 23101b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); 2311923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" TextEntryState.state=" + TextEntryState.getState()); 2312923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mSoundOn=" + mSoundOn); 2313923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mVibrateOn=" + mVibrateOn); 2314979f8690967ff5409fe18f5085858ccdb8e0ccf1satok p.println(" mPopupOn=" + mPopupOn); 2315923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 23166e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani 2317923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Characters per second measurement 2318a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2319923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastCpsTime; 2320923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int CPS_BUFFER_SIZE = 16; 2321923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; 2322923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mCpsIndex; 2323a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void measureCps() { 2325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long now = System.currentTimeMillis(); 2326923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial 2327923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIntervals[mCpsIndex] = now - mLastCpsTime; 2328923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastCpsTime = now; 2329923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE; 2330923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long total = 0; 2331923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; 2332923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); 2333923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 233434386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 23350ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok @Override 23360ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { 23374ab730dbd34fad323063f2ffd31ce33de746668dsatok SubtypeSwitcher.getInstance().updateSubtype(subtype); 23380ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 2339923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 2340