diff options
Diffstat (limited to 'java/src')
6 files changed, 141 insertions, 76 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java index 5bde668e1..36ebbb589 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java @@ -73,7 +73,7 @@ import java.util.concurrent.TimeUnit; * Because of the above reasons, this class doesn't extend {@link KeyboardView}. */ public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener, - ViewPager.OnPageChangeListener, View.OnTouchListener, + ViewPager.OnPageChangeListener, View.OnClickListener, View.OnTouchListener, EmojiPageKeyboardView.OnKeyEventListener { static final String TAG = EmojiPalettesView.class.getSimpleName(); private static final boolean DEBUG_PAGER = false; @@ -482,22 +482,35 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar); mEmojiLayoutParams.setActionBarProperties(actionBar); + // deleteKey depends only on OnTouchListener. final ImageView deleteKey = (ImageView)findViewById(R.id.emoji_keyboard_delete); deleteKey.setTag(Constants.CODE_DELETE); deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener); + + // alphabetKey depends only on OnTouchListener as it does everything in key-press in + // ACTION_DOWN. final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet); alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId); alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL); alphabetKey.setOnTouchListener(this); + + // alphabetKey2 depends only on OnTouchListener as it does everything in key-press in + // ACTION_DOWN. + final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2); + alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId); + alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL); + alphabetKey2.setOnTouchListener(this); + + // spaceKey depends on {@link View.OnClickListener} as well as {@link View.OnTouchListener}. + // {@link View.OnTouchListener} is used as the trigger of key-press while + // {@link View.OnClickListener} is used as the trigger of key-release which may not occur + // if the event is canceled by moving off the finger from the view. final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space); spaceKey.setBackgroundResource(mKeyBackgroundId); spaceKey.setTag(Constants.CODE_SPACE); spaceKey.setOnTouchListener(this); + spaceKey.setOnClickListener(this); mEmojiLayoutParams.setKeyProperties(spaceKey); - final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2); - alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId); - alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL); - alphabetKey2.setOnTouchListener(this); } @Override @@ -507,7 +520,6 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange updateEmojiCategoryPageIdView(); } - @Override public void onPageSelected(final int position) { final Pair<Integer, Integer> newPos = @@ -545,40 +557,62 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange } } - // Called from {@link EmojiPageKeyboardView} through {@link View.OnTouchListener} interface to - // handle touch events from View-based elements such as the space bar. + /** + * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnTouchListener} + * interface to handle touch events from View-based elements such as the space bar. + * Note that this method is used only for observing {@link MotionEvent#ACTION_DOWN} to trigger + * {@link KeyboardActionListener#onPressKey}. {@link KeyboardActionListener#onReleaseKey} will + * be covered by {@link #onClick} as long as the event is not canceled. + */ @Override public boolean onTouch(final View v, final MotionEvent event) { + if (event.getActionMasked() != MotionEvent.ACTION_DOWN) { + return false; + } final Object tag = v.getTag(); if (!(tag instanceof Integer)) { return false; } final int code = (Integer) tag; - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mKeyboardActionListener.onPressKey( - code, 0 /* repeatCount */, true /* isSinglePointer */); - break; - case MotionEvent.ACTION_UP: - mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE); - mKeyboardActionListener.onReleaseKey(code, false /* withSliding */); - break; - } + mKeyboardActionListener.onPressKey( + code, 0 /* repeatCount */, true /* isSinglePointer */); + // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual + // feedback stop working. return false; } - // Called from {@link EmojiPageKeyboardView} through - // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from - // non-View-based elements like typical Emoji characters. + /** + * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnClickListener} + * interface to handle non-canceled touch-up events from View-based elements such as the space + * bar. + */ + @Override + public void onClick(View v) { + final Object tag = v.getTag(); + if (!(tag instanceof Integer)) { + return; + } + final int code = (Integer) tag; + mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE); + mKeyboardActionListener.onReleaseKey(code, false /* withSliding */); + } + + /** + * Called from {@link EmojiPageKeyboardView} through + * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener} + * interface to handle touch events from non-View-based elements such as Emoji buttons. + */ @Override public void onPressKey(final Key key) { final int code = key.getCode(); mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */); } - // Called from {@link EmojiPageKeyboardView} through - // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from - // non-View-based elements like typical Emoji characters. + /** + * Called from {@link EmojiPageKeyboardView} through + * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener} + * interface to handle touch events from non-View-based elements such as Emoji buttons. + */ @Override public void onReleaseKey(final Key key) { mEmojiPalettesAdapter.addRecentKey(key); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index fb9517220..8a8a45f35 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -44,6 +44,10 @@ import java.util.concurrent.TimeUnit; public class DictionaryFacilitatorForSuggest { public static final String TAG = DictionaryFacilitatorForSuggest.class.getSimpleName(); + // HACK: This threshold is being used when adding a capitalized entry in the User History + // dictionary. + private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140; + private final Context mContext; public final Locale mLocale; @@ -389,7 +393,26 @@ public class DictionaryFacilitatorForSuggest { if (maxFreq == 0) { return; } - final String secondWord = wasAutoCapitalized ? suggestion.toLowerCase(mLocale) : suggestion; + final String suggestionLowerCase = suggestion.toLowerCase(mLocale); + final String secondWord; + if (wasAutoCapitalized) { + secondWord = suggestionLowerCase; + } else { + // HACK: We'd like to avoid adding the capitalized form of common words to the User + // History dictionary in order to avoid suggesting them until the dictionary + // consolidation is done. + // TODO: Remove this hack when ready. + final int lowerCasefreqInMainDict = mMainDictionary != null ? + mMainDictionary.getFrequency(suggestionLowerCase) : + Dictionary.NOT_A_PROBABILITY; + if (maxFreq < lowerCasefreqInMainDict + && lowerCasefreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) { + // Use lower cased word as the word can be a distracter of the popular word. + secondWord = suggestionLowerCase; + } else { + secondWord = suggestion; + } + } // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid". // We don't add words with 0-frequency (assuming they would be profanity etc.). final boolean isValid = maxFreq > 0; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index ba7503dae..adebfc08c 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -84,6 +84,7 @@ import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; import com.android.inputmethod.latin.utils.LatinImeLoggerUtils; import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.research.ResearchLogger; import java.io.FileDescriptor; @@ -1010,9 +1011,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen false /* isObsoleteSuggestions */, false /* isPrediction */); // When in fullscreen mode, show completions generated by the application - setSuggestedWords(suggestedWords); - setAutoCorrectionIndicator(false); - setSuggestionStripShown(true); + setSuggestedWords(suggestedWords, true /* shouldShow */); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions); } @@ -1021,22 +1020,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void setSuggestionStripShownInternal(final boolean shown, final boolean needsInputViewShown) { // TODO: Modify this if we support suggestions with hard keyboard - if (onEvaluateInputViewShown() && mSuggestionStripView != null) { - final boolean inputViewShown = mKeyboardSwitcher.isShowingMainKeyboardOrEmojiPalettes(); - final boolean shouldShowSuggestions = shown - && (needsInputViewShown ? inputViewShown : true); - if (isFullscreenMode()) { - mSuggestionStripView.setVisibility( - shouldShowSuggestions ? View.VISIBLE : View.GONE); - } else { - mSuggestionStripView.setVisibility( - shouldShowSuggestions ? View.VISIBLE : View.INVISIBLE); - } + if (!onEvaluateInputViewShown() || null == mSuggestionStripView) { + return; + } + final boolean inputViewShown = mKeyboardSwitcher.isShowingMainKeyboardOrEmojiPalettes(); + final boolean shouldShowSuggestions = shown + && (needsInputViewShown ? inputViewShown : true); + if (shouldShowSuggestions) { + mSuggestionStripView.setVisibility(View.VISIBLE); + } else { + mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE); } - } - - private void setSuggestionStripShown(final boolean shown) { - setSuggestionStripShownInternal(shown, /* needsInputViewShown */true); } private int getAdjustedBackingViewHeight() { @@ -1330,15 +1324,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // TODO[IL]: Define a clear interface for this - public void setSuggestedWords(final SuggestedWords words) { + public void setSuggestedWords(final SuggestedWords words, final boolean shouldShow) { mInputLogic.mSuggestedWords = words; - if (mSuggestionStripView != null) { - mSuggestionStripView.setSuggestions(words); - mKeyboardSwitcher.onAutoCorrectionStateChanged(words.mWillAutoCorrect); - } - } - - private void setAutoCorrectionIndicator(final boolean newAutoCorrectionIndicator) { + final boolean newAutoCorrectionIndicator = words.mWillAutoCorrect; // Put a blue underline to a word in TextView which will be auto-corrected. if (mInputLogic.mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator && mInputLogic.mWordComposer.isComposingWord()) { @@ -1351,6 +1339,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // the practice. mInputLogic.mConnection.setComposingText(textWithUnderline, 1); } + if (mSuggestionStripView != null) { + mSuggestionStripView.setSuggestions( + words, SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype())); + mKeyboardSwitcher.onAutoCorrectionStateChanged(words.mWillAutoCorrect); + setSuggestionStripShownInternal(shouldShow, true /* needsInputViewShown */); + } } // TODO[IL]: Move this out of LatinIME. @@ -1426,16 +1420,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void showSuggestionStripWithTypedWord(final SuggestedWords sourceSuggestedWords, final String typedWord) { - // TODO: refactor this final SuggestedWords suggestedWords = sourceSuggestedWords.isEmpty() ? SuggestedWords.EMPTY : sourceSuggestedWords; - if (suggestedWords.isEmpty()) { - // No auto-correction is available, clear the cached values. - AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord); - setSuggestedWords(suggestedWords); - setAutoCorrectionIndicator(false); - return; - } final String autoCorrection; if (suggestedWords.mWillAutoCorrect) { autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION); @@ -1444,12 +1430,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // because it may differ from mWordComposer.mTypedWord. autoCorrection = typedWord; } - mInputLogic.mWordComposer.setAutoCorrection(autoCorrection); - setSuggestedWords(suggestedWords); - setAutoCorrectionIndicator(suggestedWords.mWillAutoCorrect); - setSuggestionStripShown(isSuggestionsStripVisible()); - // An auto-correction is available, cache it in accessibility code so - // we can be speak it if the user touches a key that will insert it. + if (SuggestedWords.EMPTY != suggestedWords) { + mInputLogic.mWordComposer.setAutoCorrection(autoCorrection); + } + setSuggestedWords(suggestedWords, isSuggestionsStripVisible()); + // Cache the auto-correction in accessibility code so we can speak it if the user + // touches a key that will insert it. AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord); } @@ -1560,12 +1546,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void setNeutralSuggestionStrip() { final SettingsValues currentSettings = mSettings.getCurrent(); if (currentSettings.mBigramPredictionEnabled) { - setSuggestedWords(SuggestedWords.EMPTY); + setSuggestedWords(SuggestedWords.EMPTY, isSuggestionsStripVisible()); } else { - setSuggestedWords(currentSettings.mSpacingAndPunctuations.mSuggestPuncList); + setSuggestedWords(currentSettings.mSpacingAndPunctuations.mSuggestPuncList, + isSuggestionsStripVisible()); } - setAutoCorrectionIndicator(false); - setSuggestionStripShown(isSuggestionsStripVisible()); } public void unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip( diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index af04de435..3cd9d9555 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -28,6 +28,8 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.support.v4.view.GravityCompat; +import android.support.v4.view.ViewCompat; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; @@ -39,7 +41,6 @@ import android.text.style.UnderlineSpan; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; @@ -88,6 +89,7 @@ final class SuggestionStripLayoutHelper { private final Drawable mMoreSuggestionsHint; private static final String MORE_SUGGESTIONS_HINT = "\u2026"; private static final String LEFTWARDS_ARROW = "\u2190"; + private static final String RIGHTWARDS_ARROW = "\u2192"; private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD); private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan(); @@ -471,10 +473,13 @@ final class SuggestionStripLayoutHelper { final TextView hintView = (TextView)addToDictionaryStrip.findViewById( R.id.hint_add_to_dictionary); - hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL | GravityCompat.START); hintView.setTextColor(mColorAutoCorrect); + final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip) + == ViewCompat.LAYOUT_DIRECTION_RTL); + final String hintWithArrow = (isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW) + + hintText; final int hintWidth = width - wordWidth; - final String hintWithArrow = LEFTWARDS_ARROW + hintText; final float hintScaleX = getTextScaleX(hintWithArrow, hintWidth, hintView.getPaint()); hintView.setText(hintWithArrow); hintView.setTextScaleX(hintScaleX); diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index 32552ebe7..0ebf5cba5 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin.suggestions; import android.content.Context; import android.content.res.Resources; +import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.LayoutInflater; @@ -26,6 +27,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; +import android.view.ViewParent; import android.widget.RelativeLayout; import android.widget.TextView; @@ -83,6 +85,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick showSuggestionsStrip(); } + public void setLayoutDirection(final boolean isRtlLanguage) { + final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL + : ViewCompat.LAYOUT_DIRECTION_LTR; + ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); + ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection); + } + public void showSuggestionsStrip() { mSuggestionsStrip.setVisibility(VISIBLE); mAddToDictionaryStrip.setVisibility(INVISIBLE); @@ -153,8 +162,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mMainKeyboardView = (MainKeyboardView)inputView.findViewById(R.id.keyboard_view); } - public void setSuggestions(final SuggestedWords suggestedWords) { + public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) { clear(); + mStripVisibilityGroup.setLayoutDirection(isRtlLanguage); mSuggestedWords = suggestedWords; mLayoutHelper.layout(mSuggestedWords, mSuggestionsStrip, this); if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { @@ -189,10 +199,21 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick public void clear() { mSuggestionsStrip.removeAllViews(); + removeAllDebugInfoViews(); mStripVisibilityGroup.showSuggestionsStrip(); dismissMoreSuggestionsPanel(); } + private void removeAllDebugInfoViews() { + // The debug info views may be placed as children views of this {@link SuggestionStripView}. + for (final View debugInfoView : mDebugInfoViews) { + final ViewParent parent = debugInfoView.getParent(); + if (parent instanceof ViewGroup) { + ((ViewGroup)parent).removeView(debugInfoView); + } + } + } + private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() { @Override public void onSuggestionSelected(final int index, final SuggestedWordInfo wordInfo) { diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java index fb1be30f1..0d0288923 100644 --- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java @@ -25,7 +25,6 @@ import android.os.Build; import android.util.Log; import android.view.inputmethod.InputMethodSubtype; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.R; @@ -348,8 +347,6 @@ public final class SubtypeLocaleUtils { Arrays.sort(SORTED_RTL_LANGUAGES); } - // TODO: Remove @UsedForTesting annotation. - @UsedForTesting public static boolean isRtlLanguage(final InputMethodSubtype subtype) { final Locale locale = getSubtypeLocale(subtype); final String language = locale.getLanguage(); |