From ec622ced359cfe646efc14b68e25539fa7a438d9 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 21 Jun 2011 18:03:18 +0900 Subject: [PATCH 1/7] Support Turkish keyboard (DO NOT MERGE) Basically this change is back port from Master I1ae2c4ff. Bug: 4435347 Change-Id: Ide1a46bbf5584d8783bb93bbe64328f514c6ab79 --- .../res/values-tr/donottranslate-altchars.xml | 18 +++++----- .../latin/InputLanguageSelection.java | 24 +++++++------ .../inputmethod/latin/LanguageSwitcher.java | 8 ++--- .../android/inputmethod/latin/LatinIME.java | 36 ++++++++++--------- .../inputmethod/latin/LatinKeyboard.java | 10 ++++-- .../latin/LatinKeyboardBaseView.java | 11 +++++- .../inputmethod/latin/LatinKeyboardView.java | 2 +- .../android/inputmethod/latin/Suggest.java | 12 ++++--- 8 files changed, 71 insertions(+), 50 deletions(-) diff --git a/java/res/values-tr/donottranslate-altchars.xml b/java/res/values-tr/donottranslate-altchars.xml index 4200d949e..fb2419c1e 100644 --- a/java/res/values-tr/donottranslate-altchars.xml +++ b/java/res/values-tr/donottranslate-altchars.xml @@ -18,14 +18,14 @@ */ --> - àáâãäåæ - 3èéêë - ìíîï8 - öòóôõœø9 - üùúû7 - ş§ß - ñ - ç - ýÿ6 + â + 3 + īįíìïîı8 + ōøõóòœôö9 + ūúùûü7 + śşßš + + čćç + 6 ğ \ No newline at end of file diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java index c32713983..26854399b 100644 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -16,11 +16,6 @@ package com.android.inputmethod.latin; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Configuration; @@ -32,13 +27,19 @@ import android.preference.PreferenceGroup; import android.preference.PreferenceManager; import android.text.TextUtils; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; + public class InputLanguageSelection extends PreferenceActivity { private String mSelectedLanguages; private ArrayList mAvailableLanguages = new ArrayList(); private static final String[] WHITELIST_LANGUAGES = { - "cs", "da", "de", "en_GB", "en_US", "es", "es_US", "fr", "it", "nb", "nl", "pl", "pt", "ru" + "cs", "da", "de", "en_GB", "en_US", "es", "es_US", "fr", "it", "nb", "nl", "pl", "pt", + "ru", "tr", }; private static boolean isWhitelisted(String lang) { @@ -84,7 +85,7 @@ public class InputLanguageSelection extends PreferenceActivity { for (int i = 0; i < mAvailableLanguages.size(); i++) { CheckBoxPreference pref = new CheckBoxPreference(this); Locale locale = mAvailableLanguages.get(i).locale; - pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale))); + pref.setTitle(LanguageSwitcher.toTitleCase(locale.getDisplayName(locale), locale)); boolean checked = isLocaleIn(locale, languageList); pref.setChecked(checked); if (hasDictionary(locale)) { @@ -184,7 +185,7 @@ public class InputLanguageSelection extends PreferenceActivity { if (finalSize == 0) { preprocess[finalSize++] = - new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l)), l); + new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(l), l), l); } else { // check previous entry: // same lang and a country -> upgrade to full name and @@ -193,14 +194,15 @@ public class InputLanguageSelection extends PreferenceActivity { if (preprocess[finalSize-1].locale.getLanguage().equals( language)) { preprocess[finalSize-1].label = LanguageSwitcher.toTitleCase( - preprocess[finalSize-1].locale.getDisplayName()); + preprocess[finalSize-1].locale.getDisplayName(), + preprocess[finalSize-1].locale); preprocess[finalSize++] = - new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName()), l); + new Loc(LanguageSwitcher.toTitleCase(l.getDisplayName(), l), l); } else { String displayName; if (s.equals("zz_ZZ")) { } else { - displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(l)); + displayName = LanguageSwitcher.toTitleCase(l.getDisplayName(l), l); preprocess[finalSize++] = new Loc(displayName, l); } } diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/latin/LanguageSwitcher.java index 7b5c30491..226b4c690 100644 --- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java +++ b/java/src/com/android/inputmethod/latin/LanguageSwitcher.java @@ -16,13 +16,13 @@ package com.android.inputmethod.latin; -import java.util.Locale; - import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.preference.PreferenceManager; import android.text.TextUtils; +import java.util.Locale; + /** * Keeps track of list of selected input languages and the current * input language that the user has selected. @@ -191,11 +191,11 @@ public class LanguageSwitcher { SharedPreferencesCompat.apply(editor); } - static String toTitleCase(String s) { + static String toTitleCase(String s, Locale locale) { if (s.length() == 0) { return s; } - return Character.toUpperCase(s.charAt(0)) + s.substring(1); + return s.toUpperCase(locale).charAt(0) + s.substring(1); } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index b1689f886..4f3d3ba9f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -16,13 +16,6 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer; -import com.android.inputmethod.voice.FieldContext; -import com.android.inputmethod.voice.SettingsUtil; -import com.android.inputmethod.voice.VoiceInput; - -import org.xmlpull.v1.XmlPullParserException; - import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -65,6 +58,13 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import android.widget.LinearLayout; +import com.android.inputmethod.latin.LatinIMEUtil.RingCharBuffer; +import com.android.inputmethod.voice.FieldContext; +import com.android.inputmethod.voice.SettingsUtil; +import com.android.inputmethod.voice.VoiceInput; + +import org.xmlpull.v1.XmlPullParserException; + import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; @@ -1413,13 +1413,15 @@ public class LatinIME extends InputMethodService } primaryCode = keyCodes[0]; if (mKeyboardSwitcher.isAlphabetMode() && Character.isLowerCase(primaryCode)) { - int upperCaseCode = Character.toUpperCase(primaryCode); - if (upperCaseCode != primaryCode) { - primaryCode = upperCaseCode; + // In some locales, such as Turkish, Character.toUpperCase() may return a wrong + // character because it doesn't take care of locale. + final String upperCaseString = new String(new int[] {primaryCode}, 0, 1) + .toUpperCase(mLanguageSwitcher.getInputLocale()); + if (upperCaseString.codePointCount(0, upperCaseString.length()) == 1) { + primaryCode = upperCaseString.codePointAt(0); } else { // Some keys, such as [eszett], have upper case as multi-characters. - String upperCase = new String(new int[] {primaryCode}, 0, 1).toUpperCase(); - onText(upperCase); + onText(upperCaseString); return; } } @@ -1983,13 +1985,14 @@ public class LatinIME extends InputMethodService * word. */ private void pickSuggestion(CharSequence suggestion, boolean correcting) { - LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); + final Locale inputLocale = mLanguageSwitcher.getInputLocale(); if (mCapsLock) { - suggestion = suggestion.toString().toUpperCase(); + suggestion = suggestion.toString().toUpperCase(inputLocale); } else if (preferCapitalization() || (mKeyboardSwitcher.isAlphabetMode() && inputView.isShifted())) { - suggestion = suggestion.toString().toUpperCase().charAt(0) + suggestion = suggestion.toString().toUpperCase(inputLocale).charAt(0) + suggestion.subSequence(1, suggestion.length()).toString(); } InputConnection ic = getCurrentInputConnection(); @@ -2026,9 +2029,10 @@ public class LatinIME extends InputMethodService // If the first letter of touching is capitalized, make all the suggestions // start with a capital letter. if (Character.isUpperCase(touching.word.charAt(0))) { + final Locale inputLocale = mLanguageSwitcher.getInputLocale(); for (int i = 0; i < suggestions.size(); i++) { String origSugg = (String) suggestions.get(i); - String capsSugg = origSugg.toUpperCase().charAt(0) + String capsSugg = origSugg.toUpperCase(inputLocale).charAt(0) + origSugg.subSequence(1, origSugg.length()).toString(); suggestions.set(i, capsSugg); } diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/latin/LatinKeyboard.java index fbba55bad..1438d7da1 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboard.java @@ -513,7 +513,7 @@ public class LatinKeyboard extends Keyboard { final Rect bounds = new Rect(); // Estimate appropriate language name text size to fit in maxTextWidth. - String language = LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale)); + String language = LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale), locale); int textWidth = getTextWidth(paint, language, origTextSize, bounds); // Assuming text width and text size are proportional to each other. float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); @@ -529,7 +529,7 @@ public class LatinKeyboard extends Keyboard { textSize = origTextSize; } if (useShortName) { - language = LanguageSwitcher.toTitleCase(locale.getLanguage()); + language = LanguageSwitcher.toTitleCase(locale.getLanguage(), locale); textWidth = getTextWidth(paint, language, origTextSize, bounds); textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f); } @@ -646,6 +646,10 @@ public class LatinKeyboard extends Keyboard { setColorOfSymbolIcons(isAutoCompletion, isBlackSym); } + public Locale getInputLocale() { + return (mLocale != null) ? mLocale : mLanguageSwitcher.getSystemLocale(); + } + boolean isCurrentlyInSpace() { return mCurrentlyInSpace; } @@ -955,7 +959,7 @@ public class LatinKeyboard extends Keyboard { } private String getLanguageName(Locale locale) { - return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale)); + return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale), locale); } @Override diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java index 008d37202..fece78689 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java @@ -50,6 +50,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.WeakHashMap; /** @@ -705,10 +706,18 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx return mKeyDetector.isProximityCorrectionEnabled(); } + protected Locale getKeyboardLocale() { + if (mKeyboard instanceof LatinKeyboard) { + return ((LatinKeyboard)mKeyboard).getInputLocale(); + } else { + return getContext().getResources().getConfiguration().locale; + } + } + protected CharSequence adjustCase(CharSequence label) { if (mKeyboard.isShifted() && label != null && label.length() < 3 && Character.isLowerCase(label.charAt(0))) { - label = label.toString().toUpperCase(); + return label.toString().toUpperCase(getKeyboardLocale()); } return label; } diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java index a5476e457..efe03a51f 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java @@ -119,7 +119,7 @@ public class LatinKeyboardView extends LatinKeyboardBaseView { && ((LatinKeyboard) keyboard).isAlphaKeyboard() && !TextUtils.isEmpty(label) && label.length() < 3 && Character.isLowerCase(label.charAt(0))) { - label = label.toString().toUpperCase(); + return label.toString().toUpperCase(getKeyboardLocale()); } return label; } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 3b898941f..5015e9b3d 100755 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -16,17 +16,17 @@ package com.android.inputmethod.latin; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import android.content.Context; import android.text.AutoText; import android.text.TextUtils; import android.util.Log; import android.view.View; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. @@ -265,6 +265,7 @@ public class Suggest implements Dictionary.WordCallback { mNextLettersFrequencies); } char currentChar = wordComposer.getTypedWord().charAt(0); + // TODO: Must pay attention to locale when changing case. char currentCharUpper = Character.toUpperCase(currentChar); int count = 0; int bigramSuggestionSize = mBigramSuggestions.size(); @@ -457,6 +458,7 @@ public class Suggest implements Dictionary.WordCallback { StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1) : new StringBuilder(getApproxMaxWordLength()); sb.setLength(0); + // TODO: Must pay attention to locale when changing case. if (mIsAllUpperCase) { sb.append(new String(word, offset, length).toUpperCase()); } else if (mIsFirstCharCapitalized) { From c79aa482a8198c1a358538d109cedc3bb85b6226 Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Sat, 25 Jun 2011 00:10:49 +0900 Subject: [PATCH 2/7] Tiny string fix. Change-Id: I56dd023b770ffbb85d7be1440301596b77c8d8c2 --- java/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index f6e130789..a6ef5e533 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -105,7 +105,7 @@ Aggressive - Very Aggressive + Very aggressive Bigram suggestions @@ -322,7 +322,7 @@ Touch entered words to correct them, only when suggestions are visible - Keyboard Theme + Keyboard theme Czech Keyboard @@ -409,5 +409,5 @@ isiZulu Voice - Usability Study Mode + Usability study mode From 4f0d290c5d112ebac434bd8de4635f7d42ea2df0 Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Sat, 25 Jun 2011 03:54:11 +0900 Subject: [PATCH 3/7] Avoid memory leak by by non-static Handler inner classes bug: 4901934 Change-Id: I870ab2e621ef3640a84468f09c074cdd726dc963 --- .../AccessibleInputMethodServiceProxy.java | 14 +++-- .../deprecated/voice/VoiceInput.java | 17 ++++-- .../inputmethod/keyboard/KeyboardView.java | 26 ++++---- .../inputmethod/latin/CandidateView.java | 14 +++-- .../android/inputmethod/latin/LatinIME.java | 60 +++++++++++-------- .../latin/StaticInnerHandlerWrapper.java | 42 +++++++++++++ 6 files changed, 122 insertions(+), 51 deletions(-) create mode 100644 java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java index 043266c70..7199550a9 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java @@ -18,7 +18,6 @@ package com.android.inputmethod.accessibility; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; -import android.os.Handler; import android.os.Looper; import android.os.Message; import android.text.TextUtils; @@ -26,6 +25,7 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StaticInnerHandlerWrapper; public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActionListener { private static final AccessibleInputMethodServiceProxy sInstance = @@ -42,18 +42,20 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi private AccessibilityHandler mAccessibilityHandler; - private class AccessibilityHandler extends Handler { + private static class AccessibilityHandler + extends StaticInnerHandlerWrapper { private static final int MSG_NO_HOVER_SELECTION = 0; - public AccessibilityHandler(Looper looper) { - super(looper); + public AccessibilityHandler(AccessibleInputMethodServiceProxy outerInstance, + Looper looper) { + super(outerInstance, looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_NO_HOVER_SELECTION: - notifyNoHoverSelection(); + getOuterInstance().notifyNoHoverSelection(); break; } } @@ -82,7 +84,7 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) { mInputMethod = inputMethod; - mAccessibilityHandler = new AccessibilityHandler(inputMethod.getMainLooper()); + mAccessibilityHandler = new AccessibilityHandler(this, inputMethod.getMainLooper()); } /** diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java index b718ebbb7..8969a2168 100644 --- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java +++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java @@ -19,6 +19,7 @@ package com.android.inputmethod.deprecated.voice; import com.android.inputmethod.latin.EditingUtils; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import android.content.ContentResolver; import android.content.Context; @@ -26,7 +27,6 @@ import android.content.Intent; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; -import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.speech.RecognitionListener; @@ -132,13 +132,20 @@ public class VoiceInput implements OnClickListener { private final static int MSG_RESET = 1; - private final Handler mHandler = new Handler() { + private final UIHandler mHandler = new UIHandler(this); + + private static class UIHandler extends StaticInnerHandlerWrapper { + public UIHandler(VoiceInput outerInstance) { + super(outerInstance); + } + @Override public void handleMessage(Message msg) { if (msg.what == MSG_RESET) { - mState = DEFAULT; - mRecognitionView.finish(); - mUiListener.onCancelVoice(); + final VoiceInput voiceInput = getOuterInstance(); + voiceInput.mState = DEFAULT; + voiceInput.mRecognitionView.finish(); + voiceInput.mUiListener.onCancelVoice(); } } }; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 9dc019c61..6a60a9ddf 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -30,7 +30,6 @@ import android.graphics.Rect; import android.graphics.Region.Op; import android.graphics.Typeface; import android.graphics.drawable.Drawable; -import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; @@ -53,6 +52,7 @@ import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.keyboard.internal.SwipeTracker; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import java.util.ArrayList; import java.util.HashMap; @@ -193,9 +193,9 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private static final String KEY_LABEL_REFERENCE_CHAR = "M"; private final int mKeyLabelHorizontalPadding; - private final UIHandler mHandler = new UIHandler(); + private final UIHandler mHandler = new UIHandler(this); - class UIHandler extends Handler { + public static class UIHandler extends StaticInnerHandlerWrapper { private static final int MSG_SHOW_KEY_PREVIEW = 1; private static final int MSG_DISMISS_KEY_PREVIEW = 2; private static final int MSG_REPEAT_KEY = 3; @@ -205,34 +205,40 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private boolean mInKeyRepeat; + public UIHandler(KeyboardView outerInstance) { + super(outerInstance); + } + @Override public void handleMessage(Message msg) { + final KeyboardView keyboardView = getOuterInstance(); final PointerTracker tracker = (PointerTracker) msg.obj; switch (msg.what) { case MSG_SHOW_KEY_PREVIEW: - showKey(msg.arg1, tracker); + keyboardView.showKey(msg.arg1, tracker); break; case MSG_DISMISS_KEY_PREVIEW: - mPreviewText.setVisibility(View.INVISIBLE); + keyboardView.mPreviewText.setVisibility(View.INVISIBLE); break; case MSG_REPEAT_KEY: tracker.onRepeatKey(msg.arg1); - startKeyRepeatTimer(mKeyRepeatInterval, msg.arg1, tracker); + startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker); break; case MSG_LONGPRESS_KEY: - openMiniKeyboardIfRequired(msg.arg1, tracker); + keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker); break; case MSG_LONGPRESS_SHIFT_KEY: - onLongPressShiftKey(tracker); + keyboardView.onLongPressShiftKey(tracker); break; } } public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) { + final KeyboardView keyboardView = getOuterInstance(); removeMessages(MSG_SHOW_KEY_PREVIEW); - if (mPreviewText.getVisibility() == VISIBLE || delay == 0) { + if (keyboardView.mPreviewText.getVisibility() == VISIBLE || delay == 0) { // Show right away, if it's already visible and finger is moving around - showKey(keyIndex, tracker); + keyboardView.showKey(keyIndex, tracker); } else { sendMessageDelayed( obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay); diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 09fd3b473..bb1ccbfcd 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -21,7 +21,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Typeface; -import android.os.Handler; import android.os.Message; import android.text.Spannable; import android.text.SpannableString; @@ -95,23 +94,28 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo private boolean mShowingAutoCorrectionInverted; private boolean mShowingAddToDictionary; - private final UiHandler mHandler = new UiHandler(); + private final UiHandler mHandler = new UiHandler(this); - private class UiHandler extends Handler { + private static class UiHandler extends StaticInnerHandlerWrapper { private static final int MSG_HIDE_PREVIEW = 0; private static final int MSG_UPDATE_SUGGESTION = 1; private static final long DELAY_HIDE_PREVIEW = 1000; private static final long DELAY_UPDATE_SUGGESTION = 300; + public UiHandler(CandidateView outerInstance) { + super(outerInstance); + } + @Override public void dispatchMessage(Message msg) { + final CandidateView candidateView = getOuterInstance(); switch (msg.what) { case MSG_HIDE_PREVIEW: - hidePreview(); + candidateView.hidePreview(); break; case MSG_UPDATE_SUGGESTION: - updateSuggestions(); + candidateView.updateSuggestions(); break; } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 9c6465dd2..52935ef7d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -29,7 +29,6 @@ import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.net.ConnectivityManager; import android.os.Debug; -import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.SystemClock; @@ -206,9 +205,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private CharSequence mEnteredText; - public final UIHandler mHandler = new UIHandler(); + public final UIHandler mHandler = new UIHandler(this); - public class UIHandler extends Handler { + public static class UIHandler extends StaticInnerHandlerWrapper { private static final int MSG_UPDATE_SUGGESTIONS = 0; private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; private static final int MSG_UPDATE_SHIFT_STATE = 2; @@ -218,42 +217,50 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private static final int MSG_SPACE_TYPED = 6; private static final int MSG_SET_BIGRAM_PREDICTIONS = 7; + public UIHandler(LatinIME outerInstance) { + super(outerInstance); + } + @Override public void handleMessage(Message msg) { - final KeyboardSwitcher switcher = mKeyboardSwitcher; + final LatinIME latinIme = getOuterInstance(); + final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher; final LatinKeyboardView inputView = switcher.getKeyboardView(); switch (msg.what) { case MSG_UPDATE_SUGGESTIONS: - updateSuggestions(); + latinIme.updateSuggestions(); break; case MSG_UPDATE_OLD_SUGGESTIONS: - mRecorrection.fetchAndDisplayRecorrectionSuggestions(mVoiceProxy, mCandidateView, - mSuggest, mKeyboardSwitcher, mWord, mHasUncommittedTypedChars, - mLastSelectionStart, mLastSelectionEnd, mSettingsValues.mWordSeparators); + latinIme.mRecorrection.fetchAndDisplayRecorrectionSuggestions( + latinIme.mVoiceProxy, latinIme.mCandidateView, + latinIme.mSuggest, latinIme.mKeyboardSwitcher, latinIme.mWord, + latinIme.mHasUncommittedTypedChars, latinIme.mLastSelectionStart, + latinIme.mLastSelectionEnd, latinIme.mSettingsValues.mWordSeparators); break; case MSG_UPDATE_SHIFT_STATE: switcher.updateShiftState(); break; case MSG_SET_BIGRAM_PREDICTIONS: - updateBigramPredictions(); + latinIme.updateBigramPredictions(); break; case MSG_VOICE_RESULTS: - mVoiceProxy.handleVoiceResults(preferCapitalization() + latinIme.mVoiceProxy.handleVoiceResults(latinIme.preferCapitalization() || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); break; case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: if (inputView != null) { inputView.setSpacebarTextFadeFactor( - (1.0f + mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar) / 2, + (1.0f + latinIme.mSettingsValues. + mFinalFadeoutFactorOfLanguageOnSpacebar) / 2, (LatinKeyboard)msg.obj); } sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), - mSettingsValues.mDurationOfFadeoutLanguageOnSpacebar); + latinIme.mSettingsValues.mDurationOfFadeoutLanguageOnSpacebar); break; case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: if (inputView != null) { inputView.setSpacebarTextFadeFactor( - mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, + latinIme.mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); } break; @@ -263,7 +270,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void postUpdateSuggestions() { removeMessages(MSG_UPDATE_SUGGESTIONS); sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), - mSettingsValues.mDelayUpdateSuggestions); + getOuterInstance().mSettingsValues.mDelayUpdateSuggestions); } public void cancelUpdateSuggestions() { @@ -277,7 +284,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void postUpdateOldSuggestions() { removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), - mSettingsValues.mDelayUpdateOldSuggestions); + getOuterInstance().mSettingsValues.mDelayUpdateOldSuggestions); } public void cancelUpdateOldSuggestions() { @@ -287,7 +294,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void postUpdateShiftKeyState() { removeMessages(MSG_UPDATE_SHIFT_STATE); sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), - mSettingsValues.mDelayUpdateShiftState); + getOuterInstance().mSettingsValues.mDelayUpdateShiftState); } public void cancelUpdateShiftState() { @@ -297,7 +304,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void postUpdateBigramPredictions() { removeMessages(MSG_SET_BIGRAM_PREDICTIONS); sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS), - mSettingsValues.mDelayUpdateSuggestions); + getOuterInstance().mSettingsValues.mDelayUpdateSuggestions); } public void cancelUpdateBigramPredictions() { @@ -309,23 +316,26 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } public void startDisplayLanguageOnSpacebar(boolean localeChanged) { + final LatinIME latinIme = getOuterInstance(); removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); - final LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); + final LatinKeyboardView inputView = latinIme.mKeyboardSwitcher.getKeyboardView(); if (inputView != null) { - final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard(); + final LatinKeyboard keyboard = latinIme.mKeyboardSwitcher.getLatinKeyboard(); // The language is always displayed when the delay is negative. final boolean needsToDisplayLanguage = localeChanged - || mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar < 0; + || latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar < 0; // The language is never displayed when the delay is zero. - if (mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar != 0) { + if (latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar != 0) { inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f - : mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); + : latinIme.mSettingsValues.mFinalFadeoutFactorOfLanguageOnSpacebar, + keyboard); } // The fadeout animation will start when the delay is positive. - if (localeChanged && mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar > 0) { + if (localeChanged + && latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar > 0) { sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), - mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar); + latinIme.mSettingsValues.mDelayBeforeFadeoutLanguageOnSpacebar); } } } @@ -333,7 +343,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void startDoubleSpacesTimer() { removeMessages(MSG_SPACE_TYPED); sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED), - mSettingsValues.mDoubleSpacesTurnIntoPeriodTimeout); + getOuterInstance().mSettingsValues.mDoubleSpacesTurnIntoPeriodTimeout); } public void cancelDoubleSpacesTimer() { diff --git a/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java new file mode 100644 index 000000000..89d9ea844 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/StaticInnerHandlerWrapper.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 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.latin; + +import android.os.Handler; +import android.os.Looper; + +import java.lang.ref.WeakReference; + +public class StaticInnerHandlerWrapper extends Handler { + final private WeakReference mOuterInstanceRef; + + public StaticInnerHandlerWrapper(T outerInstance) { + super(); + if (outerInstance == null) throw new NullPointerException("outerInstance is null"); + mOuterInstanceRef = new WeakReference(outerInstance); + } + + public StaticInnerHandlerWrapper(T outerInstance, Looper looper) { + super(looper); + if (outerInstance == null) throw new NullPointerException("outerInstance is null"); + mOuterInstanceRef = new WeakReference(outerInstance); + } + + public T getOuterInstance() { + return mOuterInstanceRef.get(); + } +} From 7fb04fe007a6d0489168e9c87771db554c873464 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Sun, 26 Jun 2011 02:07:07 +0900 Subject: [PATCH 4/7] Fix ragged suggestion strip baseline Change-Id: I5fa9e2ad0993602e24f436e1d8ad0999209e5180 --- java/res/layout/candidate_word.xml | 1 + java/res/layout/candidates_strip.xml | 2 +- java/src/com/android/inputmethod/latin/CandidateView.java | 6 ++---- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/java/res/layout/candidate_word.xml b/java/res/layout/candidate_word.xml index 94ae2b44e..3d2ad06e4 100644 --- a/java/res/layout/candidate_word.xml +++ b/java/res/layout/candidate_word.xml @@ -24,4 +24,5 @@ android:layout_height="wrap_content" android:minWidth="@dimen/candidate_min_width" android:textSize="@dimen/candidate_text_size" + android:padding="0dp" style="?attr/suggestionBackgroundStyle" /> diff --git a/java/res/layout/candidates_strip.xml b/java/res/layout/candidates_strip.xml index c23c29cbe..bb11e057c 100644 --- a/java/res/layout/candidates_strip.xml +++ b/java/res/layout/candidates_strip.xml @@ -56,7 +56,7 @@ android:orientation="horizontal" android:layout_weight="1.0" android:layout_width="0dp" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:gravity="center_vertical" > mWords = new ArrayList(); private final ArrayList mInfos = new ArrayList(); private final ArrayList mDividers = new ArrayList(); - private final int mCandidatePadding; private final int mCandidateStripHeight; private final CharacterStyle mInvertedForegroundColorSpan; private final CharacterStyle mInvertedBackgroundColorSpan; @@ -179,14 +178,13 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); - mCandidatePadding = res.getDimensionPixelOffset(R.dimen.candidate_padding); mCandidateStripHeight = res.getDimensionPixelOffset(R.dimen.candidate_strip_height); for (int i = 0; i < MAX_SUGGESTIONS; i++) { final TextView word, info; switch (i) { case 0: word = (TextView)findViewById(R.id.word_left); - word.setPadding(mCandidatePadding, 0, 0, 0); + word.setPadding(res.getDimensionPixelOffset(R.dimen.candidate_padding), 0, 0, 0); info = (TextView)findViewById(R.id.info_left); break; case 1: @@ -355,7 +353,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo if (info != null) { final int infoWidth = info.getMeasuredWidth(); FrameLayoutCompatUtils.placeViewAt( - info, x + width - infoWidth, y, infoWidth, info.getMeasuredHeight()); + info, width - infoWidth, 0, infoWidth, info.getMeasuredHeight()); } } else { // TODO: Handle overflow case. From 717a8f50aec421f74e4d43432059c2fb41cb32c7 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 27 Jun 2011 16:57:18 +0900 Subject: [PATCH 5/7] Use dedicated layout for "touch to save word" feature Change-Id: Ie8c948476740a645d8b2d9a9d821236941d27adf --- java/res/layout/candidates_strip.xml | 131 +++++++++++------- .../inputmethod/latin/CandidateView.java | 33 +++-- 2 files changed, 103 insertions(+), 61 deletions(-) diff --git a/java/res/layout/candidates_strip.xml b/java/res/layout/candidates_strip.xml index bb11e057c..3509a4815 100644 --- a/java/res/layout/candidates_strip.xml +++ b/java/res/layout/candidates_strip.xml @@ -22,42 +22,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +