From 57691a35743e3705abe60db4902f9ad3c0e722d8 Mon Sep 17 00:00:00 2001 From: Maryam Garrett Date: Mon, 28 Jun 2010 16:31:12 -0400 Subject: [PATCH] Show word alternatives for spoken input With this change, we show alternatives for a word that has been spoken.The user triggers the display of alternatives by tapping on the word. The alternatives are currently generated by a client-side algorithm, but will be improved when we move to a server-side generation of the alternatives Change-Id: I454ee28fef9bf97a1b026ce8c605ca4badb39e79 --- .../android/inputmethod/latin/LatinIME.java | 83 ++++++++++++------- .../android/inputmethod/voice/VoiceInput.java | 4 +- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index a89265e76..c19428d05 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -508,7 +508,6 @@ public class LatinIME extends InputMethodService mShowingVoiceSuggestions = false; mImmediatelyAfterVoiceSuggestions = false; mVoiceInputHighlighted = false; - mWordToSuggestions.clear(); mInputTypeNoAutoCorrect = false; mPredictionOn = false; mCompletionOn = false; @@ -702,29 +701,6 @@ public class LatinIME extends InputMethodService postUpdateOldSuggestions(); } } - - if (VOICE_INSTALLED) { - if (mShowingVoiceSuggestions) { - if (mImmediatelyAfterVoiceSuggestions) { - mImmediatelyAfterVoiceSuggestions = false; - } else { - updateSuggestions(); - mShowingVoiceSuggestions = false; - } - } - if (VoiceInput.ENABLE_WORD_CORRECTIONS) { - // If we have alternatives for the current word, then show them. - String word = EditingUtil.getWordAtCursor( - getCurrentInputConnection(), getWordSeparators()); - if (word != null && mWordToSuggestions.containsKey(word.trim())) { - mSuggestionShouldReplaceCurrentWord = true; - final List suggestions = mWordToSuggestions.get(word.trim()); - - setSuggestions(suggestions, false, true, true); - setCandidatesViewShown(true); - } - } - } } @Override @@ -745,6 +721,7 @@ public class LatinIME extends InputMethodService mVoiceInput.cancel(); } } + mWordToSuggestions.clear(); mWordHistory.clear(); super.hideWindow(); TextEntryState.endSession(); @@ -1512,9 +1489,6 @@ public class LatinIME extends InputMethodService // Show N-Best alternates, if there is more than one choice. if (nBest.size() > 1) { mImmediatelyAfterVoiceSuggestions = true; - mShowingVoiceSuggestions = true; - setSuggestions(nBest.subList(1, nBest.size()), false, true, true); - setCandidatesViewShown(true); } mVoiceInputHighlighted = true; mWordToSuggestions.putAll(mVoiceResults.alternatives); @@ -1682,6 +1656,29 @@ public class LatinIME extends InputMethodService } } + private void rememberReplacedWord(CharSequence suggestion) { + if (mShowingVoiceSuggestions) { + // Retain the replaced word in the alternatives array. + InputConnection ic = getCurrentInputConnection(); + EditingUtil.Range range = new EditingUtil.Range(); + String wordToBeReplaced = EditingUtil.getWordAtCursor(getCurrentInputConnection(), + mWordSeparators, range).trim(); + if (!mWordToSuggestions.containsKey(wordToBeReplaced)) { + wordToBeReplaced = wordToBeReplaced.toLowerCase(); + } + if (mWordToSuggestions.containsKey(wordToBeReplaced)) { + List suggestions = mWordToSuggestions.get(wordToBeReplaced); + if (suggestions.contains(suggestion)) { + suggestions.remove(suggestion); + } + suggestions.add(wordToBeReplaced); + mWordToSuggestions.remove(wordToBeReplaced); + mWordToSuggestions.put(suggestion.toString(), suggestions); + } + } + // TODO: implement rememberReplacedWord for typed words + } + private void pickSuggestion(CharSequence suggestion) { if (mCapsLock) { suggestion = suggestion.toString().toUpperCase(); @@ -1692,6 +1689,7 @@ public class LatinIME extends InputMethodService } InputConnection ic = getCurrentInputConnection(); if (ic != null) { + rememberReplacedWord(suggestion); if (mSuggestionShouldReplaceCurrentWord) { EditingUtil.deleteWordAtCursor(ic, getWordSeparators()); } @@ -1710,6 +1708,7 @@ public class LatinIME extends InputMethodService private void setOldSuggestions() { // TODO: Inefficient to check if touching word and then get the touching word. Do it // in one go. + mShowingVoiceSuggestions = false; InputConnection ic = getCurrentInputConnection(); if (ic == null) return; ic.beginBatchEdit(); @@ -1727,7 +1726,35 @@ public class LatinIME extends InputMethodService if (mWordSeparators.indexOf(touching.charAt(touching.length() - 1)) > 0) { touching = touching.toString().substring(0, touching.length() - 1); } - // Search for result in word history + + // Search for result in spoken word alternatives + // TODO: possibly combine the spoken suggestions with the typed suggestions. + String selectedWord = touching.toString().trim(); + if (!mWordToSuggestions.containsKey(selectedWord)){ + selectedWord = selectedWord.toLowerCase(); + } + if (mWordToSuggestions.containsKey(selectedWord)){ + mShowingVoiceSuggestions = true; + mSuggestionShouldReplaceCurrentWord = true; + underlineWord(touching, range.charsBefore, range.charsAfter); + List suggestions = mWordToSuggestions.get(selectedWord); + // If the first letter of touching is capitalized, make all the suggestions + // start with a capital letter. + if (Character.isUpperCase((char) touching.charAt(0))) { + for (int i=0; i< suggestions.size(); i++) { + String origSugg = (String) suggestions.get(i); + String capsSugg = origSugg.toUpperCase().charAt(0) + + origSugg.subSequence(1, origSugg.length()).toString(); + suggestions.set(i,capsSugg); + } + } + setSuggestions(suggestions, false, true, true); + setCandidatesViewShown(true); + TextEntryState.selectedForCorrection(); + ic.endBatchEdit(); + return; + } + // If we didn't find a match, search for result in word history WordComposer foundWord = null; WordAlternatives alternatives = null; for (WordAlternatives entry : mWordHistory) { diff --git a/java/src/com/android/inputmethod/voice/VoiceInput.java b/java/src/com/android/inputmethod/voice/VoiceInput.java index ac06ab50d..354670969 100644 --- a/java/src/com/android/inputmethod/voice/VoiceInput.java +++ b/java/src/com/android/inputmethod/voice/VoiceInput.java @@ -63,7 +63,7 @@ public class VoiceInput implements OnClickListener { // WARNING! Before enabling this, fix the problem with calling getExtractedText() in // landscape view. It causes Extracted text updates to be rejected due to a token mismatch - public static boolean ENABLE_WORD_CORRECTIONS = false; + public static boolean ENABLE_WORD_CORRECTIONS = true; // Dummy word suggestion which means "delete current word" public static final String DELETE_SYMBOL = " \u00D7 "; // times symbol @@ -308,7 +308,7 @@ public class VoiceInput implements OnClickListener { SettingsUtil.getSettingsInt( mContext.getContentResolver(), SettingsUtil.LATIN_IME_MAX_VOICE_RESULTS, - 1)); + 10)); // Get endpointer params from Gservices. // TODO: Consider caching these values for improved performance on slower devices.