diff --git a/res/values/strings.xml b/res/values/strings.xml index 90cd6d429..85de32207 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -252,6 +252,12 @@ Voice input + + Mic on primary + + + Show the microphone on the primary keyboard + Auto submit after voice diff --git a/res/xml-de/kbd_qwerty.xml b/res/xml-de/kbd_qwerty.xml index 9e2f5841d..4e57c6067 100755 --- a/res/xml-de/kbd_qwerty.xml +++ b/res/xml-de/kbd_qwerty.xml @@ -100,7 +100,7 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="_" android:keyWidth="20%p" android:keyEdgeFlags="left"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml-fr/kbd_qwerty.xml b/res/xml-fr/kbd_qwerty.xml index 7abe18eb2..1b20c0438 100644 --- a/res/xml-fr/kbd_qwerty.xml +++ b/res/xml-fr/kbd_qwerty.xml @@ -114,24 +114,6 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml-ru/kbd_qwerty.xml b/res/xml-ru/kbd_qwerty.xml index 8a3a59229..45d355b0f 100755 --- a/res/xml-ru/kbd_qwerty.xml +++ b/res/xml-ru/kbd_qwerty.xml @@ -96,24 +96,6 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/kbd_qwerty.xml b/res/xml/kbd_qwerty.xml index e0fe5cdc3..4aa476136 100755 --- a/res/xml/kbd_qwerty.xml +++ b/res/xml/kbd_qwerty.xml @@ -111,7 +111,8 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="_" android:keyWidth="20%p" android:keyEdgeFlags="left"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + mKeyboards; - /** - * Maps keyboard mode to the equivalent mode with voice. - */ - private Map mModeToVoice; - private int mMode; /** One of the MODE_XXX values */ private int mImeOptions; private int mTextMode = MODE_TEXT_QWERTY; private boolean mIsSymbols; private boolean mHasVoice; + private boolean mVoiceOnPrimary; private boolean mPreferSymbols; private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; @@ -87,14 +83,8 @@ public class KeyboardSwitcher { KeyboardSwitcher(Context context, InputMethodService ims) { mContext = context; mKeyboards = new HashMap(); - mSymbolsId = new KeyboardId(R.xml.kbd_symbols); - mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift); - mModeToVoice = new HashMap(); - mModeToVoice.put(R.id.mode_normal, R.id.mode_normal_voice); - mModeToVoice.put(R.id.mode_url, R.id.mode_url_voice); - mModeToVoice.put(R.id.mode_email, R.id.mode_email_voice); - mModeToVoice.put(R.id.mode_im, R.id.mode_im_voice); - mModeToVoice.put(R.id.mode_webentry, R.id.mode_webentry_voice); + mSymbolsId = new KeyboardId(R.xml.kbd_symbols, false); + mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift, false); mInputMethodService = ims; } @@ -122,8 +112,9 @@ public class KeyboardSwitcher { if (displayWidth == mLastDisplayWidth) return; mLastDisplayWidth = displayWidth; if (!forceCreate) mKeyboards.clear(); - mSymbolsId = new KeyboardId(R.xml.kbd_symbols); - mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift); + mSymbolsId = new KeyboardId(R.xml.kbd_symbols, mHasVoice && !mVoiceOnPrimary); + mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift, + mHasVoice && !mVoiceOnPrimary); } /** @@ -134,15 +125,17 @@ public class KeyboardSwitcher { public int mXml; public int mKeyboardMode; /** A KEYBOARDMODE_XXX value */ public boolean mEnableShiftLock; + public boolean mHasVoice; - public KeyboardId(int xml, int mode, boolean enableShiftLock) { + public KeyboardId(int xml, int mode, boolean enableShiftLock, boolean hasVoice) { this.mXml = xml; this.mKeyboardMode = mode; this.mEnableShiftLock = enableShiftLock; + this.mHasVoice = hasVoice; } - public KeyboardId(int xml) { - this(xml, 0, false); + public KeyboardId(int xml, boolean hasVoice) { + this(xml, 0, false, hasVoice); } public boolean equals(Object other) { @@ -152,16 +145,29 @@ public class KeyboardSwitcher { public boolean equals(KeyboardId other) { return other.mXml == this.mXml && other.mKeyboardMode == this.mKeyboardMode - && other.mEnableShiftLock == this.mEnableShiftLock; + && other.mEnableShiftLock == this.mEnableShiftLock + && other.mHasVoice == this.mHasVoice; } public int hashCode() { - return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1); + return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1) + * (mHasVoice ? 4 : 8); } } - void setVoiceMode(boolean enableVoice) { - setKeyboardMode(mMode, mImeOptions, enableVoice, mIsSymbols); + void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) { + if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) { + System.err.println("Clearing keyboards"); + mKeyboards.clear(); + } + mHasVoice = enableVoice; + mVoiceOnPrimary = voiceOnPrimary; + setKeyboardMode(mMode, mImeOptions, mHasVoice, + mIsSymbols); + } + + boolean hasVoiceButton(boolean isSymbols) { + return mHasVoice && (isSymbols != mVoiceOnPrimary); } void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) { @@ -181,9 +187,6 @@ public class KeyboardSwitcher { mInputView.setPreviewEnabled(true); KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); - if (enableVoice && mModeToVoice.containsKey(id.mKeyboardMode)) { - id.mKeyboardMode = mModeToVoice.get(id.mKeyboardMode); - } LatinKeyboard keyboard = getKeyboard(id); if (mode == MODE_PHONE) { @@ -211,17 +214,12 @@ public class KeyboardSwitcher { conf.locale = mInputLocale; orig.updateConfiguration(conf, null); LatinKeyboard keyboard = new LatinKeyboard( - mContext, id.mXml, id.mKeyboardMode); + mContext, id.mXml, id.mKeyboardMode, id.mHasVoice); if (id.mKeyboardMode == KEYBOARDMODE_NORMAL || id.mKeyboardMode == KEYBOARDMODE_URL || id.mKeyboardMode == KEYBOARDMODE_IM || id.mKeyboardMode == KEYBOARDMODE_EMAIL || id.mKeyboardMode == KEYBOARDMODE_WEB - || id.mKeyboardMode == R.id.mode_normal_voice - || id.mKeyboardMode == R.id.mode_url_voice - || id.mKeyboardMode == R.id.mode_im_voice - || id.mKeyboardMode == R.id.mode_email_voice - || id.mKeyboardMode == R.id.mode_webentry_voice ) { keyboard.setExtension(R.xml.kbd_extension); } @@ -238,31 +236,32 @@ public class KeyboardSwitcher { } private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) { + boolean hasVoice = hasVoiceButton(isSymbols); if (isSymbols) { return (mode == MODE_PHONE) - ? new KeyboardId(R.xml.kbd_phone_symbols) : new KeyboardId(R.xml.kbd_symbols); + ? new KeyboardId(R.xml.kbd_phone_symbols, hasVoice) + : new KeyboardId(R.xml.kbd_symbols, hasVoice); } - switch (mode) { case MODE_TEXT: if (mTextMode == MODE_TEXT_QWERTY) { - return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_NORMAL, true); + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_NORMAL, true, hasVoice); } else if (mTextMode == MODE_TEXT_ALPHA) { - return new KeyboardId(R.xml.kbd_alpha, KEYBOARDMODE_NORMAL, true); + return new KeyboardId(R.xml.kbd_alpha, KEYBOARDMODE_NORMAL, true, hasVoice); } break; case MODE_SYMBOLS: - return new KeyboardId(R.xml.kbd_symbols); + return new KeyboardId(R.xml.kbd_symbols, hasVoice); case MODE_PHONE: - return new KeyboardId(R.xml.kbd_phone); + return new KeyboardId(R.xml.kbd_phone, hasVoice); case MODE_URL: - return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_URL, true); + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_URL, true, hasVoice); case MODE_EMAIL: - return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_EMAIL, true); + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_EMAIL, true, hasVoice); case MODE_IM: - return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_IM, true); + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_IM, true, hasVoice); case MODE_WEB: - return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_WEB, true); + return new KeyboardId(R.xml.kbd_qwerty, KEYBOARDMODE_WEB, true, hasVoice); } return null; } @@ -295,7 +294,7 @@ public class KeyboardSwitcher { boolean isAlphabetMode() { int currentMode = mCurrentId.mKeyboardMode; for (Integer mode : ALPHABET_MODES) { - if (currentMode == mode || currentMode == mModeToVoice.get(mode)) { + if (currentMode == mode) { return true; } } diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java index 7eecfb9b9..5faac5fae 100644 --- a/src/com/android/inputmethod/latin/LatinIME.java +++ b/src/com/android/inputmethod/latin/LatinIME.java @@ -92,7 +92,8 @@ public class LatinIME extends InputMethodService private static final String PREF_AUTO_COMPLETE = "auto_complete"; private static final String PREF_ENABLE_VOICE = "enable_voice_input"; private static final String PREF_VOICE_SERVER_URL = "voice_server_url"; - + private static final String PREF_VOICE_MAIN = "voice_on_main"; + // Whether or not the user has used voice input before (and thus, whether to show the // first-run warning dialog or not). private static final String PREF_HAS_USED_VOICE_INPUT = "has_used_voice_input"; @@ -211,6 +212,7 @@ public class LatinIME extends InputMethodService private boolean mIsShowingHint; private int mCorrectionMode; private boolean mEnableVoice = true; + private boolean mVoiceOnPrimary; private int mOrientation; // Indicates whether the suggestion strip is to be on in landscape @@ -445,6 +447,7 @@ public class LatinIME extends InputMethodService } mEnableVoiceButton = shouldShowVoiceButton(makeFieldContext(), attribute); + final boolean enableVoiceButton = mEnableVoiceButton && mEnableVoice; mAfterVoiceInput = false; mImmediatelyAfterVoiceInput = false; @@ -463,15 +466,15 @@ public class LatinIME extends InputMethodService case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); break; case EditorInfo.TYPE_CLASS_PHONE: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); break; case EditorInfo.TYPE_CLASS_TEXT: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); //startPrediction(); mPredictionOn = true; // Make sure that passwords are not displayed in candidate view @@ -491,19 +494,19 @@ public class LatinIME extends InputMethodService if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { mPredictionOn = false; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_WEB, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); // If it's a browser edit field and auto correct is not ON explicitly, then // disable auto correction, but keep suggestions on. if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { @@ -529,7 +532,7 @@ public class LatinIME extends InputMethodService break; default: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions, mEnableVoiceButton); + attribute.imeOptions, enableVoiceButton); updateShiftKeyState(attribute); } mInputView.closing(); @@ -790,6 +793,7 @@ public class LatinIME extends InputMethodService } mKeyboardSwitcher.setInputLocale(new Locale(mInputLanguage), getSelectedInputLanguages() != null); + mKeyboardSwitcher.setVoiceMode(mEnableVoice, mVoiceOnPrimary); mKeyboardSwitcher.makeKeyboards(true); } @@ -1504,7 +1508,8 @@ public class LatinIME extends InputMethodService int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode(); reloadKeyboards(); mKeyboardSwitcher.makeKeyboards(true); - mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0, mEnableVoiceButton); + mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0, + mEnableVoiceButton && mEnableVoice); initSuggest(mInputLanguage); persistInputLanguage(mInputLanguage); updateShiftKeyState(getCurrentInputEditorInfo()); @@ -1555,7 +1560,6 @@ public class LatinIME extends InputMethodService private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) { return ENABLE_VOICE_BUTTON - && mEnableVoice && fieldCanDoVoice(fieldContext) && !(attribute != null && attribute.privateImeOptions != null && attribute.privateImeOptions.equals(IME_OPTION_NO_MICROPHONE)); @@ -1719,10 +1723,13 @@ public class LatinIME extends InputMethodService if (VOICE_INSTALLED) { boolean enableVoice = sp.getBoolean(PREF_ENABLE_VOICE, true); - if (enableVoice != mEnableVoice && mKeyboardSwitcher != null) { - mKeyboardSwitcher.setVoiceMode(enableVoice); + boolean voiceOnPrimary = sp.getBoolean(PREF_VOICE_MAIN, true); + if (mKeyboardSwitcher != null && + (enableVoice != mEnableVoice || voiceOnPrimary != mVoiceOnPrimary)) { + mKeyboardSwitcher.setVoiceMode(enableVoice, voiceOnPrimary); } mEnableVoice = enableVoice; + mVoiceOnPrimary = voiceOnPrimary; } mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE, mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions; diff --git a/src/com/android/inputmethod/latin/LatinKeyboard.java b/src/com/android/inputmethod/latin/LatinKeyboard.java index df38358d6..f876af709 100644 --- a/src/com/android/inputmethod/latin/LatinKeyboard.java +++ b/src/com/android/inputmethod/latin/LatinKeyboard.java @@ -38,6 +38,10 @@ public class LatinKeyboard extends Keyboard { private Drawable mOldShiftIcon; private Drawable mOldShiftPreviewIcon; private Drawable mSpaceIcon; + private Drawable mMicIcon; + private Drawable mMicPreviewIcon; + private Drawable m123MicIcon; + private Drawable m123MicPreviewIcon; private Key mShiftKey; private Key mEnterKey; private Key mF1Key; @@ -45,6 +49,7 @@ public class LatinKeyboard extends Keyboard { /* package */ Locale mLocale; private Resources mRes; private int mMode; + private boolean mHasVoice; private int mExtensionResId; @@ -57,22 +62,26 @@ public class LatinKeyboard extends Keyboard { static int sSpacebarVerticalCorrection; public LatinKeyboard(Context context, int xmlLayoutResId) { - this(context, xmlLayoutResId, 0); + this(context, xmlLayoutResId, 0, false); } - public LatinKeyboard(Context context, int xmlLayoutResId, int mode) { + public LatinKeyboard(Context context, int xmlLayoutResId, int mode, boolean hasVoice) { super(context, xmlLayoutResId, mode); final Resources res = context.getResources(); mMode = mode; mRes = res; + mHasVoice = hasVoice; mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked); mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked); mShiftLockPreviewIcon.setBounds(0, 0, mShiftLockPreviewIcon.getIntrinsicWidth(), mShiftLockPreviewIcon.getIntrinsicHeight()); mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space); + mMicIcon = res.getDrawable(R.drawable.sym_keyboard_mic); + mMicPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_mic); sSpacebarVerticalCorrection = res.getDimensionPixelOffset( R.dimen.spacebar_vertical_correction); + setF1Key(); } public LatinKeyboard(Context context, int layoutTemplateResId, @@ -227,28 +236,19 @@ public class LatinKeyboard extends Keyboard { } private void setF1Key() { - // TODO -// else { -// mSpaceKey.icon = mRes.getDrawable(R.drawable.sym_keyboard_space); -// switch (mMode) { -// case KeyboardSwitcher.KEYBOARDMODE_NORMAL: -// case KeyboardSwitcher.KEYBOARDMODE_IM: -// mF1Key.label = ","; -// mF1Key.codes = new int[] { ',' }; -// mF1Key.icon = null; -// mF1Key.iconPreview = null; -// break; -// case KeyboardSwitcher.KEYBOARDMODE_EMAIL: -// case KeyboardSwitcher.KEYBOARDMODE_URL: -// mF1Key.label = mRes.getString(R.string.popular_domain_0); -// mF1Key.codes = new int[] { '.' }; -// mF1Key.text = mF1Key.label; -// mF1Key.icon = null; -// mF1Key.iconPreview = null; -// mF1Key.popupResId = R.xml.popup_domains; -// break; -// } -// } + if (mF1Key == null) return; + System.err.println("Setting F1 key"); + if (!mHasVoice) { + mF1Key.label = ","; + mF1Key.codes = new int[] { ',' }; + mF1Key.icon = null; + mF1Key.iconPreview = null; + } else { + mF1Key.codes = new int[] { LatinKeyboardView.KEYCODE_VOICE }; + mF1Key.label = null; + mF1Key.icon = mMicIcon; + mF1Key.iconPreview = mMicPreviewIcon; + } } private void updateSpaceBarForLocale() {