LatinIME.java revision bbd651a00898dabf6b2ae0e715d99953ea81063f
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; 70e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.widget.HorizontalScrollView; 7140ac45ebdcd71940394dda00371d4847f7db0f26Ken Wakasaimport android.widget.LinearLayout; 72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 73466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.FileDescriptor; 74466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.PrintWriter; 75466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.ArrayList; 76b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimodaimport java.util.Arrays; 77466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.Locale; 78466741d8a78965b8509bf527344f289e50873092Mike LeBeau 79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Input method implementation for Qwerty'ish keyboard. 81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 8255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaokapublic class LatinIME extends InputMethodService implements KeyboardActionListener, 83e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka SharedPreferences.OnSharedPreferenceChangeListener { 84466741d8a78965b8509bf527344f289e50873092Mike LeBeau private static final String TAG = "LatinIME"; 85979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final boolean PERF_DEBUG = false; 86409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean DEBUG = false; 87409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean TRACE = false; 88a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 89fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_SUGGESTIONS = 180; 90fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300; 91d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int DELAY_UPDATE_SHIFT_STATE = 300; 92fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa 93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // How many continuous deletes at which to start deleting at a higher speed. 94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int DELETE_ACCELERATE_AT = 20; 95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Key events coming any faster than this are long-presses. 96d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani private static final int QUICK_PRESS = 200; 97a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 98923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Contextual menu positions 99c1ff28462eee5880267fd2eae4da389b25f6f3daKen Wakasa private static final int POS_METHOD = 0; 100c1ff28462eee5880267fd2eae4da389b25f6f3daKen Wakasa private static final int POS_SETTINGS = 1; 101466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1027599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private int mSuggestionVisibility; 1037599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE 1047599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_value; 1057599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 1067599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_only_portrait_value; 1077599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_HIDE_VALUE 1087599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_hide_value; 1097599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1107599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int[] SUGGESTION_VISIBILITY_VALUE_ARRAY = new int[] { 1117599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_VALUE, 1127599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE, 1137599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_HIDE_VALUE 1147599cfea4a2d56f4779452ec8e8742f7b9629cc0satok }; 1157599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 116e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka private View mCandidateViewContainer; 117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CandidateView mCandidateView; 118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Suggest mSuggest; 1191b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private CompletionInfo[] mApplicationSpecifiedCompletions; 120a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AlertDialog mOptionsDialog; 122a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 12379efbed76f638be298493107fa2d0cd1b5eb529esatok private InputMethodManager mImm; 12471c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private KeyboardSwitcher mKeyboardSwitcher; 1250ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 126409220583333bdf06290dd9fd42f91b5c0d1b11asatok private VoiceIMEConnector mVoiceConnector; 127a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private UserDictionary mUserDictionary; 129979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private UserBigramDictionary mUserBigramDictionary; 1302bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer private ContactsDictionary mContactsDictionary; 1314ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani private AutoDictionary mAutoDictionary; 13236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1337e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka private Resources mResources; 13427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa private SharedPreferences mPrefs; 13536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 136c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // These variables are initialized according to the {@link EditorInfo#inputType}. 137c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mAutoSpace; 138c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mInputTypeNoAutoCorrect; 139c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mIsSettingsSuggestionStripOn; 140c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mApplicationSpecifiedCompletionOn; 141c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 14271c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final StringBuilder mComposing = new StringBuilder(); 143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private WordComposer mWord = new WordComposer(); 144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CharSequence mBestWord; 1459fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean mHasValidSuggestions; 146e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mHasDictionary; 1479a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private boolean mJustAddedAutoSpace; 148e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mAutoCorrectEnabled; 14966b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok private boolean mReCorrectionEnabled; 150979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mBigramSuggestionEnabled; 151923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCorrectOn; 152923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mVibrateOn; 153923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSoundOn; 154979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mPopupOn; 155923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCap; 1566e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani private boolean mQuickFixes; 157363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka private boolean mConfigSwipeDownDismissKeyboardEnabled; 158de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; 159de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDurationOfFadeoutLanguageOnSpacebar; 160d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; 161409220583333bdf06290dd9fd42f91b5c0d1b11asatok 16279efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCorrectionMode; 16379efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCommittedLength; 16479efbed76f638be298493107fa2d0cd1b5eb529esatok private int mOrientation; 165979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Keep track of the last selection range to decide if we need to show word alternatives 16679efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionStart; 16779efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionEnd; 1687e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords mSuggestPuncList; 169979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 170923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Indicates whether the suggestion strip is to be on in landscape 171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mJustAccepted; 172c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa private boolean mJustReverted; 173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mDeleteCount; 174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastKeyTime; 175a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AudioManager mAudioManager; 1772296317b8f0209789f797ac8a2fcb70e03f6d001Eric Laurent // Align sound effect volume on music volume 17871c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private static final float FX_VOLUME = -1.0f; 179923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSilentMode; 180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 181979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /* package */ String mWordSeparators; 182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private String mSentenceSeparators; 183979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private String mSuggestPuncs; 184409220583333bdf06290dd9fd42f91b5c0d1b11asatok // TODO: Move this flag to VoiceIMEConnector 18581c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani private boolean mConfigurationChanging; 186466741d8a78965b8509bf527344f289e50873092Mike LeBeau 187dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Keeps track of most recently inserted text (multi-character key) for reverting 188dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private CharSequence mEnteredText; 189979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mRefreshKeyboardRequired; 190dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 19171c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>(); 192979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 193979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public abstract static class WordAlternatives { 194979f8690967ff5409fe18f5085858ccdb8e0ccf1satok protected CharSequence mChosenWord; 1954f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 196979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public WordAlternatives() { 197979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Nothing 198979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 199979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 200979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public WordAlternatives(CharSequence chosenWord) { 201979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mChosenWord = chosenWord; 202979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 203979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 204979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 205979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public int hashCode() { 206979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mChosenWord.hashCode(); 207979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 208979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 209979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public abstract CharSequence getOriginalWord(); 210979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 211979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public CharSequence getChosenWord() { 212979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mChosenWord; 213979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 214979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2157e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public abstract SuggestedWords.Builder getAlternatives(); 216979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 217979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 218979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public class TypedWordAlternatives extends WordAlternatives { 219979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private WordComposer word; 220979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 221979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public TypedWordAlternatives() { 222979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Nothing 223979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 224979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 225979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) { 226979f8690967ff5409fe18f5085858ccdb8e0ccf1satok super(chosenWord); 227979f8690967ff5409fe18f5085858ccdb8e0ccf1satok word = wordComposer; 228979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 229979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 230979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 231979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public CharSequence getOriginalWord() { 232979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return word.getTypedWord(); 233979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 234979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 235979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 2367e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public SuggestedWords.Builder getAlternatives() { 237979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return getTypedSuggestions(word); 238979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 239979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 24036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 241571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka public final UIHandler mHandler = new UIHandler(); 242d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 243409220583333bdf06290dd9fd42f91b5c0d1b11asatok public class UIHandler extends Handler { 244d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SUGGESTIONS = 0; 245d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; 246d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SHIFT_STATE = 2; 247d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_VOICE_RESULTS = 3; 248de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; 249de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; 250d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 252923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void handleMessage(Message msg) { 253de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 254de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = switcher.getInputView(); 255923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 256d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SUGGESTIONS: 257d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka updateSuggestions(); 258d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 259d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_OLD_SUGGESTIONS: 260d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka setOldSuggestions(); 261d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 262d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SHIFT_STATE: 263de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka switcher.updateShiftState(); 264d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 265d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_VOICE_RESULTS: 266e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mVoiceConnector.handleVoiceResults(preferCapitalization() 267de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); 268de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 269de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: 270de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 27166432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 272d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, 27366432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka (LatinKeyboard)msg.obj); 274de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), 275de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar); 276de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 277de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: 278de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 27966432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 280d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); 281d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 283923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 284d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 285d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateSuggestions() { 286d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 287d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), DELAY_UPDATE_SUGGESTIONS); 288d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 289d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 290d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateSuggestions() { 291d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 292d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 293d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 294d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public boolean hasPendingUpdateSuggestions() { 295d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka return hasMessages(MSG_UPDATE_SUGGESTIONS); 296d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 297d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 298d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateOldSuggestions() { 299d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 300d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 301d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka DELAY_UPDATE_OLD_SUGGESTIONS); 302d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 303d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 304d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateOldSuggestions() { 305d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 306d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 307d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 308d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateShiftKeyState() { 309d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 310d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), DELAY_UPDATE_SHIFT_STATE); 311d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 312d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 313d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateShiftState() { 314d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 315d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 316d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 317d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void updateVoiceResults() { 318d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessage(obtainMessage(MSG_VOICE_RESULTS)); 319d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 320de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka 321d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka public void startDisplayLanguageOnSpacebar(boolean localeChanged) { 322de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); 323de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); 324de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 325de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) { 326de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboard keyboard = inputView.getLatinKeyboard(); 327de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is never displayed when the delay is zero. 328de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) 329d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f 330d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); 331de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is always displayed when the delay is negative. 332d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { 333de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), 334de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar); 335de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 336de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 337de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 338d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 339923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3407e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 3417e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka public void onCreate() { 34227d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 34327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mPrefs = prefs; 34427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa LatinImeLogger.init(this, prefs); 34527d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.init(this, prefs); 34627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa KeyboardSwitcher.init(this, prefs); 347363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 348923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onCreate(); 349363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 35079efbed76f638be298493107fa2d0cd1b5eb529esatok mImm = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)); 3510ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 3520ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mKeyboardSwitcher = KeyboardSwitcher.getInstance(); 353363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 354363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka final Resources res = getResources(); 355363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mResources = res; 3569502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mReCorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED, 357363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka res.getBoolean(R.bool.default_recorrection_enabled)); 358363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( 359363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka R.bool.config_swipe_down_dismiss_keyboard_enabled); 360de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( 361de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_delay_before_fadeout_language_on_spacebar); 362de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( 363de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_duration_of_fadeout_language_on_spacebar); 364d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( 36566432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; 366979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3679502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 368979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 3699502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 370979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 3710ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 372979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 373979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 3749502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait("InitSuggest", e); 375979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 376979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 377979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 378363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mOrientation = res.getConfiguration().orientation; 3796a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani initSuggestPuncList(); 380b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // register to receive ringer mode changes for silent mode 382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); 383923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project registerReceiver(mReceiver, filter); 38427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mVoiceConnector = VoiceIMEConnector.init(this, prefs, mHandler); 3853f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani prefs.registerOnSharedPreferenceChangeListener(this); 386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 38736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 388979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 389458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa * Returns a main dictionary resource id 390458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa * @return main dictionary resource id 391979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 392458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa public static int getMainDictionaryResourceId(Resources res) { 393458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final String MAIN_DIC_NAME = "main"; 394979f8690967ff5409fe18f5085858ccdb8e0ccf1satok String packageName = LatinIME.class.getPackage().getName(); 395458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); 396979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 397979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3980ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void initSuggest() { 3990ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 4004ab730dbd34fad323063f2ffd31ce33de746668dsatok String locale = mSubtypeSwitcher.getInputLocaleStr(); 40136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4020ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale)); 40336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mSuggest != null) { 40436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mSuggest.close(); 40536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 40627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 4079502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mQuickFixes = prefs.getBoolean(Settings.PREF_QUICK_FIXES, true); 408979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 409458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 410458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa int mainDicResId = getMainDictionaryResourceId(res); 411458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mSuggest = new Suggest(this, mainDicResId); 4121b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 413e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 4140ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mUserDictionary = new UserDictionary(this, locale); 415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggest.setUserDictionary(mUserDictionary); 416e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 417e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); 4182bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer mSuggest.setContactsDictionary(mContactsDictionary); 419e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 420e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mAutoDictionary = new AutoDictionary(this, this, locale, Suggest.DIC_AUTO); 42134386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mSuggest.setAutoDictionary(mAutoDictionary); 422e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 423e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mUserBigramDictionary = new UserBigramDictionary(this, this, locale, Suggest.DIC_USER); 424e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.setUserBigramDictionary(mUserBigramDictionary); 425e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 426e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 427458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mWordSeparators = res.getString(R.string.word_separators); 428458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mSentenceSeparators = res.getString(R.string.sentence_separators); 42936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4300ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.changeSystemLocale(savedLocale); 431923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 43236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 433466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 434466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onDestroy() { 435e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa if (mSuggest != null) { 436e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.close(); 437e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest = null; 438979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 439923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project unregisterReceiver(mReceiver); 440409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.destroy(); 441979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 442979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.onDestroy(); 443923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDestroy(); 444923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 445923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 446923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 447923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onConfigurationChanged(Configuration conf) { 448dc64b138b5e3fb3706c0818d0a308fe6e36985b0Tadashi G. Takaoka mSubtypeSwitcher.onConfigurationChanged(conf); 449b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani // If orientation changed while predicting, commit the change 450b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani if (conf.orientation != mOrientation) { 451466741d8a78965b8509bf527344f289e50873092Mike LeBeau InputConnection ic = getCurrentInputConnection(); 452466741d8a78965b8509bf527344f289e50873092Mike LeBeau commitTyped(ic); 453466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (ic != null) ic.finishComposingText(); // For voice input 454b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mOrientation = conf.orientation; 455b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 4568b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 45781c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = true; 458923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onConfigurationChanged(conf); 459bbd651a00898dabf6b2ae0e715d99953ea81063fLuca Zanolin mVoiceConnector.onConfigurationChanged(conf); 46081c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = false; 461923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 462b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 463923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 464923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateInputView() { 4658d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka return mKeyboardSwitcher.onCreateInputView(); 466923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 468923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 469923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateCandidatesView() { 470e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LayoutInflater inflater = getLayoutInflater(); 471e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); 472e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateViewContainer = container; 473e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka if (container.getPaddingRight() != 0) { 474e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka HorizontalScrollView scrollView = 475e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view); 476e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); 477e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka container.setGravity(Gravity.CENTER_HORIZONTAL); 478e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka } 479e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateView = (CandidateView) container.findViewById(R.id.candidates); 480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.setService(this); 481923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setCandidatesViewShown(true); 482e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka return container; 483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 484923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 48547f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins private static boolean isPasswordVariation(int variation) { 486e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD 487e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD 488e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD; 48947f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins } 49047f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins 49147f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins private static boolean isEmailVariation(int variation) { 492e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 493e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; 49447f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins } 49547f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins 496a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker @Override 497923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onStartInputView(EditorInfo attribute, boolean restarting) { 49845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 49945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka LatinKeyboardView inputView = switcher.getInputView(); 5008e09172df1bb176cc899940862c56bed9b9aec4esatok 501923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In landscape mode, this method gets called without the input view being created. 502979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (inputView == null) { 503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 504923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 505923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 5068d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka mSubtypeSwitcher.updateParametersOnStartInputView(); 5074ab730dbd34fad323063f2ffd31ce33de746668dsatok 50836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mRefreshKeyboardRequired) { 50936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mRefreshKeyboardRequired = false; 510c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka onRefreshKeyboard(); 51136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 51236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 513923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.newSession(this); 5146c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani 515c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to 516c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // know now whether this is a password text field, because we need to know now whether we 517c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // want to enable the voice button. 518c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.resetVoiceStates(isPasswordVariation( 519c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka attribute.inputType & InputType.TYPE_MASK_VARIATION)); 520c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 521c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int mode = initializeInputAttributesAndGetMode(attribute.inputType); 522c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 523c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.closing(); 524c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mEnteredText = null; 525c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mComposing.setLength(0); 526c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHasValidSuggestions = false; 527c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mDeleteCount = 0; 528c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mJustAddedAutoSpace = false; 529c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 530c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka loadSettings(attribute); 531c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (mSubtypeSwitcher.isKeyboardMode()) { 532c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.loadKeyboard(mode, attribute.imeOptions, 533c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.isVoiceButtonEnabled(), 534c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.isVoiceButtonOnPrimary()); 535c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.updateShiftState(); 536c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 537c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 538c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka setCandidatesViewShownInternal(isCandidateStripVisible(), 539c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka false /* needsInputViewShown */ ); 540c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Delay updating suggestions because keyboard input view may not be shown at this point. 541c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHandler.postUpdateSuggestions(); 542c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 543c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka updateCorrectionMode(); 544c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 545c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setPreviewEnabled(mPopupOn); 546c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setProximityCorrectionEnabled(true); 547c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // If we just entered a text field, maybe it has some old text that requires correction 548c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka checkReCorrectionOnStart(); 549c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setForeground(true); 550c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 551c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mVoiceConnector.onStartInputView(inputView.getWindowToken()); 552c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 553c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); 554c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 555c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 556c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private int initializeInputAttributesAndGetMode(int inputType) { 557c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int variation = inputType & InputType.TYPE_MASK_VARIATION; 558c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mAutoSpace = false; 559e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = false; 5609fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 5611b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = false; 5621b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = null; 563dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 564f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka final int mode; 565c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switch (inputType & InputType.TYPE_MASK_CLASS) { 566e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_NUMBER: 567e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_DATETIME: 5685a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_NUMBER; 5692c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka break; 570e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_PHONE: 5715a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_PHONE; 572923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 573e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case InputType.TYPE_CLASS_TEXT: 5749fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = true; 575923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Make sure that passwords are not displayed in candidate view 57647f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isPasswordVariation(variation)) { 5779fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 578923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 57947f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isEmailVariation(variation) 580e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { 581923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAutoSpace = false; 582923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 583923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAutoSpace = true; 584923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 58547f795dc8709f95b35888fbcca80c0c18dbe63edLeon Scroggins if (isEmailVariation(variation)) { 5869fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 5875a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_EMAIL; 588e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { 5899fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 5905a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_URL; 591e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { 5925a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_IM; 593e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { 5949fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 5955a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 596e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { 5975a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_WEB; 5986c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani // If it's a browser edit field and auto correct is not ON explicitly, then 5996c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani // disable auto correction, but keep suggestions on. 600c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { 601e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 6026c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani } 603f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka } else { 6045a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 605923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 60636ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani 60736ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani // If NO_SUGGESTIONS is set, don't do prediction. 608c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { 6099fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 610e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 61136ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 61236ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani // If it's not multiline and the autoCorrect flag is not set, then don't correct 613c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && 614c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { 615e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 61636ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 617c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { 6189fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6191b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = isFullscreenMode(); 620923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 621923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 622923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project default: 6235a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mode = KeyboardId.MODE_TEXT; 624f8e30a91537b8b4920887d0d4f0771de3a23c4cbTadashi G. Takaoka break; 625923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 626c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mode; 627923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 628923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 629b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani private void checkReCorrectionOnStart() { 630d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (!mReCorrectionEnabled) return; 631d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 632d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa final InputConnection ic = getCurrentInputConnection(); 633d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (ic == null) return; 634d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa // There could be a pending composing span. Clean it up first. 635d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa ic.finishComposingText(); 636d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 6379fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isShowingSuggestionsStrip() && isSuggestionsRequested()) { 638b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // First get the cursor position. This is required by setOldSuggestions(), so that 639b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // it can pass the correct range to setComposingRegion(). At this point, we don't 6404ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka // have valid values for mLastSelectionStart/End because onUpdateSelection() has 641b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // not been called yet. 642b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedTextRequest etr = new ExtractedTextRequest(); 643b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani etr.token = 0; // anything is fine here 644b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedText et = ic.getExtractedText(etr, 0); 645b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani if (et == null) return; 646b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 647b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionStart = et.startOffset + et.selectionStart; 648b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionEnd = et.startOffset + et.selectionEnd; 649b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 650b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // Then look for possible corrections in a delayed fashion 65155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { 652d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 65355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 654b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 655b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 656b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 657923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 658923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onFinishInput() { 659923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onFinishInput(); 660a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 661979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 6621b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 663979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 664409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging); 665409220583333bdf06290dd9fd42f91b5c0d1b11asatok 6665a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 667d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.closing(); 6684ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); 669979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); 670466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 671466741d8a78965b8509bf527344f289e50873092Mike LeBeau 672466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 6736495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa public void onFinishInputView(boolean finishingInput) { 6746495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa super.onFinishInputView(finishingInput); 6755a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 676d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.setForeground(false); 677d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka // Remove pending messages related to update suggestions 678d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 679d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateOldSuggestions(); 6806495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa } 6816495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa 6826495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa @Override 683466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onUpdateExtractedText(int token, ExtractedText text) { 684466741d8a78965b8509bf527344f289e50873092Mike LeBeau super.onUpdateExtractedText(token, text); 685409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.showPunctuationHintIfNecessary(); 686923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 687923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 688923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 689923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onUpdateSelection(int oldSelStart, int oldSelEnd, 690923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int newSelStart, int newSelEnd, 691923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int candidatesStart, int candidatesEnd) { 692923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 693923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project candidatesStart, candidatesEnd); 694466741d8a78965b8509bf527344f289e50873092Mike LeBeau 695466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (DEBUG) { 696466741d8a78965b8509bf527344f289e50873092Mike LeBeau Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart 697466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ose=" + oldSelEnd 698466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nss=" + newSelStart 699466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nse=" + newSelEnd 700466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", cs=" + candidatesStart 701466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ce=" + candidatesEnd); 702466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 703466741d8a78965b8509bf527344f289e50873092Mike LeBeau 704409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setCursorAndSelection(newSelEnd, newSelStart); 7054f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 706923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If the current selection in the text view changes, we should 707923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // clear whatever candidate text we have. 7089fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((((mComposing.length() > 0 && mHasValidSuggestions) 7098e09172df1bb176cc899940862c56bed9b9aec4esatok || mVoiceConnector.isVoiceInputHighlighted()) && (newSelStart != candidatesEnd 7108e09172df1bb176cc899940862c56bed9b9aec4esatok || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) { 711923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 7129fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 713d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 714923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.reset(); 715923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 716923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 717923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.finishComposingText(); 718923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 719409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setVoiceInputHighlighted(false); 7209fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (!mHasValidSuggestions && !mJustAccepted) { 7219a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa switch (TextEntryState.getState()) { 722e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case ACCEPTED_DEFAULT: 723e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka TextEntryState.reset(); 724e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // $FALL-THROUGH$ 725e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case SPACE_AFTER_PICKED: 726e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mJustAddedAutoSpace = false; // The user moved the cursor. 727e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 728e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka default: 729e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 7309a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 731923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 732923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = false; 733d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 734466741d8a78965b8509bf527344f289e50873092Mike LeBeau 735979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a note of the cursor position 736979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionStart = newSelStart; 737979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionEnd = newSelEnd; 738466741d8a78965b8509bf527344f289e50873092Mike LeBeau 7399fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isShowingSuggestionsStrip()) { 74066b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Don't look for corrections if the keyboard is not visible 7411679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown()) { 74266b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Check if we should go in or out of correction mode. 7439fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isSuggestionsRequested() && !mJustReverted 74466b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok && (candidatesStart == candidatesEnd || newSelStart != oldSelStart 74566b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok || TextEntryState.isCorrecting()) 7469fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) { 74766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { 748d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 74966b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } else { 75066b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok abortCorrection(false); 75155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Show the punctuation suggestions list if the current one is not 752364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // and if not showing "Touch again to save". 7537599cfea4a2d56f4779452ec8e8742f7b9629cc0satok if (mCandidateView != null && !isShowingPunctuationList() 7547599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && !mCandidateView.isShowingAddToDictionaryHint()) { 755ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 75655b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 75766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } 758b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 759466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 760466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 761923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 762923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 763c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 764c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has clicked on the extracted text view, 765c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * when running in fullscreen mode. The default implementation hides 766c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * the candidates view when this happens, but only if the extracted text 767c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * editor has a vertical scroll bar because its text doesn't fit. 768c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 769c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 770c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 771c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 772c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedTextClicked() { 7739fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isSuggestionsRequested()) return; 774c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 775c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedTextClicked(); 776c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 777c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 778c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 779c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has performed a cursor movement in the 780c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * extracted text view, when it is running in fullscreen mode. The default 781c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * implementation hides the candidates view when a vertical movement 782c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * happens, but only if the extracted text editor has a vertical scroll bar 783c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * because its text doesn't fit. 784c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 785c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 786c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 787c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 788c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedCursorMovement(int dx, int dy) { 7899fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mReCorrectionEnabled && isSuggestionsRequested()) return; 790c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 791c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedCursorMovement(dx, dy); 792c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 793c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 794923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 795923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void hideWindow() { 796979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 7971b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 798979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 799923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (TRACE) Debug.stopMethodTracing(); 8006e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani if (mOptionsDialog != null && mOptionsDialog.isShowing()) { 8016e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog.dismiss(); 8026e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog = null; 8036e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 804409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.hideVoiceWindow(mConfigurationChanging); 805979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.clear(); 806923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.hideWindow(); 807923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.endSession(); 808923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 809923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 810923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 8111b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) { 812979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (DEBUG) { 813a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, "Received completions:"); 8141b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int count = (applicationSpecifiedCompletions != null) 8151b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka ? applicationSpecifiedCompletions.length : 0; 8161b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka for (int i = 0; i < count; i++) { 817a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]); 818923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 819923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 8201b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) { 8211b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = applicationSpecifiedCompletions; 8221b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (applicationSpecifiedCompletions == null) { 823b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 824923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 825923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 826a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 8277e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder() 8281b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka .setApplicationSpecifiedCompletions(applicationSpecifiedCompletions) 8297e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setTypedWordValid(true) 8307e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setHasMinimalSuggestion(true); 831979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // When in fullscreen mode, show completions generated by the application 8327e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(builder.build()); 833923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 834543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShown(true); 835923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 836923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 837923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 838543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { 839923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // TODO: Remove this if we support candidates with hard keyboard 840923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (onEvaluateInputViewShown()) { 8411679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka super.setCandidatesViewShown(shown 8421679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); 843923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 844923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 845a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 846923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 847543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa public void setCandidatesViewShown(boolean shown) { 848543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); 849543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa } 850543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa 851543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa @Override 852923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onComputeInsets(InputMethodService.Insets outInsets) { 853923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onComputeInsets(outInsets); 854264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project if (!isFullscreenMode()) { 855264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project outInsets.contentTopInsets = outInsets.visibleTopInsets; 856264b19a6853ab3d13d26270e99a13dc015b01bebThe Android Open Source Project } 857923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 858a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 859923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 860979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public boolean onEvaluateFullscreenMode() { 861458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 862458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa DisplayMetrics dm = res.getDisplayMetrics(); 863979f8690967ff5409fe18f5085858ccdb8e0ccf1satok float displayHeight = dm.heightPixels; 864979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // If the display is more than X inches high, don't go to fullscreen mode 865458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa float dimen = res.getDimension(R.dimen.max_height_for_fullscreen); 866979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (displayHeight > dimen) { 867979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 868979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 869979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return super.onEvaluateFullscreenMode(); 870979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 871979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 872979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 873979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 874923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 875923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 876e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_BACK: 877e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { 878e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.getInputView().handleBack()) { 8796e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani return true; 8806e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 881e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 882e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 883923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 884923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyDown(keyCode, event); 885923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 886923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 887923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 888923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 889923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 890e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_DOWN: 891e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_UP: 892e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_LEFT: 893e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_RIGHT: 894e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Enable shift key and DPAD to do selections 895e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown() 896e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && mKeyboardSwitcher.isShiftedOrShiftLocked()) { 897e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(), 898e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getAction(), event.getKeyCode(), event.getRepeatCount(), 899e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getDeviceId(), event.getScanCode(), 900e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON); 901e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka InputConnection ic = getCurrentInputConnection(); 902e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (ic != null) 903e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka ic.sendKeyEvent(newEvent); 904e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return true; 905e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 906e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 907923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 908923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyUp(keyCode, event); 909923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 910923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 911409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void commitTyped(InputConnection inputConnection) { 9129fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 9139fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 914923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() > 0) { 915923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (inputConnection != null) { 916923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project inputConnection.commitText(mComposing, 1); 917923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 918923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = mComposing.length(); 919923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedTyped(mComposing); 920979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); 921923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 922923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 923923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 924923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 925923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 926b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public boolean getCurrentAutoCapsState() { 927923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 9281c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani EditorInfo ei = getCurrentInputEditorInfo(); 929e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) { 930b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return ic.getCursorCapsMode(ei.inputType) != 0; 9311c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 932b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 9331c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 9341c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 935923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void swapPunctuationAndSpace() { 936923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 937923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); 939923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastTwo != null && lastTwo.length() == 2 940571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastTwo.charAt(0) == Keyboard.CODE_SPACE 941571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && isSentenceSeparator(lastTwo.charAt(1))) { 942923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 943923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 944923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(lastTwo.charAt(1) + " ", 1); 945923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 946b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 9479a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 948923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 949923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 9501c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 9514ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa private void reswapPeriodAndSpace() { 9524ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa final InputConnection ic = getCurrentInputConnection(); 9534ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (ic == null) return; 9544ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 9554ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastThree != null && lastThree.length() == 3 956571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(0) == Keyboard.CODE_PERIOD 957571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 958571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_PERIOD) { 9594ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.beginBatchEdit(); 9604ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.deleteSurroundingText(3, 0); 9614ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.commitText(" ..", 1); 9624ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.endBatchEdit(); 963b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 9644ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 9654ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 9664ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 967923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void doubleSpace() { 968923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project //if (!mAutoPunctuate) return; 969923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCorrectionMode == Suggest.CORRECTION_NONE) return; 970923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 971923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 972923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 973923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastThree != null && lastThree.length() == 3 974923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project && Character.isLetterOrDigit(lastThree.charAt(0)) 975571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 976571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_SPACE) { 977923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 978923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 979923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(". ", 1); 980923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 981b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 9829a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 983923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 984923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 985a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 98641a519729505a877844f2c57a33509c302dddbceKen Wakasa private void maybeRemovePreviousPeriod(CharSequence text) { 98741a519729505a877844f2c57a33509c302dddbceKen Wakasa final InputConnection ic = getCurrentInputConnection(); 98841a519729505a877844f2c57a33509c302dddbceKen Wakasa if (ic == null) return; 98941a519729505a877844f2c57a33509c302dddbceKen Wakasa 99041a519729505a877844f2c57a33509c302dddbceKen Wakasa // When the text's first character is '.', remove the previous period 99141a519729505a877844f2c57a33509c302dddbceKen Wakasa // if there is one. 99241a519729505a877844f2c57a33509c302dddbceKen Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 9934ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastOne != null && lastOne.length() == 1 994571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_PERIOD 995571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && text.charAt(0) == Keyboard.CODE_PERIOD) { 99641a519729505a877844f2c57a33509c302dddbceKen Wakasa ic.deleteSurroundingText(1, 0); 99741a519729505a877844f2c57a33509c302dddbceKen Wakasa } 99841a519729505a877844f2c57a33509c302dddbceKen Wakasa } 99941a519729505a877844f2c57a33509c302dddbceKen Wakasa 10009a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private void removeTrailingSpace() { 10019a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa final InputConnection ic = getCurrentInputConnection(); 10029a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic == null) return; 10039a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 10049a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10059a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (lastOne != null && lastOne.length() == 1 1006571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_SPACE) { 10079a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.deleteSurroundingText(1, 0); 10089a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10099a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10109a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 1011923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean addWordToDictionary(String word) { 1012923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mUserDictionary.addWord(word, 128); 10136558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Suggestion strip should be updated after the operation of adding word to the 10146558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // user dictionary 1015d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1016923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1017923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1018923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1019923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isAlphabet(int code) { 1020923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (Character.isLetter(code)) { 1021923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1022923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1023923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1024923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1025923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1026a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1027e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyPressed() { 10289a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10299502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 10309a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok showOptionsMenu(); 10319a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10329a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10339a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10349a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10359a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10369a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1037e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyLongPressed() { 10389a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10399502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 104079efbed76f638be298493107fa2d0cd1b5eb529esatok mImm.showInputMethodPicker(); 10419a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10429a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10439a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10449a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10459a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10469a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 10479a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok private boolean isShowingOptionDialog() { 10489a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok return mOptionsDialog != null && mOptionsDialog.isShowing(); 10499a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10509a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 10515f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka // Implementation of {@link KeyboardActionListener}. 10525a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 10538aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { 1054923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long when = SystemClock.uptimeMillis(); 1055571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { 1056923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDeleteCount = 0; 1057923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1058923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastKeyTime = when; 1059b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1060b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1061923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1062571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 10634189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleBackspace(); 10644189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mDeleteCount++; 10654189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnDelete(); 10664189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1067571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SHIFT: 10684189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Shift key is handled in onPress() when device has distinct multi-touch panel. 10694189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!distinctMultiTouch) 1070b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleShift(); 10714189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1072e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: 10734189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Symbol key is handled in onPress() when device has distinct multi-touch panel. 10744189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!distinctMultiTouch) 1075b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.changeKeyboardMode(); 10764189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1077571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CANCEL: 10784189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!isShowingOptionDialog()) { 10794189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleClose(); 10804189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 10814189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1082e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS: 1083e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyPressed(); 10844189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1085e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS_LONGPRESS: 1086e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyLongPressed(); 10874189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1088571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_NEXT_LANGUAGE: 10894189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka toggleLanguage(false, true); 10904189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1091571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_PREV_LANGUAGE: 10924189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka toggleLanguage(false, false); 10934189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1094571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CAPSLOCK: 1095b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleCapsLock(); 10964189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 109720cdb37bd062ae6cb6d42ad6229a19733476cd55satok case Keyboard.CODE_VOICE: 109820cdb37bd062ae6cb6d42ad6229a19733476cd55satok mSubtypeSwitcher.switchToShortcutIME(); 10994189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1100571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_TAB: 110145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka handleTab(); 11024189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 11034189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka default: 1104571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_ENTER) { 11054189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mJustAddedAutoSpace = false; 11064189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11074189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka RingCharBuffer.getInstance().push((char)primaryCode, x, y); 11084189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnInputChar(); 11094189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (isWordSeparator(primaryCode)) { 11104189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleSeparator(primaryCode); 11114189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } else { 11124189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleCharacter(primaryCode, keyCodes); 11134189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11144189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Cancel the just reverted state 1115c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1117b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onKey(primaryCode); 1118dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Reset after any single keystroke 1119dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = null; 1120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1121a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 11225a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11238aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onTextInput(CharSequence text) { 1124409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.commitVoiceInput(); 1125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1127979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(false); 1128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 112955b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka commitTyped(ic); 113041a519729505a877844f2c57a33509c302dddbceKen Wakasa maybeRemovePreviousPeriod(text); 1131923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(text, 1); 1132923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1133b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 11345f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); 1135c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 11369a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 1137dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = text; 1138923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1139923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 11405a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11418aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCancelInput() { 114283e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka // User released a finger outside any key 11435f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onCancelInput(); 114483e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka } 114583e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka 1146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleBackspace() { 1147409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (mVoiceConnector.logAndRevertVoiceInput()) return; 11484f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1149504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1150504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (ic == null) return; 1151979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.beginBatchEdit(); 1152979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1153409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleBackspace(); 11544f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1155504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka boolean deleteChar = false; 11569fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1157923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 1158923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (length > 0) { 1159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.delete(length - 1, length); 1160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.deleteLast(); 1161923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1162923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() == 0) { 11639fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1165d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1167923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(1, 0); 1168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1170923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project deleteChar = true; 1171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1172d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 1173504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.backspace(); 1175979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) { 1176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project revertLastWord(deleteChar); 1177979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1179504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1180504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1181504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { 1182dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani ic.deleteSurroundingText(mEnteredText.length(), 0); 1183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else if (deleteChar) { 11846558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 11856558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Go back to the suggestion mode if the user canceled the 118655b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // "Touch again to save". 11876558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // NOTE: In gerenal, we don't revert the word when backspacing 11886558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // from a manual suggestion pick. We deliberately chose a 11896558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // different behavior only in the case of picking the first 11906558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // suggestion (typed word). It's intentional to have made this 11916558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // inconsistent with backspacing after selecting other suggestions. 11926558253160e2039c87f424bd814f402ecd31de3bKen Wakasa revertLastWord(deleteChar); 11936558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } else { 1194923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 11956558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mDeleteCount > DELETE_ACCELERATE_AT) { 11966558253160e2039c87f424bd814f402ecd31de3bKen Wakasa sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 11976558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 1198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1199923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1200c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1201979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1202923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 120445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka private void handleTab() { 120545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int imeOptions = getCurrentInputEditorInfo().imeOptions; 120645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int navigationFlags = 120745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka EditorInfo.IME_FLAG_NAVIGATE_NEXT | EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS; 120845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if ((imeOptions & navigationFlags) == 0) { 120945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); 121045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 121145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 121245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 121345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 121445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (ic == null) 121545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 121645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 121745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // True if keyboard is in either chording shift or manual temporary upper case mode. 121845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase(); 121945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0 122045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && !isManualTemporaryUpperCase) { 122145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); 122245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0 122345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && isManualTemporaryUpperCase) { 122445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_PREVIOUS); 122545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 122645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 122745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 1228979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void abortCorrection(boolean force) { 1229979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (force || TextEntryState.isCorrecting()) { 1230ca26f20fa4903de46e374babbfba8c8a1a5cac93satok TextEntryState.onAbortCorrection(); 1231ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1232979f8690967ff5409fe18f5085858ccdb8e0ccf1satok getCurrentInputConnection().finishComposingText(); 1233b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1234923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1235923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1236a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleCharacter(int primaryCode, int[] keyCodes) { 1238409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleCharacter(); 12394f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1240b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isCorrecting()) { 1241b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani abortCorrection(false); 1242b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 12434f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1244e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int code = primaryCode; 12459fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) { 12469fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 12479fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = true; 1248923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 1249979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(mBestWord); 1250923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.reset(); 1251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1252923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 12531679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1254f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (switcher.isShiftedOrShiftLocked()) { 1255eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT 1256eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani || keyCodes[0] > Character.MAX_CODE_POINT) { 1257eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani return; 1258eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani } 1259e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = keyCodes[0]; 1260e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (switcher.isAlphabetMode() && Character.isLowerCase(code)) { 1261e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int upperCaseCode = Character.toUpperCase(code); 1262e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (upperCaseCode != code) { 1263e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = upperCaseCode; 126412a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } else { 126512a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka // Some keys, such as [eszett], have upper case as multi-characters. 1266e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka String upperCase = new String(new int[] {code}, 0, 1).toUpperCase(); 12678aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka onTextInput(upperCase); 126812a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka return; 126912a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } 1270979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1271923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 12729fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1273f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (mComposing.length() == 0 && switcher.isAlphabetMode() 1274f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka && switcher.isShiftedOrShiftLocked()) { 12750b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa mWord.setFirstCharCapitalized(true); 1276923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1277e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mComposing.append((char) code); 1278e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mWord.add(code, keyCodes); 1279923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 12811c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani // If it's the first letter, make note of auto-caps state 12821c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani if (mWord.size() == 1) { 1283b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mWord.setAutoCapitalized(getCurrentAutoCapsState()); 12841c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 1285923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1287d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1288923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1289e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka sendKeyChar((char)code); 1290923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1291b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 1292979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (LatinIME.PERF_DEBUG) measureCps(); 1293e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka TextEntryState.typedCharacter((char) code, isWordSeparator(code)); 1294923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1295923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1296923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleSeparator(int primaryCode) { 1297409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleSeparator(); 12984f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 129955b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Should dismiss the "Touch again to save" message when handling separator 13006558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 1301d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 13026558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 13036558253160e2039c87f424bd814f402ecd31de3bKen Wakasa 1304923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project boolean pickedDefault = false; 1305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Handle separator 13061b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1309979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(false); 1310923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13119fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1312923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In certain languages where single quote is a separator, it's better 1313a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker // not to auto correct, but accept the typed word. For instance, 1314923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // in Italian dov' should not be expanded to dove' because the elision 1315923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // requires the last vowel to be removed. 1316c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa if (mAutoCorrectOn && primaryCode != '\'' && !mJustReverted) { 1317979f8690967ff5409fe18f5085858ccdb8e0ccf1satok pickedDefault = pickDefaultSuggestion(); 13189a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // Picked the suggestion by the space key. We consider this 13199a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // as "added an auto space". 1320571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode == Keyboard.CODE_SPACE) { 13219a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 13229a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1323923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(ic); 1325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1326923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1327571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) { 13289a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa removeTrailingSpace(); 13299a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 13309a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1331923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendKeyChar((char)primaryCode); 13324ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 13334ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // Handle the case of ". ." -> " .." with auto-space if necessary 13344ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // before changing the TextEntryState. 1335979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED 1336571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && primaryCode == Keyboard.CODE_PERIOD) { 13374ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa reswapPeriodAndSpace(); 13384ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 13394ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.typedCharacter((char) primaryCode, true); 1341979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED 1342571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && primaryCode != Keyboard.CODE_ENTER) { 1343923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project swapPunctuationAndSpace(); 13449fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { 1345923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project doubleSpace(); 1346923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1347979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (pickedDefault) { 134855b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka CharSequence typedWord = mWord.getTypedWord(); 134955b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka TextEntryState.backToAcceptedDefault(typedWord); 135055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { 13514ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka if (ic != null) { 13524ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka CorrectionInfo correctionInfo = new CorrectionInfo( 13534ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); 13544ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka ic.commitCorrection(correctionInfo); 13554ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka } 135655b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (mCandidateView != null) 135755b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka mCandidateView.onAutoCorrectionInverted(mBestWord); 135855b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka } 135955b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka setPunctuationSuggestions(); 1360923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1361b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1362923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1363923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1364923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1365923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1366466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1367923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleClose() { 1368923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(getCurrentInputConnection()); 1369409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.handleClose(); 1370923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestHideSelf(0); 13711679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 13721679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) 13731679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.closing(); 1374923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.endSession(); 1375923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1376923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1377979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void saveWordInHistory(CharSequence result) { 1378979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mWord.size() <= 1) { 1379979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWord.reset(); 1380979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1382979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Skip if result is null. It happens in some edge case. 1383979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextUtils.isEmpty(result)) { 1384979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1385923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1386979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1387979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a copy of the CharSequence, since it is/could be a mutable CharSequence 1388979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final String resultCopy = result.toString(); 1389979f8690967ff5409fe18f5085858ccdb8e0ccf1satok TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy, 1390979f8690967ff5409fe18f5085858ccdb8e0ccf1satok new WordComposer(mWord)); 1391979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.add(entry); 1392923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1393923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 13949fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isSuggestionsRequested() { 1395c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mIsSettingsSuggestionStripOn 1396c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); 1397923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1398a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 13997599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private boolean isShowingPunctuationList() { 14007e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return mSuggestPuncList == mCandidateView.getSuggestions(); 14017599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14027599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 14039fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isShowingSuggestionsStrip() { 14047599cfea4a2d56f4779452ec8e8742f7b9629cc0satok return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) 14057599cfea4a2d56f4779452ec8e8742f7b9629cc0satok || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 14067599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && mOrientation == Configuration.ORIENTATION_PORTRAIT); 14077599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14087599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1409923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCandidateStripVisible() { 14109fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isCorrecting()) 14119fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14129fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!isShowingSuggestionsStrip()) 14139fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return false; 14149fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) 14159fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14169fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return isSuggestionsRequested(); 1417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1419409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void switchToKeyboardView() { 14205a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mHandler.post(new Runnable() { 14215a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 14225a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka public void run() { 14235a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (DEBUG) { 14245a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka Log.d(TAG, "Switch to keyboard view."); 14255a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14265a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka View v = mKeyboardSwitcher.getInputView(); 14275a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (v != null) { 14285a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka // Confirms that the keyboard view doesn't have parent view. 14295a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka ViewParent p = v.getParent(); 14305a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (p != null && p instanceof ViewGroup) { 14315a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka ((ViewGroup) p).removeView(v); 14325a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14335a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka setInputView(v); 14345a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14355a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 14365a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka updateInputViewShown(); 14375a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 14385a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 14395a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka }); 1440466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1441466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1442409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void clearSuggestions() { 14437e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(SuggestedWords.EMPTY); 1444466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1445466741d8a78965b8509bf527344f289e50873092Mike LeBeau 14467e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public void setSuggestions(SuggestedWords words) { 1447409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (mVoiceConnector.getAndResetIsShowingHint()) { 1448466741d8a78965b8509bf527344f289e50873092Mike LeBeau setCandidatesView(mCandidateViewContainer); 1449466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1450466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1451466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (mCandidateView != null) { 14527e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mCandidateView.setSuggestions(words); 14539ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka if (mCandidateView.isConfigCandidateHighlightFontColorEnabled()) { 14549ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged( 14559ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka words.hasWordAboveAutoCorrectionScoreThreshold()); 14569ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka } 1457466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1458466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1459466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1460409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void updateSuggestions() { 14611679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(null); 14621b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani 1463923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Check if we have a suggestion engine attached. 14649fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((mSuggest == null || !isSuggestionsRequested()) 1465409220583333bdf06290dd9fd42f91b5c0d1b11asatok && !mVoiceConnector.isVoiceInputHighlighted()) { 1466923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1468466741d8a78965b8509bf527344f289e50873092Mike LeBeau 14699fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1470ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1471923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1472923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1473979f8690967ff5409fe18f5085858ccdb8e0ccf1satok showSuggestions(mWord); 1474979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1475979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 14767e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords.Builder getTypedSuggestions(WordComposer word) { 14779ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka return mSuggest.getSuggestedWordBuilder(mKeyboardSwitcher.getInputView(), word, null); 1478979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1479979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1480979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showCorrections(WordAlternatives alternatives) { 14811679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(null); 14827e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = alternatives.getAlternatives(); 14837e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.setTypedWordValid(false).setHasMinimalSuggestion(false); 14847e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), alternatives.getOriginalWord()); 1485979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1486979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1487979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showSuggestions(WordComposer word) { 1488979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // TODO Maybe need better way of retrieving previous word 1489e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1490979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordSeparators); 14917e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 14929ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.getInputView(), word, prevWord); 1493923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 14941b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies(); 14951679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka mKeyboardSwitcher.setPreferredLetters(nextLettersFrequencies); 14961b62ff1a3d61cd44ab88acdfcbdf0fc70a7e1b10Amith Yamasani 1497378a1b516d867671d292900c5d42aef3a0dc1556Ken Wakasa boolean correctionAvailable = !mInputTypeNoAutoCorrect && !mJustReverted 1498378a1b516d867671d292900c5d42aef3a0dc1556Ken Wakasa && mSuggest.hasMinimalCorrection(); 1499a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final CharSequence typedWord = word.getTypedWord(); 1500923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If we're in basic correct 1501a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final boolean typedWordValid = mSuggest.isValidWord(typedWord) || 1502979f8690967ff5409fe18f5085858ccdb8e0ccf1satok (preferCapitalization() 1503979f8690967ff5409fe18f5085858ccdb8e0ccf1satok && mSuggest.isValidWord(typedWord.toString().toLowerCase())); 1504979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mCorrectionMode == Suggest.CORRECTION_FULL 1505979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { 1506923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project correctionAvailable |= typedWordValid; 1507923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15084a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani // Don't auto-correct words with multiple capital letter 1509979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !word.isMostlyCaps(); 1510979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !TextEntryState.isCorrecting(); 1511979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1512a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // Basically, we update the suggestion strip only when suggestion count > 1. However, 1513a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // there is an exception: We update the suggestion strip whenever typed word's length 1514a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // is 1, regardless of suggestion count. Actually, in most cases, suggestion count is 1 1515a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // when typed word's length is 1, but we do always need to clear the previous state when 1516a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // the user starts typing a word (i.e. typed word's length == 1). 1517a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa if (typedWord.length() == 1 || builder.size() > 1 1518a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa || mCandidateView.isShowingAddToDictionaryHint()) { 15199fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable); 15209fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else { 15219fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); 15229fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (previousSuggestions == mSuggestPuncList) 15239fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return; 15249fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); 15259fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } 15267e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), typedWord); 1527979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 15284a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani 15297e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { 15307e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(suggestedWords); 15317e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (suggestedWords.size() > 0) { 15329ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka if (suggestedWords.hasAutoCorrectionWord()) { 15337e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mBestWord = suggestedWords.getWord(1); 1534923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1535923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = typedWord; 1536923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1537923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1538923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 1539923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1540ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1541923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1542923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1543979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean pickDefaultSuggestion() { 1544923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Complete any pending candidate query first 1545d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka if (mHandler.hasPendingUpdateSuggestions()) { 1546d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 1547923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 1548923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15496780b898ec2647a21319601a03ae1c393c0e1b29Amith Yamasani if (mBestWord != null && mBestWord.length() > 0) { 1550923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord); 1551923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = true; 155255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(mBestWord); 15539468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 1554979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); 1555979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return true; 1556979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1557923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1558979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 1559923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1560923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1561923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void pickSuggestionManually(int index, CharSequence suggestion) { 15627e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords suggestions = mCandidateView.getSuggestions(); 1563409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators); 15644f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1565979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final boolean correcting = TextEntryState.isCorrecting(); 15669a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa InputConnection ic = getCurrentInputConnection(); 15679a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15689a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.beginBatchEdit(); 15699a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 15701b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null 15711b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka && index >= 0 && index < mApplicationSpecifiedCompletions.length) { 15721b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka CompletionInfo ci = mApplicationSpecifiedCompletions[index]; 1573923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1574923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitCompletion(ci); 1575923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1576923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1577923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCandidateView != null) { 1578923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.clear(); 1579923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1580b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 15819a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15829a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 15839a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1584923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1585923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15866a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 15876a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani // If this is a punctuation, apply it through the normal key press 1588979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) 1589979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || isSuggestedPunctuation(suggestion.charAt(0)))) { 1590979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Word separators are suggested before the user inputs something. 1591979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // So, LatinImeLogger logs "" as a user's input. 1592979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion( 15937e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka "", suggestion.toString(), index, suggestions.mWords); 159455b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa final char primaryCode = suggestion.charAt(0); 1595a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka onCodeInput(primaryCode, new int[] { primaryCode }, 1596a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE, 1597a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE); 15989a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15999a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16009a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 16016a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani return; 16026a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 16039a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAccepted = true; 160455b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(suggestion); 16059468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 16060c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani if (index == 0) { 1607979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); 1608979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1609979f8690967ff5409fe18f5085858ccdb8e0ccf1satok addToBigramDictionary(suggestion, 1); 16100c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani } 1611979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(), 16127e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka index, suggestions.mWords); 1613923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); 1614923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Follow it with a space 1615979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mAutoSpace && !correcting) { 1616923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendSpace(); 16179a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1618923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1619979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1620b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani final boolean showingAddToDictionaryHint = index == 0 && mCorrectionMode > 0 1621b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani && !mSuggest.isValidWord(suggestion) 1622b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani && !mSuggest.isValidWord(suggestion.toString().toLowerCase()); 1623b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1624979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!correcting) { 1625b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Fool the state watcher so that a subsequent backspace will not do a revert, unless 1626b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // we just did a correction, in which case we need to stay in 1627b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // TextEntryState.State.PICKED_SUGGESTION state. 1628571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true); 1629ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1630b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else if (!showingAddToDictionaryHint) { 1631364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // If we're not showing the "Touch again to save", then show corrections again. 1632979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // In case the cursor position doesn't change, make sure we show the suggestions again. 1633b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1634d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 1635979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1636b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (showingAddToDictionaryHint) { 163766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mCandidateView.showAddToDictionaryHint(suggestion); 163866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 16399a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16409a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16419a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1642923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1643a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1644979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1645979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Commits the chosen word to the text field and saves it for later 1646979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * retrieval. 1647979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param suggestion the suggestion picked by the user to be committed to 1648979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * the text field 1649979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 165055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka private void pickSuggestion(CharSequence suggestion) { 1651b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1652b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!switcher.isKeyboardAvailable()) 16531679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return; 1654923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1655923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1656409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators); 1657979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.commitText(suggestion, 1); 1658923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1659979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(suggestion); 16609fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1661923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1662b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.setPreferredLetters(null); 1663923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1664923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1665b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani /** 1666b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * Tries to apply any typed alternatives for the word if we have any cached alternatives, 1667b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * otherwise tries to find new corrections and completions for the word. 1668b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @param touching The word that the cursor is touching, with position information 1669b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @return true if an alternative was found, false otherwise. 1670b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani */ 1671e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) { 1672b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // If we didn't find a match, search for result in typed word history 1673b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordComposer foundWord = null; 1674b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordAlternatives alternatives = null; 1675b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani for (WordAlternatives entry : mWordHistory) { 1676e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) { 1677b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (entry instanceof TypedWordAlternatives) { 1678b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani foundWord = ((TypedWordAlternatives) entry).word; 1679b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1680b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani alternatives = entry; 1681b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani break; 1682b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1683b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 16841b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // If we didn't find a match, at least suggest corrections. 1685b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord == null 1686e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && (mSuggest.isValidWord(touching.mWord) 1687e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || mSuggest.isValidWord(touching.mWord.toString().toLowerCase()))) { 1688b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani foundWord = new WordComposer(); 1689e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka for (int i = 0; i < touching.mWord.length(); i++) { 1690e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.add(touching.mWord.charAt(i), new int[] { 1691e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka touching.mWord.charAt(i) 1692b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani }); 1693b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1694e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0))); 1695b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1696b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Found a match, show suggestions 1697b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null || alternatives != null) { 1698b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (alternatives == null) { 1699e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka alternatives = new TypedWordAlternatives(touching.mWord, foundWord); 1700b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1701b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani showCorrections(alternatives); 1702b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null) { 1703b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord = new WordComposer(foundWord); 1704b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1705b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord.reset(); 1706b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1707b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return true; 1708b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1709b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return false; 1710b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1711b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1712979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void setOldSuggestions() { 1713409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.setShowingVoiceSuggestions(false); 1714b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) { 1715b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return; 1716b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1717979f8690967ff5409fe18f5085858ccdb8e0ccf1satok InputConnection ic = getCurrentInputConnection(); 1718979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (ic == null) return; 17199fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1720b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Extract the selected or touching text 1721e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic, 1722b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mLastSelectionStart, mLastSelectionEnd, mWordSeparators); 1723979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1724e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (touching != null && touching.mWord.length() > 1) { 1725b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.beginBatchEdit(); 1726979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1727409220583333bdf06290dd9fd42f91b5c0d1b11asatok if (!mVoiceConnector.applyVoiceAlternatives(touching) 1728409220583333bdf06290dd9fd42f91b5c0d1b11asatok && !applyTypedAlternatives(touching)) { 1729b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani abortCorrection(true); 1730b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1731979f8690967ff5409fe18f5085858ccdb8e0ccf1satok TextEntryState.selectedForCorrection(); 1732e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka EditingUtils.underlineWord(ic, touching); 1733979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1734b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1735b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.endBatchEdit(); 1736979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1737979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(true); 1738ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); // Show the punctuation suggestions list 1739979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1740979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1741979f8690967ff5409fe18f5085858ccdb8e0ccf1satok abortCorrection(true); 1742979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1743979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1744979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1745ca26f20fa4903de46e374babbfba8c8a1a5cac93satok private void setPunctuationSuggestions() { 17467e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(mSuggestPuncList); 17479fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 17486a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 17496a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 1750979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void addToDictionaries(CharSequence suggestion, int frequencyDelta) { 1751979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, false); 1752979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1753979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1754979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void addToBigramDictionary(CharSequence suggestion, int frequencyDelta) { 1755979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, true); 1756979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1757979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1758979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1759979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Adds to the UserBigramDictionary and/or AutoDictionary 1760979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param addToBigramDictionary true if it should be added to bigram dictionary if possible 1761979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 1762979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta, 1763979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean addToBigramDictionary) { 1764979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion == null || suggestion.length() < 1) return; 17650c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be 17660c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // adding words in situations where the user or application really didn't 17670c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // want corrections enabled or learned. 1768979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!(mCorrectionMode == Suggest.CORRECTION_FULL 1769979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) { 1770979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1771979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1772e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion) 1773e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka || (!mSuggest.isValidWord(suggestion.toString()) 1774e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) { 1775e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); 1776e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 1777979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1778e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mUserBigramDictionary != null) { 1779e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1780e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mSentenceSeparators); 1781e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!TextUtils.isEmpty(prevWord)) { 1782e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); 1783979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 178432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 178532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 178632e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 1787923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCursorTouchingWord() { 1788923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1789923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return false; 1790923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toLeft = ic.getTextBeforeCursor(1, 0); 1791923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toRight = ic.getTextAfterCursor(1, 0); 1792923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!TextUtils.isEmpty(toLeft) 179355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toLeft.charAt(0)) 179455b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toLeft.charAt(0))) { 1795923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1796923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1797a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker if (!TextUtils.isEmpty(toRight) 179855b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toRight.charAt(0)) 179955b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toRight.charAt(0))) { 1800923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1801923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1802923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1803923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1804a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1805dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) { 1806dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); 1807dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani return TextUtils.equals(text, beforeText); 1808dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani } 1809dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 1810923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void revertLastWord(boolean deleteChar) { 1811923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 18129fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions && length > 0) { 1813923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1814c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = true; 1815504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); 1816923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (deleteChar) ic.deleteSurroundingText(1, 0); 1817923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int toDelete = mCommittedLength; 1818504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); 1819504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { 1820923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project toDelete--; 1821923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1822923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(toDelete, 0); 182330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Re-insert punctuation only when the deleted character was word separator and the 182430be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // composing text wasn't equal to the auto-corrected text. 182530be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka if (deleteChar 182630be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) 182730be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.equals(mComposing, toTheLeft)) { 1828504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.commitText(mComposing, 1); 1829504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.acceptedTyped(mComposing); 183030be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka ic.commitText(punctuation, 1); 183130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka TextEntryState.typedCharacter(punctuation.charAt(0), true); 183230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Clear composing text 183330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mComposing.setLength(0); 1834504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } else { 183530be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mHasValidSuggestions = true; 1836504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.setComposingText(mComposing, 1); 1837504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.backspace(); 1838504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1839d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1840923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1841923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 1842c1e2e827b5d1bba59eb99d322dc101657ec28768Ken Wakasa mJustReverted = false; 1843923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1844923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1845923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1846923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected String getWordSeparators() { 1847923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mWordSeparators; 1848923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1849a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1850923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean isWordSeparator(int code) { 1851923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project String separators = getWordSeparators(); 1852923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return separators.contains(String.valueOf((char)code)); 1853923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1854923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1855979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSentenceSeparator(int code) { 1856923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mSentenceSeparators.contains(String.valueOf((char)code)); 1857923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1858923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1859923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void sendSpace() { 1860571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka sendKeyChar((char)Keyboard.CODE_SPACE); 1861b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1862923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1863923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1864923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean preferCapitalization() { 18650b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return mWord.isFirstCharCapitalized(); 1866923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1867923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1868c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID 1869c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // according to new language or mode. 1870c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka public void onRefreshKeyboard() { 18714ab730dbd34fad323063f2ffd31ce33de746668dsatok toggleLanguage(true, true); 18724ab730dbd34fad323063f2ffd31ce33de746668dsatok } 18734ab730dbd34fad323063f2ffd31ce33de746668dsatok 18744ab730dbd34fad323063f2ffd31ce33de746668dsatok // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. 18753f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani private void toggleLanguage(boolean reset, boolean next) { 1876de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { 18774ab730dbd34fad323063f2ffd31ce33de746668dsatok mSubtypeSwitcher.toggleLanguage(reset, next); 18784ab730dbd34fad323063f2ffd31ce33de746668dsatok } 18794ab730dbd34fad323063f2ffd31ce33de746668dsatok // Reload keyboard because the current language has been changed. 1880b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 18818b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final EditorInfo attribute = getCurrentInputEditorInfo(); 1882c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int mode = initializeInputAttributesAndGetMode((attribute != null) 1883c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka ? attribute.inputType : 0); 1884d98c20b036ff02f99406dabb8cc4fdf4a51cd6c4Tadashi G. Takaoka final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; 1885409220583333bdf06290dd9fd42f91b5c0d1b11asatok switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(), 1886409220583333bdf06290dd9fd42f91b5c0d1b11asatok mVoiceConnector.isVoiceButtonOnPrimary()); 18870ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 1888b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 188936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 189036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 18915a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 189236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 189336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani String key) { 18940ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.onSharedPreferenceChanged(sharedPreferences, key); 18959502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) { 189636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mRefreshKeyboardRequired = true; 18979502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka } else if (Settings.PREF_RECORRECTION_ENABLED.equals(key)) { 18989502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mReCorrectionEnabled = sharedPreferences.getBoolean( 18999502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_RECORRECTION_ENABLED, 1900458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mResources.getBoolean(R.bool.default_recorrection_enabled)); 190136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 190236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 190336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 19045a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 19058aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onSwipeDown() { 1906363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka if (mConfigSwipeDownDismissKeyboardEnabled) 1907363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka handleClose(); 1908923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1909923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19105a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1911923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onPress(int primaryCode) { 1912cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) { 1913cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka vibrate(); 1914cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka playKeyClick(primaryCode); 1915cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 19161679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 19171679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1918571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1919b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onPressShift(); 1920e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 19216c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onPressSymbol(); 192240a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } else { 19236c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onOtherKeyPressed(); 1924681b102a492b7d5301c1ca87985b4c391eb5eb14Tadashi G. Takaoka } 1925923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1926923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19275a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1928923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onRelease(int primaryCode) { 19291679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 19303f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani // Reset any drag flags in the keyboard 19311679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka switcher.keyReleased(); 19321679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1933571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1934889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka switcher.onReleaseShift(); 1935e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 19366c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onReleaseSymbol(); 193740a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } 1938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1939a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1940a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1941923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // receive ringer mode changes to detect silent mode 1942923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private BroadcastReceiver mReceiver = new BroadcastReceiver() { 1943923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 1944923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onReceive(Context context, Intent intent) { 1945923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 1946923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1947923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 1948923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1949923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // update flags for silent mode 1950923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void updateRingerMode() { 1951923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 1952923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 1953923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1954923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager != null) { 1955923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); 1956923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1957923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1958923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1959923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void playKeyClick(int primaryCode) { 1960923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // if mAudioManager is null, we don't have the ringer state yet 1961923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // mAudioManager will be set by updateRingerMode 1962923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 1963979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mKeyboardSwitcher.getInputView() != null) { 1964923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 1965923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1966923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1967923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSoundOn && !mSilentMode) { 1968923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: Volume and enable should come from UI settings 1969923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: These should be triggered after auto-repeat logic 1970923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int sound = AudioManager.FX_KEYPRESS_STANDARD; 1971923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1972571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 1973923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_DELETE; 1974923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1975571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_ENTER: 1976923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_RETURN; 1977923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1978571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SPACE: 1979923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_SPACEBAR; 1980923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1981923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1982923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager.playSoundEffect(sound, FX_VOLUME); 1983923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1984923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1985923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1986409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void vibrate() { 1987923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mVibrateOn) { 1988923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1989923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 19901679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 19911679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) { 19921679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.performHapticFeedback( 1993979f8690967ff5409fe18f5085858ccdb8e0ccf1satok HapticFeedbackConstants.KEYBOARD_TAP, 199466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); 1995923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1997923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 199871c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public void promoteToUserDictionary(String word, int frequency) { 199934386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani if (mUserDictionary.isValidWord(word)) return; 200034386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mUserDictionary.addWord(word, frequency); 200134386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani } 200234386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 200371c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public WordComposer getCurrentWord() { 20046516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani return mWord; 20056516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani } 20066516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani 200771c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public boolean getPopupOn() { 2008979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mPopupOn; 2009979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2010979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2011e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private void updateCorrectionMode() { 2012e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; 2013e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) 2014e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani && !mInputTypeNoAutoCorrect && mHasDictionary; 201532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) 2016e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani ? Suggest.CORRECTION_FULL 201732e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); 2018979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) 2019979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; 2020e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani if (mSuggest != null) { 2021e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mSuggest.setCorrectionMode(mCorrectionMode); 2022e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2023e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2024e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani 20250ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void updateAutoTextEnabled() { 202632e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani if (mSuggest == null) return; 20270ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSuggest.setAutoTextEnabled(mQuickFixes 20284ab730dbd34fad323063f2ffd31ce33de746668dsatok && SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage()); 202932e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 203032e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 20317599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private void updateSuggestionVisibility(SharedPreferences prefs) { 2032458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 20337599cfea4a2d56f4779452ec8e8742f7b9629cc0satok final String suggestionVisiblityStr = prefs.getString( 20349502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_SHOW_SUGGESTIONS_SETTING, 2035458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa res.getString(R.string.prefs_suggestion_visibility_default_value)); 20367599cfea4a2d56f4779452ec8e8742f7b9629cc0satok for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { 2037458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa if (suggestionVisiblityStr.equals(res.getString(visibility))) { 20387599cfea4a2d56f4779452ec8e8742f7b9629cc0satok mSuggestionVisibility = visibility; 20397599cfea4a2d56f4779452ec8e8742f7b9629cc0satok break; 20407599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 20417599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 20427599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 20437599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 2044466741d8a78965b8509bf527344f289e50873092Mike LeBeau protected void launchSettings() { 20459502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(Settings.class); 2046466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 2047466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2048bf96661d33d0126adb60a48880ceba1ff055d4a4satok public void launchDebugSettings() { 20499502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(DebugSettings.class); 2050bf96661d33d0126adb60a48880ceba1ff055d4a4satok } 2051bf96661d33d0126adb60a48880ceba1ff055d4a4satok 2052507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka protected void launchSettings(Class<? extends PreferenceActivity> settingsClass) { 2053923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project handleClose(); 2054923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Intent intent = new Intent(); 2055466741d8a78965b8509bf527344f289e50873092Mike LeBeau intent.setClass(LatinIME.this, settingsClass); 2056923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2057923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project startActivity(intent); 2058923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2059923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2060507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private void loadSettings(EditorInfo attribute) { 2061923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Get the settings preferences 206227d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 20634174655e23734563775acb9e1e644b31b9e72fa5Ken Wakasa Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 20644174655e23734563775acb9e1e644b31b9e72fa5Ken Wakasa mVibrateOn = vibrator != null && vibrator.hasVibrator() 20659502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); 20669502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, false); 20679502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mPopupOn = prefs.getBoolean(Settings.PREF_POPUP_ON, 20689b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka mResources.getBoolean(R.bool.config_default_popup_preview)); 20699502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); 20709502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mQuickFixes = prefs.getBoolean(Settings.PREF_QUICK_FIXES, true); 2071a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 207227d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mAutoCorrectEnabled = isAutoCorrectEnabled(prefs); 207327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs); 20741b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 2075466741d8a78965b8509bf527344f289e50873092Mike LeBeau 207627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mVoiceConnector.loadSettings(attribute, prefs); 2077409220583333bdf06290dd9fd42f91b5c0d1b11asatok 2078e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 20790ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 208027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa updateSuggestionVisibility(prefs); 208127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.getInstance().loadSettings(); 208236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 208336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 2084b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda /** 20851b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold. 2086b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda */ 20871b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) { 2088b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // When mSuggest is not initialized, cannnot modify mSuggest's threshold. 2089b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (mSuggest == null) return; 20901b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When auto correction setting is turned off, the threshold is ignored. 2091b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (!isAutoCorrectEnabled(sp)) return; 2092b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 20931b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 20941b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 20959ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 20961b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String[] autoCorrectionThresholdValues = mResources.getStringArray( 20979ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.array.auto_correction_threshold_values); 20981b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned off. 20991b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka double autoCorrectionThreshold = Double.MAX_VALUE; 2100b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda try { 21011b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); 21021b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { 21031b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.parseDouble( 21041b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThresholdValues[arrayIndex]); 2105b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2106b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } catch (NumberFormatException e) { 21071b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // Whenever the threshold settings are correct, never come here. 21081b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.MAX_VALUE; 21091b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Log.w(TAG, "Cannot load auto correction threshold setting." 21101b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting 21111b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + ", autoCorrectionThresholdValues: " 21121b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + Arrays.toString(autoCorrectionThresholdValues)); 2113b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2114b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // TODO: This should be refactored : 21151b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // setAutoCorrectionThreshold should be called outside of this method. 21161b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold); 2117b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2118b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2119b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isAutoCorrectEnabled(SharedPreferences sp) { 21201b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 21211b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 21229ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 21231b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String autoCorrectionOff = mResources.getString( 21249ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.string.auto_correction_threshold_mode_index_off); 21251b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka return !currentAutoCorrectionSetting.equals(autoCorrectionOff); 2126b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2127b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2128b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isBigramSuggestionEnabled(SharedPreferences sp) { 2129b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // TODO: Define default value instead of 'true'. 21309502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, true); 2131b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2132b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 21336a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani private void initSuggestPuncList() { 21347e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (mSuggestPuncs != null || mSuggestPuncList != null) 21357e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return; 21367e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder(); 21377e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka String puncs = mResources.getString(R.string.suggested_punctuations); 21387e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (puncs != null) { 21397e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka for (int i = 0; i < puncs.length(); i++) { 21407e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.addWord(puncs.subSequence(i, i + 1)); 21416a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21426a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21437e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncList = builder.build(); 21447e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncs = puncs; 21456a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21466a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 2147979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSuggestedPunctuation(int code) { 2148979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mSuggestPuncs.contains(String.valueOf((char)code)); 2149979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2150979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2151923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void showOptionsMenu() { 2152923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project AlertDialog.Builder builder = new AlertDialog.Builder(this); 2153923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project builder.setCancelable(true); 2154923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project builder.setIcon(R.drawable.ic_dialog_keyboard); 2155923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project builder.setNegativeButton(android.R.string.cancel, null); 2156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence itemSettings = getString(R.string.english_ime_settings); 21579a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok CharSequence itemInputMethod = getString(R.string.selectInputMethod); 2158923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project builder.setItems(new CharSequence[] { 2159c1ff28462eee5880267fd2eae4da389b25f6f3daKen Wakasa itemInputMethod, itemSettings}, 2160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project new DialogInterface.OnClickListener() { 2161923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 21625a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2163923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onClick(DialogInterface di, int position) { 2164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project di.dismiss(); 2165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (position) { 2166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case POS_SETTINGS: 2167923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project launchSettings(); 2168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case POS_METHOD: 217079efbed76f638be298493107fa2d0cd1b5eb529esatok mImm.showInputMethodPicker(); 2171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }); 2175c1ff28462eee5880267fd2eae4da389b25f6f3daKen Wakasa builder.setTitle(mResources.getString(R.string.english_ime_input_options)); 2176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog = builder.create(); 2177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Window window = mOptionsDialog.getWindow(); 2178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project WindowManager.LayoutParams lp = window.getAttributes(); 2179979f8690967ff5409fe18f5085858ccdb8e0ccf1satok lp.token = mKeyboardSwitcher.getInputView().getWindowToken(); 2180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.setAttributes(lp); 2182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog.show(); 2184923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 21867e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 21877e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2188923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.dump(fd, fout, args); 2189a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2190923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 2191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println("LatinIME state :"); 2192923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode()); 2193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mComposing=" + mComposing.toString()); 21949fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn); 2195923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mCorrectionMode=" + mCorrectionMode); 21969fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mHasValidSuggestions=" + mHasValidSuggestions); 2197923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoCorrectOn=" + mAutoCorrectOn); 2198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoSpace=" + mAutoSpace); 21991b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); 2200923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" TextEntryState.state=" + TextEntryState.getState()); 2201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mSoundOn=" + mSoundOn); 2202923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mVibrateOn=" + mVibrateOn); 2203979f8690967ff5409fe18f5085858ccdb8e0ccf1satok p.println(" mPopupOn=" + mPopupOn); 2204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 22056e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani 2206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Characters per second measurement 2207a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2208923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastCpsTime; 2209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int CPS_BUFFER_SIZE = 16; 2210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; 2211923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mCpsIndex; 2212a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void measureCps() { 2214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long now = System.currentTimeMillis(); 2215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial 2216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIntervals[mCpsIndex] = now - mLastCpsTime; 2217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastCpsTime = now; 2218923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE; 2219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long total = 0; 2220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; 2221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); 2222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 222334386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 22240ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok @Override 22250ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) { 22264ab730dbd34fad323063f2ffd31ce33de746668dsatok SubtypeSwitcher.getInstance().updateSubtype(subtype); 22270ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 2228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 2229