| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.inputmethod.pinyin; |
| |
| import com.android.inputmethod.pinyin.SoftKeyboard.KeyRow; |
| |
| import android.content.res.Resources; |
| import android.view.inputmethod.EditorInfo; |
| |
| /** |
| * Switcher used to switching input mode between Chinese, English, symbol,etc. |
| */ |
| public class InputModeSwitcher { |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| private static final int USERDEF_KEYCODE_SHIFT_1 = -1; |
| |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| private static final int USERDEF_KEYCODE_LANG_2 = -2; |
| |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| private static final int USERDEF_KEYCODE_SYM_3 = -3; |
| |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| public static final int USERDEF_KEYCODE_PHONE_SYM_4 = -4; |
| |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| private static final int USERDEF_KEYCODE_MORE_SYM_5 = -5; |
| |
| /** |
| * User defined key code, used by soft keyboard. |
| */ |
| private static final int USERDEF_KEYCODE_SMILEY_6 = -6; |
| |
| |
| /** |
| * Bits used to indicate soft keyboard layout. If none bit is set, the |
| * current input mode does not require a soft keyboard. |
| **/ |
| private static final int MASK_SKB_LAYOUT = 0xf0000000; |
| |
| /** |
| * A kind of soft keyboard layout. An input mode should be anded with |
| * {@link #MASK_SKB_LAYOUT} to get its soft keyboard layout. |
| */ |
| private static final int MASK_SKB_LAYOUT_QWERTY = 0x10000000; |
| |
| /** |
| * A kind of soft keyboard layout. An input mode should be anded with |
| * {@link #MASK_SKB_LAYOUT} to get its soft keyboard layout. |
| */ |
| private static final int MASK_SKB_LAYOUT_SYMBOL1 = 0x20000000; |
| |
| /** |
| * A kind of soft keyboard layout. An input mode should be anded with |
| * {@link #MASK_SKB_LAYOUT} to get its soft keyboard layout. |
| */ |
| private static final int MASK_SKB_LAYOUT_SYMBOL2 = 0x30000000; |
| |
| /** |
| * A kind of soft keyboard layout. An input mode should be anded with |
| * {@link #MASK_SKB_LAYOUT} to get its soft keyboard layout. |
| */ |
| private static final int MASK_SKB_LAYOUT_SMILEY = 0x40000000; |
| |
| /** |
| * A kind of soft keyboard layout. An input mode should be anded with |
| * {@link #MASK_SKB_LAYOUT} to get its soft keyboard layout. |
| */ |
| private static final int MASK_SKB_LAYOUT_PHONE = 0x50000000; |
| |
| /** |
| * Used to indicate which language the current input mode is in. If the |
| * current input mode works with a none-QWERTY soft keyboard, these bits are |
| * also used to get language information. For example, a Chinese symbol soft |
| * keyboard and an English one are different in an icon which is used to |
| * tell user the language information. BTW, the smiley soft keyboard mode |
| * should be set with {@link #MASK_LANGUAGE_CN} because it can only be |
| * launched from Chinese QWERTY soft keyboard, and it has Chinese icon on |
| * soft keyboard. |
| */ |
| private static final int MASK_LANGUAGE = 0x0f000000; |
| |
| /** |
| * Used to indicate the current language. An input mode should be anded with |
| * {@link #MASK_LANGUAGE} to get this information. |
| */ |
| private static final int MASK_LANGUAGE_CN = 0x01000000; |
| |
| /** |
| * Used to indicate the current language. An input mode should be anded with |
| * {@link #MASK_LANGUAGE} to get this information. |
| */ |
| private static final int MASK_LANGUAGE_EN = 0x02000000; |
| |
| /** |
| * Used to indicate which case the current input mode is in. For example, |
| * English QWERTY has lowercase and uppercase. For the Chinese QWERTY, these |
| * bits are ignored. For phone keyboard layout, these bits can be |
| * {@link #MASK_CASE_UPPER} to request symbol page for phone soft keyboard. |
| */ |
| private static final int MASK_CASE = 0x00f00000; |
| |
| /** |
| * Used to indicate the current case information. An input mode should be |
| * anded with {@link #MASK_CASE} to get this information. |
| */ |
| private static final int MASK_CASE_LOWER = 0x00100000; |
| |
| /** |
| * Used to indicate the current case information. An input mode should be |
| * anded with {@link #MASK_CASE} to get this information. |
| */ |
| private static final int MASK_CASE_UPPER = 0x00200000; |
| |
| /** |
| * Mode for inputing Chinese with soft keyboard. |
| */ |
| public static final int MODE_SKB_CHINESE = (MASK_SKB_LAYOUT_QWERTY | MASK_LANGUAGE_CN); |
| |
| /** |
| * Mode for inputing basic symbols for Chinese mode with soft keyboard. |
| */ |
| public static final int MODE_SKB_SYMBOL1_CN = (MASK_SKB_LAYOUT_SYMBOL1 | MASK_LANGUAGE_CN); |
| |
| /** |
| * Mode for inputing more symbols for Chinese mode with soft keyboard. |
| */ |
| public static final int MODE_SKB_SYMBOL2_CN = (MASK_SKB_LAYOUT_SYMBOL2 | MASK_LANGUAGE_CN); |
| |
| /** |
| * Mode for inputing English lower characters with soft keyboard. |
| */ |
| public static final int MODE_SKB_ENGLISH_LOWER = (MASK_SKB_LAYOUT_QWERTY |
| | MASK_LANGUAGE_EN | MASK_CASE_LOWER); |
| |
| /** |
| * Mode for inputing English upper characters with soft keyboard. |
| */ |
| public static final int MODE_SKB_ENGLISH_UPPER = (MASK_SKB_LAYOUT_QWERTY |
| | MASK_LANGUAGE_EN | MASK_CASE_UPPER); |
| |
| /** |
| * Mode for inputing basic symbols for English mode with soft keyboard. |
| */ |
| public static final int MODE_SKB_SYMBOL1_EN = (MASK_SKB_LAYOUT_SYMBOL1 | MASK_LANGUAGE_EN); |
| |
| /** |
| * Mode for inputing more symbols for English mode with soft keyboard. |
| */ |
| public static final int MODE_SKB_SYMBOL2_EN = (MASK_SKB_LAYOUT_SYMBOL2 | MASK_LANGUAGE_EN); |
| |
| /** |
| * Mode for inputing smileys with soft keyboard. |
| */ |
| public static final int MODE_SKB_SMILEY = (MASK_SKB_LAYOUT_SMILEY | MASK_LANGUAGE_CN); |
| |
| /** |
| * Mode for inputing phone numbers. |
| */ |
| public static final int MODE_SKB_PHONE_NUM = (MASK_SKB_LAYOUT_PHONE); |
| |
| /** |
| * Mode for inputing phone numbers. |
| */ |
| public static final int MODE_SKB_PHONE_SYM = (MASK_SKB_LAYOUT_PHONE | MASK_CASE_UPPER); |
| |
| /** |
| * Mode for inputing Chinese with a hardware keyboard. |
| */ |
| public static final int MODE_HKB_CHINESE = (MASK_LANGUAGE_CN); |
| |
| /** |
| * Mode for inputing English with a hardware keyboard |
| */ |
| public static final int MODE_HKB_ENGLISH = (MASK_LANGUAGE_EN); |
| |
| /** |
| * Unset mode. |
| */ |
| public static final int MODE_UNSET = 0; |
| |
| /** |
| * Maximum toggle states for a soft keyboard. |
| */ |
| public static final int MAX_TOGGLE_STATES = 4; |
| |
| /** |
| * The input mode for the current edit box. |
| */ |
| private int mInputMode = MODE_UNSET; |
| |
| /** |
| * Used to remember previous input mode. When user enters an edit field, the |
| * previous input mode will be tried. If the previous mode can not be used |
| * for the current situation (For example, previous mode is a soft keyboard |
| * mode to input symbols, and we have a hardware keyboard for the current |
| * situation), {@link #mRecentLauageInputMode} will be tried. |
| **/ |
| private int mPreviousInputMode = MODE_SKB_CHINESE; |
| |
| /** |
| * Used to remember recent mode to input language. |
| */ |
| private int mRecentLauageInputMode = MODE_SKB_CHINESE; |
| |
| /** |
| * Editor information of the current edit box. |
| */ |
| private EditorInfo mEditorInfo; |
| |
| /** |
| * Used to indicate required toggling operations. |
| */ |
| private ToggleStates mToggleStates = new ToggleStates(); |
| |
| /** |
| * The current field is a short message field? |
| */ |
| private boolean mShortMessageField; |
| |
| /** |
| * Is return key in normal state? |
| */ |
| private boolean mEnterKeyNormal = true; |
| |
| /** |
| * Current icon. 0 for none icon. |
| */ |
| int mInputIcon = R.drawable.ime_pinyin; |
| |
| /** |
| * IME service. |
| */ |
| private PinyinIME mImeService; |
| |
| /** |
| * Key toggling state for Chinese mode. |
| */ |
| private int mToggleStateCn; |
| |
| /** |
| * Key toggling state for Chinese mode with candidates. |
| */ |
| private int mToggleStateCnCand; |
| |
| /** |
| * Key toggling state for English lowwercase mode. |
| */ |
| private int mToggleStateEnLower; |
| |
| /** |
| * Key toggling state for English upppercase mode. |
| */ |
| private int mToggleStateEnUpper; |
| |
| /** |
| * Key toggling state for English symbol mode for the first page. |
| */ |
| private int mToggleStateEnSym1; |
| |
| /** |
| * Key toggling state for English symbol mode for the second page. |
| */ |
| private int mToggleStateEnSym2; |
| |
| /** |
| * Key toggling state for smiley mode. |
| */ |
| private int mToggleStateSmiley; |
| |
| /** |
| * Key toggling state for phone symbol mode. |
| */ |
| private int mToggleStatePhoneSym; |
| |
| /** |
| * Key toggling state for GO action of ENTER key. |
| */ |
| private int mToggleStateGo; |
| |
| /** |
| * Key toggling state for SEARCH action of ENTER key. |
| */ |
| private int mToggleStateSearch; |
| |
| /** |
| * Key toggling state for SEND action of ENTER key. |
| */ |
| private int mToggleStateSend; |
| |
| /** |
| * Key toggling state for NEXT action of ENTER key. |
| */ |
| private int mToggleStateNext; |
| |
| /** |
| * Key toggling state for SEND action of ENTER key. |
| */ |
| private int mToggleStateDone; |
| |
| /** |
| * QWERTY row toggling state for Chinese input. |
| */ |
| private int mToggleRowCn; |
| |
| /** |
| * QWERTY row toggling state for English input. |
| */ |
| private int mToggleRowEn; |
| |
| /** |
| * QWERTY row toggling state for URI input. |
| */ |
| private int mToggleRowUri; |
| |
| /** |
| * QWERTY row toggling state for email address input. |
| */ |
| private int mToggleRowEmailAddress; |
| |
| class ToggleStates { |
| /** |
| * If it is true, this soft keyboard is a QWERTY one. |
| */ |
| boolean mQwerty; |
| |
| /** |
| * If {@link #mQwerty} is true, this variable is used to decide the |
| * letter case of the QWERTY keyboard. |
| */ |
| boolean mQwertyUpperCase; |
| |
| /** |
| * The id of enabled row in the soft keyboard. Refer to |
| * {@link com.android.inputmethod.pinyin.SoftKeyboard.KeyRow} for |
| * details. |
| */ |
| public int mRowIdToEnable; |
| |
| /** |
| * Used to store all other toggle states for the current input mode. |
| */ |
| public int mKeyStates[] = new int[MAX_TOGGLE_STATES]; |
| |
| /** |
| * Number of states to toggle. |
| */ |
| public int mKeyStatesNum; |
| } |
| |
| public InputModeSwitcher(PinyinIME imeService) { |
| mImeService = imeService; |
| Resources r = mImeService.getResources(); |
| mToggleStateCn = Integer.parseInt(r.getString(R.string.toggle_cn)); |
| mToggleStateCnCand = Integer.parseInt(r |
| .getString(R.string.toggle_cn_cand)); |
| mToggleStateEnLower = Integer.parseInt(r |
| .getString(R.string.toggle_en_lower)); |
| mToggleStateEnUpper = Integer.parseInt(r |
| .getString(R.string.toggle_en_upper)); |
| mToggleStateEnSym1 = Integer.parseInt(r |
| .getString(R.string.toggle_en_sym1)); |
| mToggleStateEnSym2 = Integer.parseInt(r |
| .getString(R.string.toggle_en_sym2)); |
| mToggleStateSmiley = Integer.parseInt(r |
| .getString(R.string.toggle_smiley)); |
| mToggleStatePhoneSym = Integer.parseInt(r |
| .getString(R.string.toggle_phone_sym)); |
| |
| mToggleStateGo = Integer |
| .parseInt(r.getString(R.string.toggle_enter_go)); |
| mToggleStateSearch = Integer.parseInt(r |
| .getString(R.string.toggle_enter_search)); |
| mToggleStateSend = Integer.parseInt(r |
| .getString(R.string.toggle_enter_send)); |
| mToggleStateNext = Integer.parseInt(r |
| .getString(R.string.toggle_enter_next)); |
| mToggleStateDone = Integer.parseInt(r |
| .getString(R.string.toggle_enter_done)); |
| |
| mToggleRowCn = Integer.parseInt(r.getString(R.string.toggle_row_cn)); |
| mToggleRowEn = Integer.parseInt(r.getString(R.string.toggle_row_en)); |
| mToggleRowUri = Integer.parseInt(r.getString(R.string.toggle_row_uri)); |
| mToggleRowEmailAddress = Integer.parseInt(r |
| .getString(R.string.toggle_row_emailaddress)); |
| } |
| |
| public int getInputMode() { |
| return mInputMode; |
| } |
| |
| public ToggleStates getToggleStates() { |
| return mToggleStates; |
| } |
| |
| public int getSkbLayout() { |
| int layout = (mInputMode & MASK_SKB_LAYOUT); |
| |
| switch (layout) { |
| case MASK_SKB_LAYOUT_QWERTY: |
| return R.xml.skb_qwerty; |
| case MASK_SKB_LAYOUT_SYMBOL1: |
| return R.xml.skb_sym1; |
| case MASK_SKB_LAYOUT_SYMBOL2: |
| return R.xml.skb_sym2; |
| case MASK_SKB_LAYOUT_SMILEY: |
| return R.xml.skb_smiley; |
| case MASK_SKB_LAYOUT_PHONE: |
| return R.xml.skb_phone; |
| } |
| return 0; |
| } |
| |
| // Return the icon to update. |
| public int switchLanguageWithHkb() { |
| int newInputMode = MODE_HKB_CHINESE; |
| mInputIcon = R.drawable.ime_pinyin; |
| |
| if (MODE_HKB_CHINESE == mInputMode) { |
| newInputMode = MODE_HKB_ENGLISH; |
| mInputIcon = R.drawable.ime_en; |
| } |
| |
| saveInputMode(newInputMode); |
| return mInputIcon; |
| } |
| |
| // Return the icon to update. |
| public int switchModeForUserKey(int userKey) { |
| int newInputMode = MODE_UNSET; |
| |
| if (USERDEF_KEYCODE_LANG_2 == userKey) { |
| if (MODE_SKB_CHINESE == mInputMode) { |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } else if (MODE_SKB_ENGLISH_LOWER == mInputMode |
| || MODE_SKB_ENGLISH_UPPER == mInputMode) { |
| newInputMode = MODE_SKB_CHINESE; |
| } else if (MODE_SKB_SYMBOL1_CN == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL1_EN; |
| } else if (MODE_SKB_SYMBOL1_EN == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL1_CN; |
| } else if (MODE_SKB_SYMBOL2_CN == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL2_EN; |
| } else if (MODE_SKB_SYMBOL2_EN == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL2_CN; |
| } else if (MODE_SKB_SMILEY == mInputMode) { |
| newInputMode = MODE_SKB_CHINESE; |
| } |
| } else if (USERDEF_KEYCODE_SYM_3 == userKey) { |
| if (MODE_SKB_CHINESE == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL1_CN; |
| } else if (MODE_SKB_ENGLISH_UPPER == mInputMode |
| || MODE_SKB_ENGLISH_LOWER == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL1_EN; |
| } else if (MODE_SKB_SYMBOL1_EN == mInputMode |
| || MODE_SKB_SYMBOL2_EN == mInputMode) { |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } else if (MODE_SKB_SYMBOL1_CN == mInputMode |
| || MODE_SKB_SYMBOL2_CN == mInputMode) { |
| newInputMode = MODE_SKB_CHINESE; |
| } else if (MODE_SKB_SMILEY == mInputMode) { |
| newInputMode = MODE_SKB_SYMBOL1_CN; |
| } |
| } else if (USERDEF_KEYCODE_SHIFT_1 == userKey) { |
| if (MODE_SKB_ENGLISH_LOWER == mInputMode) { |
| newInputMode = MODE_SKB_ENGLISH_UPPER; |
| } else if (MODE_SKB_ENGLISH_UPPER == mInputMode) { |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } |
| } else if (USERDEF_KEYCODE_MORE_SYM_5 == userKey) { |
| int sym = (MASK_SKB_LAYOUT & mInputMode); |
| if (MASK_SKB_LAYOUT_SYMBOL1 == sym) { |
| sym = MASK_SKB_LAYOUT_SYMBOL2; |
| } else { |
| sym = MASK_SKB_LAYOUT_SYMBOL1; |
| } |
| newInputMode = ((mInputMode & (~MASK_SKB_LAYOUT)) | sym); |
| } else if (USERDEF_KEYCODE_SMILEY_6 == userKey) { |
| if (MODE_SKB_CHINESE == mInputMode) { |
| newInputMode = MODE_SKB_SMILEY; |
| } else { |
| newInputMode = MODE_SKB_CHINESE; |
| } |
| } else if (USERDEF_KEYCODE_PHONE_SYM_4 == userKey) { |
| if (MODE_SKB_PHONE_NUM == mInputMode) { |
| newInputMode = MODE_SKB_PHONE_SYM; |
| } else { |
| newInputMode = MODE_SKB_PHONE_NUM; |
| } |
| } |
| |
| if (newInputMode == mInputMode || MODE_UNSET == newInputMode) { |
| return mInputIcon; |
| } |
| |
| saveInputMode(newInputMode); |
| prepareToggleStates(true); |
| return mInputIcon; |
| } |
| |
| // Return the icon to update. |
| public int requestInputWithHkb(EditorInfo editorInfo) { |
| mShortMessageField = false; |
| boolean english = false; |
| int newInputMode = MODE_HKB_CHINESE; |
| |
| switch (editorInfo.inputType & EditorInfo.TYPE_MASK_CLASS) { |
| case EditorInfo.TYPE_CLASS_NUMBER: |
| case EditorInfo.TYPE_CLASS_PHONE: |
| case EditorInfo.TYPE_CLASS_DATETIME: |
| english = true; |
| break; |
| case EditorInfo.TYPE_CLASS_TEXT: |
| int v = editorInfo.inputType & EditorInfo.TYPE_MASK_VARIATION; |
| if (v == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS |
| || v == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD |
| || v == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD |
| || v == EditorInfo.TYPE_TEXT_VARIATION_URI) { |
| english = true; |
| } else if (v == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { |
| mShortMessageField = true; |
| } |
| break; |
| default: |
| } |
| |
| if (english) { |
| // If the application request English mode, we switch to it. |
| newInputMode = MODE_HKB_ENGLISH; |
| } else { |
| // If the application do not request English mode, we will |
| // try to keep the previous mode to input language text. |
| // Because there is not soft keyboard, we need discard all |
| // soft keyboard related information from the previous language |
| // mode. |
| if ((mRecentLauageInputMode & MASK_LANGUAGE) == MASK_LANGUAGE_CN) { |
| newInputMode = MODE_HKB_CHINESE; |
| } else { |
| newInputMode = MODE_HKB_ENGLISH; |
| } |
| } |
| mEditorInfo = editorInfo; |
| saveInputMode(newInputMode); |
| prepareToggleStates(false); |
| return mInputIcon; |
| } |
| |
| // Return the icon to update. |
| public int requestInputWithSkb(EditorInfo editorInfo) { |
| mShortMessageField = false; |
| |
| int newInputMode = MODE_SKB_CHINESE; |
| |
| switch (editorInfo.inputType & EditorInfo.TYPE_MASK_CLASS) { |
| case EditorInfo.TYPE_CLASS_NUMBER: |
| case EditorInfo.TYPE_CLASS_DATETIME: |
| newInputMode = MODE_SKB_SYMBOL1_EN; |
| break; |
| case EditorInfo.TYPE_CLASS_PHONE: |
| newInputMode = MODE_SKB_PHONE_NUM; |
| break; |
| case EditorInfo.TYPE_CLASS_TEXT: |
| int v = editorInfo.inputType & EditorInfo.TYPE_MASK_VARIATION; |
| if (v == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS |
| || v == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD |
| || v == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD |
| || v == EditorInfo.TYPE_TEXT_VARIATION_URI) { |
| // If the application request English mode, we switch to it. |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } else { |
| if (v == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { |
| mShortMessageField = true; |
| } |
| // If the application do not request English mode, we will |
| // try to keep the previous mode. |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| newInputMode = mInputMode; |
| if (0 == skbLayout) { |
| if ((mInputMode & MASK_LANGUAGE) == MASK_LANGUAGE_CN) { |
| newInputMode = MODE_SKB_CHINESE; |
| } else { |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } |
| } |
| } |
| break; |
| default: |
| // Try to keep the previous mode. |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| newInputMode = mInputMode; |
| if (0 == skbLayout) { |
| if ((mInputMode & MASK_LANGUAGE) == MASK_LANGUAGE_CN) { |
| newInputMode = MODE_SKB_CHINESE; |
| } else { |
| newInputMode = MODE_SKB_ENGLISH_LOWER; |
| } |
| } |
| break; |
| } |
| |
| mEditorInfo = editorInfo; |
| saveInputMode(newInputMode); |
| prepareToggleStates(true); |
| return mInputIcon; |
| } |
| |
| // Return the icon to update. |
| public int requestBackToPreviousSkb() { |
| int layout = (mInputMode & MASK_SKB_LAYOUT); |
| int lastLayout = (mPreviousInputMode & MASK_SKB_LAYOUT); |
| if (0 != layout && 0 != lastLayout) { |
| mInputMode = mPreviousInputMode; |
| saveInputMode(mInputMode); |
| prepareToggleStates(true); |
| return mInputIcon; |
| } |
| return 0; |
| } |
| |
| public int getTooggleStateForCnCand() { |
| return mToggleStateCnCand; |
| } |
| |
| public boolean isEnglishWithHkb() { |
| return MODE_HKB_ENGLISH == mInputMode; |
| } |
| |
| public boolean isEnglishWithSkb() { |
| return MODE_SKB_ENGLISH_LOWER == mInputMode |
| || MODE_SKB_ENGLISH_UPPER == mInputMode; |
| } |
| |
| public boolean isEnglishUpperCaseWithSkb() { |
| return MODE_SKB_ENGLISH_UPPER == mInputMode; |
| } |
| |
| public boolean isChineseText() { |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| if (MASK_SKB_LAYOUT_QWERTY == skbLayout || 0 == skbLayout) { |
| int language = (mInputMode & MASK_LANGUAGE); |
| if (MASK_LANGUAGE_CN == language) return true; |
| } |
| return false; |
| } |
| |
| public boolean isChineseTextWithHkb() { |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| if (0 == skbLayout) { |
| int language = (mInputMode & MASK_LANGUAGE); |
| if (MASK_LANGUAGE_CN == language) return true; |
| } |
| return false; |
| } |
| |
| public boolean isChineseTextWithSkb() { |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| if (MASK_SKB_LAYOUT_QWERTY == skbLayout) { |
| int language = (mInputMode & MASK_LANGUAGE); |
| if (MASK_LANGUAGE_CN == language) return true; |
| } |
| return false; |
| } |
| |
| public boolean isSymbolWithSkb() { |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| if (MASK_SKB_LAYOUT_SYMBOL1 == skbLayout |
| || MASK_SKB_LAYOUT_SYMBOL2 == skbLayout) { |
| return true; |
| } |
| return false; |
| } |
| |
| public boolean isEnterNoramlState() { |
| return mEnterKeyNormal; |
| } |
| |
| public boolean tryHandleLongPressSwitch(int keyCode) { |
| if (USERDEF_KEYCODE_LANG_2 == keyCode |
| || USERDEF_KEYCODE_PHONE_SYM_4 == keyCode) { |
| mImeService.showOptionsMenu(); |
| return true; |
| } |
| return false; |
| } |
| |
| private void saveInputMode(int newInputMode) { |
| mPreviousInputMode = mInputMode; |
| mInputMode = newInputMode; |
| |
| int skbLayout = (mInputMode & MASK_SKB_LAYOUT); |
| if (MASK_SKB_LAYOUT_QWERTY == skbLayout || 0 == skbLayout) { |
| mRecentLauageInputMode = mInputMode; |
| } |
| |
| mInputIcon = R.drawable.ime_pinyin; |
| if (isEnglishWithHkb()) { |
| mInputIcon = R.drawable.ime_en; |
| } else if (isChineseTextWithHkb()) { |
| mInputIcon = R.drawable.ime_pinyin; |
| } |
| |
| if (!Environment.getInstance().hasHardKeyboard()) { |
| mInputIcon = 0; |
| } |
| } |
| |
| private void prepareToggleStates(boolean needSkb) { |
| mEnterKeyNormal = true; |
| if (!needSkb) return; |
| |
| mToggleStates.mQwerty = false; |
| mToggleStates.mKeyStatesNum = 0; |
| |
| int states[] = mToggleStates.mKeyStates; |
| int statesNum = 0; |
| // Toggle state for language. |
| int language = (mInputMode & MASK_LANGUAGE); |
| int layout = (mInputMode & MASK_SKB_LAYOUT); |
| int charcase = (mInputMode & MASK_CASE); |
| int variation = mEditorInfo.inputType & EditorInfo.TYPE_MASK_VARIATION; |
| |
| if (MASK_SKB_LAYOUT_PHONE != layout) { |
| if (MASK_LANGUAGE_CN == language) { |
| // Chinese and Chinese symbol are always the default states, |
| // do not add a toggling operation. |
| if (MASK_SKB_LAYOUT_QWERTY == layout) { |
| mToggleStates.mQwerty = true; |
| mToggleStates.mQwertyUpperCase = true; |
| if (mShortMessageField) { |
| states[statesNum] = mToggleStateSmiley; |
| statesNum++; |
| } |
| } |
| } else if (MASK_LANGUAGE_EN == language) { |
| if (MASK_SKB_LAYOUT_QWERTY == layout) { |
| mToggleStates.mQwerty = true; |
| mToggleStates.mQwertyUpperCase = false; |
| states[statesNum] = mToggleStateEnLower; |
| if (MASK_CASE_UPPER == charcase) { |
| mToggleStates.mQwertyUpperCase = true; |
| states[statesNum] = mToggleStateEnUpper; |
| } |
| statesNum++; |
| } else if (MASK_SKB_LAYOUT_SYMBOL1 == layout) { |
| states[statesNum] = mToggleStateEnSym1; |
| statesNum++; |
| } else if (MASK_SKB_LAYOUT_SYMBOL2 == layout) { |
| states[statesNum] = mToggleStateEnSym2; |
| statesNum++; |
| } |
| } |
| |
| // Toggle rows for QWERTY. |
| mToggleStates.mRowIdToEnable = KeyRow.DEFAULT_ROW_ID; |
| if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { |
| mToggleStates.mRowIdToEnable = mToggleRowEmailAddress; |
| } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { |
| mToggleStates.mRowIdToEnable = mToggleRowUri; |
| } else if (MASK_LANGUAGE_CN == language) { |
| mToggleStates.mRowIdToEnable = mToggleRowCn; |
| } else if (MASK_LANGUAGE_EN == language) { |
| mToggleStates.mRowIdToEnable = mToggleRowEn; |
| } |
| } else { |
| if (MASK_CASE_UPPER == charcase) { |
| states[statesNum] = mToggleStatePhoneSym; |
| statesNum++; |
| } |
| } |
| |
| // Toggle state for enter key. |
| int action = mEditorInfo.imeOptions |
| & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION); |
| |
| if (action == EditorInfo.IME_ACTION_GO) { |
| states[statesNum] = mToggleStateGo; |
| statesNum++; |
| mEnterKeyNormal = false; |
| } else if (action == EditorInfo.IME_ACTION_SEARCH) { |
| states[statesNum] = mToggleStateSearch; |
| statesNum++; |
| mEnterKeyNormal = false; |
| } else if (action == EditorInfo.IME_ACTION_SEND) { |
| states[statesNum] = mToggleStateSend; |
| statesNum++; |
| mEnterKeyNormal = false; |
| } else if (action == EditorInfo.IME_ACTION_NEXT) { |
| int f = mEditorInfo.inputType & EditorInfo.TYPE_MASK_FLAGS; |
| if (f != EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) { |
| states[statesNum] = mToggleStateNext; |
| statesNum++; |
| mEnterKeyNormal = false; |
| } |
| } else if (action == EditorInfo.IME_ACTION_DONE) { |
| states[statesNum] = mToggleStateDone; |
| statesNum++; |
| mEnterKeyNormal = false; |
| } |
| mToggleStates.mKeyStatesNum = statesNum; |
| } |
| } |