diff --git a/java/res/xml-sw600dp/kbd_phone_symbols.xml b/java/res/xml-sw600dp/kbd_phone_shift.xml similarity index 100% rename from java/res/xml-sw600dp/kbd_phone_symbols.xml rename to java/res/xml-sw600dp/kbd_phone_shift.xml diff --git a/java/res/xml-sw768dp/kbd_phone_symbols.xml b/java/res/xml-sw768dp/kbd_phone_shift.xml similarity index 100% rename from java/res/xml-sw768dp/kbd_phone_symbols.xml rename to java/res/xml-sw768dp/kbd_phone_shift.xml diff --git a/java/res/xml/kbd_numkey_styles.xml b/java/res/xml/kbd_numkey_styles.xml index a40acaf55..c6ba23d39 100644 --- a/java/res/xml/kbd_numkey_styles.xml +++ b/java/res/xml/kbd_numkey_styles.xml @@ -91,12 +91,12 @@ latin:parentStyle="numKeyStyle" /> > mKeyboardCache = new HashMap>(); - private EditorInfo mAttribute; - private boolean mIsSymbols; /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of * what user actually typed. */ private boolean mIsAutoCorrectionActive; - private boolean mVoiceKeyEnabled; - private boolean mVoiceButtonOnPrimary; // TODO: Encapsulate these state handling to separate class and combine with ShiftKeyState // and ModifierKeyState. @@ -94,8 +91,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha private static final int SWITCH_STATE_CHORDING_SYMBOL = 6; private int mSwitchState = SWITCH_STATE_ALPHA; - // Indicates whether or not we have the settings key in option of settings - private boolean mSettingsKeyEnabledInSettings; private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto; private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = R.string.settings_key_mode_always_show; @@ -151,42 +146,21 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha public void loadKeyboard(EditorInfo attribute, Settings.Values settings) { mSwitchState = SWITCH_STATE_ALPHA; try { - loadKeyboardInternal(attribute, settings.isVoiceButtonEnabled(attribute), - settings.isVoiceButtonOnPrimary(), false); + final boolean voiceKeyEnabled = settings.isVoiceKeyEnabled(attribute); + final boolean voiceKeyOnMain = settings.isVoiceKeyOnMain(); + mMainKeyboardId = getKeyboardId( + attribute, false, false, voiceKeyEnabled, voiceKeyOnMain); + mSymbolsKeyboardId = getKeyboardId( + attribute, true, false, voiceKeyEnabled, voiceKeyOnMain); + mSymbolsShiftedKeyboardId = getKeyboardId( + attribute, true, true, voiceKeyEnabled, voiceKeyOnMain); + setKeyboard(getKeyboard(mMainKeyboardId)); } catch (RuntimeException e) { - // Get KeyboardId to record which keyboard has been failed to load. - final KeyboardId id = getKeyboardId(attribute, false); - Log.w(TAG, "loading keyboard failed: " + id, e); - LatinImeLogger.logOnException(id.toString(), e); + Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e); + LatinImeLogger.logOnException(mMainKeyboardId.toString(), e); } } - private void loadKeyboardInternal(EditorInfo attribute, boolean voiceButtonEnabled, - boolean voiceButtonOnPrimary, boolean isSymbols) { - if (mKeyboardView == null) return; - - mAttribute = attribute; - mVoiceKeyEnabled = voiceButtonEnabled; - mVoiceButtonOnPrimary = voiceButtonOnPrimary; - mIsSymbols = isSymbols; - // Update the settings key state because number of enabled IMEs could have been changed - mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService); - final KeyboardId id = getKeyboardId(attribute, isSymbols); - - // Note: This comment is only applied for phone number keyboard layout. - // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch - // between "phone keyboard" and "phone symbols keyboard". But on xlarge device, - // "@integer/key_shift" key code is used for that purpose in order to properly display - // "more" and "locked more" key labels. To achieve these behavior, we should initialize - // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard" - // respectively here for xlarge device's layout switching. - mSymbolsId = makeSiblingKeyboardId(id, R.xml.kbd_symbols, R.xml.kbd_phone); - mSymbolsShiftedId = makeSiblingKeyboardId( - id, R.xml.kbd_symbols_shift, R.xml.kbd_phone_symbols); - - setKeyboard(getKeyboard(id)); - } - @SuppressWarnings("unused") public void onSizeChanged(int w, int h, int oldw, int oldh) { final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth(); @@ -255,45 +229,40 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha return keyboard; } - private boolean hasVoiceKey(boolean isSymbols) { - return mVoiceKeyEnabled && (isSymbols != mVoiceButtonOnPrimary); - } - - private boolean hasSettingsKey(EditorInfo attribute) { - return mSettingsKeyEnabledInSettings - && !Utils.inPrivateImeOptions(mInputMethodService.getPackageName(), + private static boolean hasSettingsKey(SharedPreferences prefs, Context context, + EditorInfo attribute) { + return getSettingsKeyMode(prefs, context) + && !Utils.inPrivateImeOptions(context.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute); } - private KeyboardId getKeyboardId(EditorInfo attribute, boolean isSymbols) { + private KeyboardId getKeyboardId(EditorInfo attribute, final boolean isSymbols, + final boolean isShift, final boolean voiceKeyEnabled, final boolean voiceKeyOnMain) { final int mode = Utils.getKeyboardMode(attribute); - final boolean hasVoiceKey = hasVoiceKey(isSymbols); + final boolean hasVoiceKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain); final int xmlId; final boolean enableShiftLock; - if (isSymbols) { - if (mode == KeyboardId.MODE_PHONE) { - xmlId = R.xml.kbd_phone_symbols; - } else if (mode == KeyboardId.MODE_NUMBER) { - // Note: MODE_NUMBER keyboard layout has no "switch alpha symbol" key. - xmlId = R.xml.kbd_number; - } else { - xmlId = R.xml.kbd_symbols; - } + switch (mode) { + case KeyboardId.MODE_PHONE: + xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone; + enableShiftLock = true; + break; + case KeyboardId.MODE_NUMBER: + xmlId = R.xml.kbd_number; enableShiftLock = false; - } else { - if (mode == KeyboardId.MODE_PHONE) { - xmlId = R.xml.kbd_phone; - enableShiftLock = false; - } else if (mode == KeyboardId.MODE_NUMBER) { - xmlId = R.xml.kbd_number; - enableShiftLock = false; + break; + default: + if (isSymbols) { + xmlId = isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols; } else { xmlId = R.xml.kbd_qwerty; - enableShiftLock = true; } + enableShiftLock = true; + break; } - final boolean hasSettingsKey = hasSettingsKey(attribute); + + final boolean hasSettingsKey = hasSettingsKey(mPrefs, mInputMethodService, attribute); final int f2KeyMode = getF2KeyMode(mPrefs, mInputMethodService, attribute); final boolean clobberSettingsKey = Utils.inPrivateImeOptions( mInputMethodService.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY, @@ -305,16 +274,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final Locale locale = mSubtypeSwitcher.getInputLocale(); return new KeyboardId( res.getResourceEntryName(xmlId), xmlId, locale, orientation, mWindowWidth, - mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled, + mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, voiceKeyEnabled, hasVoiceKey, enableShiftLock); } - private KeyboardId makeSiblingKeyboardId(KeyboardId base, int alphabet, int phone) { - final int xmlId = base.mMode == KeyboardId.MODE_PHONE ? phone : alphabet; - final String xmlName = mInputMethodService.getResources().getResourceEntryName(xmlId); - return base.cloneWithNewLayout(xmlName, xmlId); - } - public int getKeyboardMode() { return mCurrentId != null ? mCurrentId.mMode : KeyboardId.MODE_TEXT; } @@ -602,13 +565,15 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha if (isAlphabetMode()) return; final LatinKeyboard keyboard; - if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) { - keyboard = getKeyboard(mSymbolsShiftedId); - // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To - // enable the indicator, we need to call setShiftLocked(true). - keyboard.setShiftLocked(true); + if (mCurrentId.equals(mSymbolsKeyboardId) + || !mCurrentId.equals(mSymbolsShiftedKeyboardId)) { + keyboard = getKeyboard(mSymbolsShiftedKeyboardId); + // Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a. + // sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked() + // that takes care of the current keyboard having such ALT key or not. + keyboard.setShiftLocked(hasStickyShiftKey(keyboard)); } else { - keyboard = getKeyboard(mSymbolsId); + keyboard = getKeyboard(mSymbolsKeyboardId); // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the // indicator, we need to call setShiftLocked(false). keyboard.setShiftLocked(false); @@ -616,6 +581,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha setKeyboard(keyboard); } + private static boolean hasStickyShiftKey(Keyboard keyboard) { + for (final Key shiftKey : keyboard.getShiftKeys()) { + if (shiftKey.mSticky) + return true; + } + return false; + } + public boolean isInMomentarySwitchState() { return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL || mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE; @@ -630,10 +603,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } private void toggleKeyboardMode() { - loadKeyboardInternal(mAttribute, mVoiceKeyEnabled, mVoiceButtonOnPrimary, !mIsSymbols); - if (mIsSymbols) { + if (mCurrentId.equals(mMainKeyboardId)) { + setKeyboard(getKeyboard(mSymbolsKeyboardId)); mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; } else { + setKeyboard(getKeyboard(mMainKeyboardId)); mSwitchState = SWITCH_STATE_ALPHA; } } @@ -684,10 +658,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // {@link #SWITCH_STATE_MOMENTARY}. if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { // Detected only the mode change key has been pressed, and then released. - if (mIsSymbols) { - mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; - } else { + if (mCurrentId.equals(mMainKeyboardId)) { mSwitchState = SWITCH_STATE_ALPHA; + } else { + mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; } } else if (getPointerCount() == 1) { // Snap back to the previous keyboard mode if the user pressed the mode change key @@ -800,8 +774,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final int layoutId = getKeyboardThemeIndex(mInputMethodService, sharedPreferences); postSetInputView(createInputView(layoutId, false)); } else if (Settings.PREF_SETTINGS_KEY.equals(key)) { - mSettingsKeyEnabledInSettings = getSettingsKeyMode(sharedPreferences, - mInputMethodService); postSetInputView(createInputView(mThemeIndex, true)); } } diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index dbab227db..e44ae29d9 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -118,8 +118,8 @@ public class Settings extends InputMethodSettingsActivity public final boolean mBigramPredictionEnabled; public final boolean mUseContactsDict; - private final boolean mVoiceButtonEnabled; - private final boolean mVoiceButtonOnPrimary; + private final boolean mVoiceKeyEnabled; + private final boolean mVoiceKeyOnMain; public Values(final SharedPreferences prefs, final Context context, final String localeStr) { @@ -183,8 +183,8 @@ public class Settings extends InputMethodSettingsActivity final String voiceModeMain = res.getString(R.string.voice_mode_main); final String voiceModeOff = res.getString(R.string.voice_mode_off); final String voiceMode = prefs.getString(PREF_VOICE_SETTINGS_KEY, voiceModeMain); - mVoiceButtonEnabled = voiceMode != null && !voiceMode.equals(voiceModeOff); - mVoiceButtonOnPrimary = voiceMode != null && voiceMode.equals(voiceModeMain); + mVoiceKeyEnabled = voiceMode != null && !voiceMode.equals(voiceModeOff); + mVoiceKeyOnMain = voiceMode != null && voiceMode.equals(voiceModeMain); Utils.setSystemLocale(res, savedLocale); } @@ -284,15 +284,15 @@ public class Settings extends InputMethodSettingsActivity return builder.setIsPunctuationSuggestions().build(); } - public boolean isVoiceButtonEnabled(EditorInfo attribute) { + public boolean isVoiceKeyEnabled(EditorInfo attribute) { final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled(); final int inputType = (attribute != null) ? attribute.inputType : 0; - return shortcutImeEnabled && mVoiceButtonEnabled + return shortcutImeEnabled && mVoiceKeyEnabled && !InputTypeCompatUtils.isPasswordInputType(inputType); } - public boolean isVoiceButtonOnPrimary() { - return mVoiceButtonOnPrimary; + public boolean isVoiceKeyOnMain() { + return mVoiceKeyOnMain; } }