aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/CompatUtils.java54
-rw-r--r--java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java3
-rw-r--r--java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java15
-rw-r--r--java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java6
-rw-r--r--java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java29
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java78
-rw-r--r--java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/VoiceProxy.java14
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java104
-rw-r--r--java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java6
-rw-r--r--java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java (renamed from java/src/com/android/inputmethod/latin/Recorrection.java)140
-rw-r--r--java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java (renamed from java/src/com/android/inputmethod/latin/WordAlternatives.java)13
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/FieldContext.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/Hints.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java2
-rw-r--r--java/src/com/android/inputmethod/deprecated/voice/Whitelist.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java53
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyStyles.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java16
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java45
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardParser.java137
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java233
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java186
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboard.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java19
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboard.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java15
-rw-r--r--java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/ModifierKeyState.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java27
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/Row.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/ShiftKeyState.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/SwipeTracker.java2
-rw-r--r--java/src/com/android/inputmethod/latin/AutoDictionary.java12
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java3
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java10
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java19
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java19
-rw-r--r--java/src/com/android/inputmethod/latin/EditingUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableDictionary.java33
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java219
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java93
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java30
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java43
-rw-r--r--java/src/com/android/inputmethod/latin/UserBigramDictionary.java4
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java59
-rw-r--r--java/src/com/android/inputmethod/latin/WhitelistDictionary.java1
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java2
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java114
63 files changed, 1258 insertions, 666 deletions
diff --git a/java/src/com/android/inputmethod/compat/CompatUtils.java b/java/src/com/android/inputmethod/compat/CompatUtils.java
index 0b532f7f0..6e14bfa8b 100644
--- a/java/src/com/android/inputmethod/compat/CompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/CompatUtils.java
@@ -22,7 +22,6 @@ import android.util.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -74,23 +73,22 @@ public class CompatUtils {
return targetClass.getMethod(name, parameterTypes);
} catch (SecurityException e) {
// ignore
- return null;
} catch (NoSuchMethodException e) {
// ignore
- return null;
}
+ return null;
}
public static Field getField(Class<?> targetClass, String name) {
+ if (targetClass == null || TextUtils.isEmpty(name)) return null;
try {
return targetClass.getField(name);
} catch (SecurityException e) {
// ignore
- return null;
} catch (NoSuchFieldException e) {
// ignore
- return null;
}
+ return null;
}
public static Constructor<?> getConstructor(Class<?> targetClass, Class<?>[] types) {
@@ -99,51 +97,49 @@ public class CompatUtils {
return targetClass.getConstructor(types);
} catch (SecurityException e) {
// ignore
- return null;
} catch (NoSuchMethodException e) {
// ignore
- return null;
}
+ return null;
+ }
+
+ public static Object newInstance(Constructor<?> constructor, Object[] args) {
+ if (constructor == null) return null;
+ try {
+ return constructor.newInstance(args);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in newInstance: " + e.getClass().getSimpleName());
+ }
+ return null;
}
public static Object invoke(
Object receiver, Object defaultValue, Method method, Object... args) {
- if (receiver == null || method == null) return defaultValue;
+ if (method == null) return defaultValue;
try {
return method.invoke(receiver, args);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Exception in invoke: IllegalArgumentException");
- return defaultValue;
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Exception in invoke: IllegalAccessException");
- return defaultValue;
- } catch (InvocationTargetException e) {
- Log.e(TAG, "Exception in invoke: IllegalTargetException");
- return defaultValue;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in invoke: " + e.getClass().getSimpleName());
}
+ return defaultValue;
}
public static Object getFieldValue(Object receiver, Object defaultValue, Field field) {
- if (receiver == null || field == null) return defaultValue;
+ if (field == null) return defaultValue;
try {
return field.get(receiver);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Exception in getFieldValue: IllegalArgumentException");
- return defaultValue;
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Exception in getFieldValue: IllegalAccessException");
- return defaultValue;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in getFieldValue: " + e.getClass().getSimpleName());
}
+ return defaultValue;
}
public static void setFieldValue(Object receiver, Field field, Object value) {
- if (receiver == null || field == null) return;
+ if (field == null) return;
try {
field.set(receiver, value);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Exception in setFieldValue: IllegalArgumentException");
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Exception in setFieldValue: IllegalAccessException");
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in setFieldValue: " + e.getClass().getSimpleName());
}
}
diff --git a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
index f6f4f7a59..2789bcb39 100644
--- a/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/EditorInfoCompatUtils.java
@@ -78,6 +78,9 @@ public class EditorInfoCompatUtils {
case EditorInfo.IME_ACTION_SEND:
action = "actionSend";
break;
+ case EditorInfo.IME_ACTION_NEXT:
+ action = "actionNext";
+ break;
case EditorInfo.IME_ACTION_DONE:
action = "actionDone";
break;
diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
index c926be06f..7d00b6007 100644
--- a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
@@ -18,15 +18,12 @@ package com.android.inputmethod.compat;
import com.android.inputmethod.latin.EditingUtils.SelectedWord;
-import android.util.Log;
import android.view.inputmethod.InputConnection;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class InputConnectionCompatUtils {
- private static final String TAG = InputConnectionCompatUtils.class.getSimpleName();
private static final Class<?> CLASS_CorrectionInfo = CompatUtils
.getClass("android.view.inputmethod.CorrectionInfo");
private static final Class<?>[] INPUT_TYPE_CorrectionInfo = new Class<?>[] { int.class,
@@ -53,18 +50,10 @@ public class InputConnectionCompatUtils {
return;
}
Object[] args = { offset, oldText, newText };
- try {
- Object correctionInfo = CONSTRUCTOR_CorrectionInfo.newInstance(args);
+ Object correctionInfo = CompatUtils.newInstance(CONSTRUCTOR_CorrectionInfo, args);
+ if (correctionInfo != null) {
CompatUtils.invoke(ic, null, METHOD_InputConnection_commitCorrection,
correctionInfo);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error in commitCorrection: IllegalArgumentException");
- } catch (InstantiationException e) {
- Log.e(TAG, "Error in commitCorrection: InstantiationException");
- } catch (IllegalAccessException e) {
- Log.e(TAG, "Error in commitCorrection: IllegalAccessException");
- } catch (InvocationTargetException e) {
- Log.e(TAG, "Error in commitCorrection: InvocationTargetException");
}
}
diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
index 806c355a9..667d86c42 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java
@@ -48,6 +48,8 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper
CompatUtils.getMethod(CLASS_InputMethodSubtype, "containsExtraValueKey", String.class);
private static final Method METHOD_getExtraValueOf =
CompatUtils.getMethod(CLASS_InputMethodSubtype, "getExtraValueOf", String.class);
+ private static final Method METHOD_isAuxiliary =
+ CompatUtils.getMethod(CLASS_InputMethodSubtype, "isAuxiliary");
private final int mDummyNameResId;
private final int mDummyIconResId;
@@ -116,6 +118,10 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper
return (String)CompatUtils.invoke(mObj, null, METHOD_getExtraValueOf, key);
}
+ public boolean isAuxiliary() {
+ return (Boolean)CompatUtils.invoke(mObj, false, METHOD_isAuxiliary);
+ }
+
public boolean isDummy() {
return !hasOriginalObject();
}
diff --git a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
index d85174188..6c2f0f799 100644
--- a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java
@@ -37,6 +37,7 @@ public class InputTypeCompatUtils {
(Integer) CompatUtils.getFieldValue(null, null,
FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD);
private static final int WEB_TEXT_PASSWORD_INPUT_TYPE;
+ private static final int WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE;
private static final int NUMBER_PASSWORD_INPUT_TYPE;
private static final int TEXT_PASSWORD_INPUT_TYPE =
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
@@ -45,20 +46,35 @@ public class InputTypeCompatUtils {
static {
WEB_TEXT_PASSWORD_INPUT_TYPE =
- OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD != null
- ? InputType.TYPE_CLASS_TEXT | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD
- : 0;
+ OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD != null
+ ? InputType.TYPE_CLASS_TEXT | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD
+ : 0;
+ WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE =
+ OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null
+ ? InputType.TYPE_CLASS_TEXT
+ | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
+ : 0;
NUMBER_PASSWORD_INPUT_TYPE =
OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD != null
? InputType.TYPE_CLASS_NUMBER | OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD
: 0;
}
+ private static boolean isWebEditTextInputType(int inputType) {
+ return inputType == (InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
+ }
+
private static boolean isWebPasswordInputType(int inputType) {
return WEB_TEXT_PASSWORD_INPUT_TYPE != 0
&& inputType == WEB_TEXT_PASSWORD_INPUT_TYPE;
}
+ private static boolean isWebEmailAddressInputType(int inputType) {
+ return WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE != 0
+ && inputType == WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE;
+ }
+
private static boolean isNumberPasswordInputType(int inputType) {
return NUMBER_PASSWORD_INPUT_TYPE != 0
&& inputType == NUMBER_PASSWORD_INPUT_TYPE;
@@ -78,6 +94,13 @@ public class InputTypeCompatUtils {
|| isWebEmailAddressVariation(variation);
}
+ public static boolean isWebInputType(int inputType) {
+ final int maskedInputType =
+ inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION);
+ return isWebEditTextInputType(maskedInputType) || isWebPasswordInputType(maskedInputType)
+ || isWebEmailAddressInputType(maskedInputType);
+ }
+
// Please refer to TextView.isPasswordInputType
public static boolean isPasswordInputType(int inputType) {
final int maskedInputType =
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
new file mode 100644
index 000000000..5b02de36e
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -0,0 +1,78 @@
+/*
+ * 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.compat;
+
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
+
+import android.content.Context;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+
+import java.lang.reflect.Constructor;
+import java.util.Locale;
+
+public class SuggestionSpanUtils {
+ public static final String ACTION_SUGGESTION_PICKED =
+ "android.text.style.SUGGESTION_PICKED";
+ public static final String SUGGESTION_SPAN_PICKED_AFTER = "after";
+ public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
+ public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";
+
+ private static final Class<?> CLASS_SuggestionSpan = CompatUtils
+ .getClass("android.text.style.SuggestionSpan");
+ private static final Class<?>[] INPUT_TYPE_SuggestionSpan = new Class<?>[] {
+ Context.class, Locale.class, String[].class, int.class, Class.class };
+ private static final Constructor<?> CONSTRUCTOR_SuggestionSpan = CompatUtils
+ .getConstructor(CLASS_SuggestionSpan, INPUT_TYPE_SuggestionSpan);
+ public static final boolean SUGGESTION_SPAN_IS_SUPPORTED;
+ static {
+ SUGGESTION_SPAN_IS_SUPPORTED =
+ CLASS_SuggestionSpan != null && CONSTRUCTOR_SuggestionSpan != null;
+ }
+
+ public static CharSequence getTextWithSuggestionSpan(Context context,
+ CharSequence suggestion, SuggestedWords suggestedWords) {
+ if (CONSTRUCTOR_SuggestionSpan == null || suggestedWords == null
+ || suggestedWords.size() == 0) {
+ return suggestion;
+ }
+
+ final Spannable spannable;
+ if (suggestion instanceof Spannable) {
+ spannable = (Spannable) suggestion;
+ } else {
+ spannable = new SpannableString(suggestion);
+ }
+ // TODO: Use SUGGESTIONS_MAX_SIZE instead of 5.
+ final int N = Math.min(5, suggestedWords.size());
+ final String[] suggestionsArray = new String[N];
+ for (int i = 0; i < N; ++i) {
+ suggestionsArray[i] = suggestedWords.getWord(i).toString();
+ }
+ final Object[] args =
+ { context, null, suggestionsArray, 0,
+ (Class<?>) SuggestionSpanPickedNotificationReceiver.class };
+ final Object ss = CompatUtils.newInstance(CONSTRUCTOR_SuggestionSpan, args);
+ if (ss == null) {
+ return suggestion;
+ }
+ spannable.setSpan(ss, 0, suggestion.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return spannable;
+ }
+}
diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
index e14a49c49..290e6b554 100644
--- a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 753dceead..85993ea4d 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -137,8 +137,8 @@ public class VoiceProxy implements VoiceInput.UiListener {
@Override
public void showHint(int viewResource) {
View view = LayoutInflater.from(mService).inflate(viewResource, null);
- mService.setCandidatesView(view);
- mService.setCandidatesViewShown(true);
+// mService.setCandidatesView(view);
+// mService.setCandidatesViewShown(true);
mIsShowingHint = true;
}
});
@@ -441,7 +441,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
}
builder.setTypedWordValid(true).setHasMinimalSuggestion(true);
mService.setSuggestions(builder.build());
- mService.setCandidatesViewShown(true);
+// mService.setCandidatesViewShown(true);
return true;
}
return false;
@@ -526,7 +526,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
mHandler.post(new Runnable() {
@Override
public void run() {
- mService.setCandidatesViewShown(false);
+// mService.setCandidatesViewShown(false);
mRecognizing = true;
mVoiceInput.newView();
View v = mVoiceInput.getView();
@@ -536,7 +536,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
((ViewGroup) p).removeView(v);
}
- View keyboardView = KeyboardSwitcher.getInstance().getInputView();
+ View keyboardView = KeyboardSwitcher.getInstance().getKeyboardView();
// The full height of the keyboard is difficult to calculate
// as the dimension is expressed in "mm" and not in "pixel"
@@ -691,7 +691,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) {
// Close keyboard view if it is been shown.
if (KeyboardSwitcher.getInstance().isInputViewShown())
- KeyboardSwitcher.getInstance().getInputView().purgeKeyboardAndClosing();
+ KeyboardSwitcher.getInstance().getKeyboardView().purgeKeyboardAndClosing();
startListening(false, windowToken);
}
// If we have no token, onAttachedToWindow will take care of showing dialog and start
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
index a1b49b475..fe70eef96 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Google Inc.
+ * Copyright (C) 2008-2009 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
@@ -43,6 +43,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
+import java.util.Map.Entry;
+import java.util.TreeMap;
public class InputLanguageSelection extends PreferenceActivity {
@@ -51,21 +53,17 @@ public class InputLanguageSelection extends PreferenceActivity {
private HashMap<CheckBoxPreference, Locale> mLocaleMap =
new HashMap<CheckBoxPreference, Locale>();
- private static class Loc implements Comparable<Object> {
+ private static class LocaleEntry implements Comparable<Object> {
private static Collator sCollator = Collator.getInstance();
private String mLabel;
public final Locale mLocale;
- public Loc(String label, Locale locale) {
+ public LocaleEntry(String label, Locale locale) {
this.mLabel = label;
this.mLocale = locale;
}
- public void setLabel(String label) {
- this.mLabel = label;
- }
-
@Override
public String toString() {
return this.mLabel;
@@ -73,7 +71,7 @@ public class InputLanguageSelection extends PreferenceActivity {
@Override
public int compareTo(Object o) {
- return sCollator.compare(this.mLabel, ((Loc) o).mLabel);
+ return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel);
}
}
@@ -85,21 +83,58 @@ public class InputLanguageSelection extends PreferenceActivity {
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, "");
String[] languageList = mSelectedLanguages.split(",");
- ArrayList<Loc> availableLanguages = getUniqueLocales();
+ ArrayList<LocaleEntry> availableLanguages = getUniqueLocales();
PreferenceGroup parent = getPreferenceScreen();
+ final HashMap<Long, LocaleEntry> dictionaryIdLocaleMap = new HashMap<Long, LocaleEntry>();
+ final TreeMap<LocaleEntry, Boolean> localeHasDictionaryMap =
+ new TreeMap<LocaleEntry, Boolean>();
for (int i = 0; i < availableLanguages.size(); i++) {
- Locale locale = availableLanguages.get(i).mLocale;
- final Pair<Boolean, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale);
- final boolean hasDictionary = hasDictionaryOrLayout.first;
+ LocaleEntry loc = availableLanguages.get(i);
+ Locale locale = loc.mLocale;
+ final Pair<Long, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale);
+ final Long dictionaryId = hasDictionaryOrLayout.first;
final boolean hasLayout = hasDictionaryOrLayout.second;
+ final boolean hasDictionary = dictionaryId != null;
// Add this locale to the supported list if:
- // 1) this locale has a layout/ 2) this locale has a dictionary and the length
- // of the locale is equal to or larger than 5.
- if (!hasLayout && !(hasDictionary && locale.toString().length() >= 5)) {
+ // 1) this locale has a layout/ 2) this locale has a dictionary
+ // If some locales have no layout but have a same dictionary, the shortest locale
+ // will be added to the supported list.
+ if (!hasLayout && !hasDictionary) {
continue;
}
+ if (hasLayout) {
+ localeHasDictionaryMap.put(loc, hasDictionary);
+ }
+ if (!hasDictionary) {
+ continue;
+ }
+ if (dictionaryIdLocaleMap.containsKey(dictionaryId)) {
+ final String newLocale = locale.toString();
+ final String oldLocale =
+ dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString();
+ // Check if this locale is more appropriate to be the candidate of the input locale.
+ if (oldLocale.length() <= newLocale.length() && !hasLayout) {
+ // Don't add this new locale to the map<dictionary id, locale> if:
+ // 1) the new locale's name is longer than the existing one, and
+ // 2) the new locale doesn't have its layout
+ continue;
+ }
+ }
+ dictionaryIdLocaleMap.put(dictionaryId, loc);
+ }
+
+ for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) {
+ if (!localeHasDictionaryMap.containsKey(localeEntry)) {
+ localeHasDictionaryMap.put(localeEntry, true);
+ }
+ }
+
+ for (Entry<LocaleEntry, Boolean> entry : localeHasDictionaryMap.entrySet()) {
+ final LocaleEntry localeEntry = entry.getKey();
+ final Locale locale = localeEntry.mLocale;
+ final Boolean hasDictionary = entry.getValue();
CheckBoxPreference pref = new CheckBoxPreference(this);
- pref.setTitle(SubtypeSwitcher.getFullDisplayName(locale, true));
+ pref.setTitle(localeEntry.mLabel);
boolean checked = isLocaleIn(locale, languageList);
pref.setChecked(checked);
if (hasDictionary) {
@@ -118,11 +153,11 @@ public class InputLanguageSelection extends PreferenceActivity {
return false;
}
- private Pair<Boolean, Boolean> hasDictionaryOrLayout(Locale locale) {
- if (locale == null) return new Pair<Boolean, Boolean>(false, false);
+ private Pair<Long, Boolean> hasDictionaryOrLayout(Locale locale) {
+ if (locale == null) return new Pair<Long, Boolean>(null, false);
final Resources res = getResources();
final Locale saveLocale = Utils.setSystemLocale(res, locale);
- final boolean hasDictionary = DictionaryFactory.isDictionaryAvailable(this, locale);
+ final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale);
boolean hasLayout = false;
try {
@@ -141,7 +176,7 @@ public class InputLanguageSelection extends PreferenceActivity {
} catch (IOException e) {
}
Utils.setSystemLocale(res, saveLocale);
- return new Pair<Boolean, Boolean>(hasDictionary, hasLayout);
+ return new Pair<Long, Boolean>(dictionaryId, hasLayout);
}
private String get5Code(Locale locale) {
@@ -174,13 +209,13 @@ public class InputLanguageSelection extends PreferenceActivity {
SharedPreferencesCompat.apply(editor);
}
- public ArrayList<Loc> getUniqueLocales() {
+ public ArrayList<LocaleEntry> getUniqueLocales() {
String[] locales = getAssets().getLocales();
Arrays.sort(locales);
- ArrayList<Loc> uniqueLocales = new ArrayList<Loc>();
+ ArrayList<LocaleEntry> uniqueLocales = new ArrayList<LocaleEntry>();
final int origSize = locales.length;
- Loc[] preprocess = new Loc[origSize];
+ LocaleEntry[] preprocess = new LocaleEntry[origSize];
int finalSize = 0;
for (int i = 0 ; i < origSize; i++ ) {
String s = locales[i];
@@ -202,26 +237,13 @@ public class InputLanguageSelection extends PreferenceActivity {
if (finalSize == 0) {
preprocess[finalSize++] =
- new Loc(SubtypeSwitcher.getFullDisplayName(l, true), l);
+ new LocaleEntry(SubtypeSwitcher.getFullDisplayName(l, false), l);
} else {
- // check previous entry:
- // same lang and a country -> upgrade to full name and
- // insert ours with full name
- // diff lang -> insert ours with lang-only name
- if (preprocess[finalSize-1].mLocale.getLanguage().equals(
- language)) {
- preprocess[finalSize-1].setLabel(SubtypeSwitcher.getFullDisplayName(
- preprocess[finalSize-1].mLocale, false));
- preprocess[finalSize++] =
- new Loc(SubtypeSwitcher.getFullDisplayName(l, false), l);
+ if (s.equals("zz_ZZ")) {
+ // ignore this locale
} else {
- String displayName;
- if (s.equals("zz_ZZ")) {
- // ignore this locale
- } else {
- displayName = SubtypeSwitcher.getFullDisplayName(l, true);
- preprocess[finalSize++] = new Loc(displayName, l);
- }
+ final String displayName = SubtypeSwitcher.getFullDisplayName(l, false);
+ preprocess[finalSize++] = new LocaleEntry(displayName, l);
}
}
}
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 5ef236e31..1eedb5ee1 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -20,6 +20,7 @@ import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.Settings;
import com.android.inputmethod.latin.SharedPreferencesCompat;
+import com.android.inputmethod.latin.Utils;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
@@ -125,8 +126,7 @@ public class LanguageSwitcher {
private void constructLocales() {
mLocales.clear();
for (final String lang : mSelectedLanguageArray) {
- final Locale locale = new Locale(lang.substring(0, 2),
- lang.length() > 4 ? lang.substring(3, 5) : "");
+ final Locale locale = Utils.constructLocaleFromString(lang);
mLocales.add(locale);
}
}
diff --git a/java/src/com/android/inputmethod/latin/Recorrection.java b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
index 3fa6292ba..d40728d25 100644
--- a/java/src/com/android/inputmethod/latin/Recorrection.java
+++ b/java/src/com/android/inputmethod/deprecated/recorrection/Recorrection.java
@@ -14,11 +14,22 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.deprecated.recorrection;
import com.android.inputmethod.compat.InputConnectionCompatUtils;
+import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.AutoCorrection;
+import com.android.inputmethod.latin.CandidateView;
+import com.android.inputmethod.latin.EditingUtils;
+import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.Settings;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.TextEntryState;
+import com.android.inputmethod.latin.WordComposer;
import android.content.SharedPreferences;
import android.content.res.Resources;
@@ -32,12 +43,13 @@ import java.util.ArrayList;
/**
* Manager of re-correction functionalities
*/
-public class Recorrection {
+public class Recorrection implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final Recorrection sInstance = new Recorrection();
private LatinIME mService;
private boolean mRecorrectionEnabled = false;
- private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>();
+ private final ArrayList<RecorrectionSuggestionEntries> mRecorrectionSuggestionsList =
+ new ArrayList<RecorrectionSuggestionEntries>();
public static Recorrection getInstance() {
return sInstance;
@@ -58,20 +70,17 @@ public class Recorrection {
}
private void initInternal(LatinIME context, SharedPreferences prefs) {
- final Resources res = context.getResources();
- // If the option should not be shown, do not read the re-correction preference
- // but always use the default setting defined in the resources.
- if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
- mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
- res.getBoolean(R.bool.config_default_recorrection_enabled));
- } else {
- mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) {
+ mRecorrectionEnabled = false;
+ return;
}
+ updateRecorrectionEnabled(context.getResources(), prefs);
mService = context;
+ prefs.registerOnSharedPreferenceChangeListener(this);
}
public void checkRecorrectionOnStart() {
- if (!mRecorrectionEnabled) return;
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
final InputConnection ic = mService.getCurrentInputConnection();
if (ic == null) return;
@@ -98,42 +107,42 @@ public class Recorrection {
}
public void updateRecorrectionSelection(KeyboardSwitcher keyboardSwitcher,
- CandidateView candidateView, int candidatesStart, int candidatesEnd, int newSelStart,
- int newSelEnd, int oldSelStart, int lastSelectionStart,
+ CandidateView candidateView, int candidatesStart, int candidatesEnd,
+ int newSelStart, int newSelEnd, int oldSelStart, int lastSelectionStart,
int lastSelectionEnd, boolean hasUncommittedTypedChars) {
- if (mRecorrectionEnabled && mService.isShowingSuggestionsStrip()) {
- // Don't look for corrections if the keyboard is not visible
- if (keyboardSwitcher.isInputViewShown()) {
- // Check if we should go in or out of correction mode.
- if (mService.isSuggestionsRequested()
- && (candidatesStart == candidatesEnd || newSelStart != oldSelStart
- || TextEntryState.isRecorrecting())
- && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) {
- if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) {
- mService.mHandler.cancelUpdateBigramPredictions();
- mService.mHandler.postUpdateOldSuggestions();
- } else {
- abortRecorrection(false);
- // If showing the "touch again to save" hint, do not replace it. Else,
- // show the bigrams if we are at the end of the text, punctuation otherwise.
- if (candidateView != null
- && !candidateView.isShowingAddToDictionaryHint()) {
- InputConnection ic = mService.getCurrentInputConnection();
- if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) {
- if (!mService.isShowingPunctuationList()) {
- mService.setPunctuationSuggestions();
- }
- } else {
- mService.mHandler.postUpdateBigramPredictions();
- }
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
+ if (!mService.isShowingSuggestionsStrip()) return;
+ if (!keyboardSwitcher.isInputViewShown()) return;
+ if (!mService.isSuggestionsRequested()) return;
+ // Don't look for corrections if the keyboard is not visible
+ // Check if we should go in or out of correction mode.
+ if ((candidatesStart == candidatesEnd || newSelStart != oldSelStart || TextEntryState
+ .isRecorrecting())
+ && (newSelStart < newSelEnd - 1 || !hasUncommittedTypedChars)) {
+ if (mService.isCursorTouchingWord() || lastSelectionStart < lastSelectionEnd) {
+ mService.mHandler.cancelUpdateBigramPredictions();
+ mService.mHandler.postUpdateOldSuggestions();
+ } else {
+ abortRecorrection(false);
+ // If showing the "touch again to save" hint, do not replace it. Else,
+ // show the bigrams if we are at the end of the text, punctuation
+ // otherwise.
+ if (candidateView != null && !candidateView.isShowingAddToDictionaryHint()) {
+ InputConnection ic = mService.getCurrentInputConnection();
+ if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) {
+ if (!mService.isShowingPunctuationList()) {
+ mService.setPunctuationSuggestions();
}
+ } else {
+ mService.mHandler.postUpdateBigramPredictions();
}
}
}
}
}
- public void saveWordInHistory(WordComposer word, CharSequence result) {
+ public void saveRecorrectionSuggestion(WordComposer word, CharSequence result) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
if (word.size() <= 1) {
return;
}
@@ -144,12 +153,13 @@ public class Recorrection {
// Make a copy of the CharSequence, since it is/could be a mutable CharSequence
final String resultCopy = result.toString();
- WordAlternatives entry = new WordAlternatives(resultCopy, new WordComposer(word));
- mWordHistory.add(entry);
+ RecorrectionSuggestionEntries entry = new RecorrectionSuggestionEntries(
+ resultCopy, new WordComposer(word));
+ mRecorrectionSuggestionsList.add(entry);
}
public void clearWordsInHistory() {
- mWordHistory.clear();
+ mRecorrectionSuggestionsList.clear();
}
/**
@@ -160,11 +170,12 @@ public class Recorrection {
*/
public boolean applyTypedAlternatives(WordComposer word, Suggest suggest,
KeyboardSwitcher keyboardSwitcher, EditingUtils.SelectedWord touching) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return false;
// If we didn't find a match, search for result in typed word history
WordComposer foundWord = null;
- WordAlternatives alternatives = null;
+ RecorrectionSuggestionEntries alternatives = null;
// Search old suggestions to suggest re-corrected suggestions.
- for (WordAlternatives entry : mWordHistory) {
+ for (RecorrectionSuggestionEntries entry : mRecorrectionSuggestionsList) {
if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
foundWord = entry.mWordComposer;
alternatives = entry;
@@ -186,7 +197,7 @@ public class Recorrection {
// Found a match, show suggestions
if (foundWord != null || alternatives != null) {
if (alternatives == null) {
- alternatives = new WordAlternatives(touching.mWord, foundWord);
+ alternatives = new RecorrectionSuggestionEntries(touching.mWord, foundWord);
}
showRecorrections(suggest, keyboardSwitcher, alternatives);
if (foundWord != null) {
@@ -201,17 +212,18 @@ public class Recorrection {
private void showRecorrections(Suggest suggest, KeyboardSwitcher keyboardSwitcher,
- WordAlternatives alternatives) {
- SuggestedWords.Builder builder = alternatives.getAlternatives(suggest, keyboardSwitcher);
+ RecorrectionSuggestionEntries entries) {
+ SuggestedWords.Builder builder = entries.getAlternatives(suggest, keyboardSwitcher);
builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
- mService.showSuggestions(builder.build(), alternatives.getOriginalWord());
+ mService.showSuggestions(builder.build(), entries.getOriginalWord());
}
- public void setRecorrectionSuggestions(VoiceProxy voiceProxy, CandidateView candidateView,
- Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word,
- boolean hasUncommittedTypedChars, int lastSelectionStart, int lastSelectionEnd,
- String wordSeparators) {
+ public void fetchAndDisplayRecorrectionSuggestions(VoiceProxy voiceProxy,
+ CandidateView candidateView, Suggest suggest, KeyboardSwitcher keyboardSwitcher,
+ WordComposer word, boolean hasUncommittedTypedChars, int lastSelectionStart,
+ int lastSelectionEnd, String wordSeparators) {
if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return;
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED || !mRecorrectionEnabled) return;
voiceProxy.setShowingVoiceSuggestions(false);
if (candidateView != null && candidateView.isShowingAddToDictionaryHint()) {
return;
@@ -237,7 +249,7 @@ public class Recorrection {
ic.endBatchEdit();
} else {
abortRecorrection(true);
- mService.setPunctuationSuggestions(); // Show the punctuation suggestions list
+ mService.updateBigramPredictions();
}
} else {
abortRecorrection(true);
@@ -245,6 +257,7 @@ public class Recorrection {
}
public void abortRecorrection(boolean force) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
if (force || TextEntryState.isRecorrecting()) {
TextEntryState.onAbortRecorrection();
mService.setCandidatesViewShown(mService.isCandidateStripVisible());
@@ -252,4 +265,23 @@ public class Recorrection {
mService.clearSuggestions();
}
}
+
+ public void updateRecorrectionEnabled(Resources res, SharedPreferences prefs) {
+ // If the option should not be shown, do not read the re-correction preference
+ // but always use the default setting defined in the resources.
+ if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
+ mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
+ res.getBoolean(R.bool.config_default_recorrection_enabled));
+ } else {
+ mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
+ }
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (SuggestionSpanUtils.SUGGESTION_SPAN_IS_SUPPORTED) return;
+ if (key.equals(Settings.PREF_RECORRECTION_ENABLED)) {
+ updateRecorrectionEnabled(mService.getResources(), prefs);
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/WordAlternatives.java b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
index 0e9914400..5e6c87044 100644
--- a/java/src/com/android/inputmethod/latin/WordAlternatives.java
+++ b/java/src/com/android/inputmethod/deprecated/recorrection/RecorrectionSuggestionEntries.java
@@ -14,17 +14,20 @@
* the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.deprecated.recorrection;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.WordComposer;
import android.text.TextUtils;
-public class WordAlternatives {
+public class RecorrectionSuggestionEntries {
public final CharSequence mChosenWord;
public final WordComposer mWordComposer;
- public WordAlternatives(CharSequence chosenWord, WordComposer wordComposer) {
+ public RecorrectionSuggestionEntries(CharSequence chosenWord, WordComposer wordComposer) {
mChosenWord = chosenWord;
mWordComposer = wordComposer;
}
@@ -54,6 +57,6 @@ public class WordAlternatives {
private static SuggestedWords.Builder getTypedSuggestions(
Suggest suggest, KeyboardSwitcher keyboardSwitcher, WordComposer word) {
- return suggest.getSuggestedWordBuilder(keyboardSwitcher.getInputView(), word, null);
+ return suggest.getSuggestedWordBuilder(keyboardSwitcher.getKeyboardView(), word, null);
}
-} \ No newline at end of file
+}
diff --git a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
index 0ef73d2d7..3c79cc218 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/Hints.java b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
index 52a4f4e58..06b234381 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/Hints.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Hints.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
index b57c16f40..dcb826e8f 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/RecognitionView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
index 7721fe268..855a09a1d 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SettingsUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
index 8cc79de1e..25b314085 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/SoundIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
index 7ee0de9c9..2dba01432 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
index 87b943426..22e8207bf 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/VoiceInputLogger.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Google Inc.
+ * Copyright (C) 2008 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
index a3025f252..8ed279f42 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/WaveformImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Google Inc.
+ * Copyright (C) 2008-2009 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
diff --git a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
index 310689cb2..6c5f52ae2 100644
--- a/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
+++ b/java/src/com/android/inputmethod/deprecated/voice/Whitelist.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 5c59d4441..cb529461a 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -101,6 +101,10 @@ public class Key {
/** Key is enabled and responds on press */
public boolean mEnabled = true;
+ // keyWidth constants
+ private static final int KEYWIDTH_FILL_RIGHT = 0;
+ private static final int KEYWIDTH_FILL_BOTH = -1;
+
private final static int[] KEY_STATE_NORMAL_ON = {
android.R.attr.state_checkable,
android.R.attr.state_checked
@@ -140,12 +144,12 @@ public class Key {
};
/**
- * This constructor is being used only for key in mini popup keyboard.
+ * This constructor is being used only for key in popup mini keyboard.
*/
public Key(Resources res, Keyboard keyboard, CharSequence popupCharacter, int x, int y,
- int width, int edgeFlags) {
+ int width, int height, int edgeFlags) {
mKeyboard = keyboard;
- mHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
+ mHeight = height - keyboard.getVerticalGap();
mGap = keyboard.getHorizontalGap();
mVisualInsetsLeft = mVisualInsetsRight = 0;
mWidth = width - mGap;
@@ -178,6 +182,7 @@ public class Key {
* @param x the x coordinate of the top-left
* @param y the y coordinate of the top-left
* @param parser the XML parser containing the attributes for this key
+ * @param keyStyles active key styles set
*/
public Key(Resources res, Row row, int x, int y, XmlResourceParser parser,
KeyStyles keyStyles) {
@@ -185,6 +190,7 @@ public class Key {
final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard);
+ int keyWidth;
try {
mHeight = KeyboardParser.getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_rowHeight,
@@ -192,17 +198,13 @@ public class Key {
mGap = KeyboardParser.getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_horizontalGap,
mKeyboard.getDisplayWidth(), row.mDefaultHorizontalGap);
- mWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
+ keyWidth = KeyboardParser.getDimensionOrFraction(keyboardAttr,
R.styleable.Keyboard_keyWidth,
- mKeyboard.getDisplayWidth(), row.mDefaultWidth) - mGap;
+ mKeyboard.getDisplayWidth(), row.mDefaultWidth);
} finally {
keyboardAttr.recycle();
}
- // Horizontal gap is divided equally to both sides of the key.
- mX = x + mGap / 2;
- mY = y;
-
final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard_Key);
try {
@@ -216,6 +218,35 @@ public class Key {
style = keyStyles.getEmptyKeyStyle();
}
+ final int keyboardWidth = mKeyboard.getDisplayWidth();
+ int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyXPos, keyboardWidth, x);
+ if (keyXPos < 0) {
+ // If keyXPos is negative, the actual x-coordinate will be k + keyXPos.
+ keyXPos += keyboardWidth;
+ if (keyXPos < x) {
+ // keyXPos shouldn't be less than x because drawable area for this key starts
+ // at x. Or, this key will overlaps the adjacent key on its left hand side.
+ keyXPos = x;
+ }
+ }
+ if (keyWidth == KEYWIDTH_FILL_RIGHT) {
+ // If keyWidth is zero, the actual key width will be determined to fill out the
+ // area up to the right edge of the keyboard.
+ keyWidth = keyboardWidth - keyXPos;
+ } else if (keyWidth <= KEYWIDTH_FILL_BOTH) {
+ // If keyWidth is negative, the actual key width will be determined to fill out the
+ // area between the nearest key on the left hand side and the right edge of the
+ // keyboard.
+ keyXPos = x;
+ keyWidth = keyboardWidth - keyXPos;
+ }
+
+ // Horizontal gap is divided equally to both sides of the key.
+ mX = keyXPos + mGap / 2;
+ mY = y;
+ mWidth = keyWidth - mGap;
+
final CharSequence[] popupCharacters = style.getTextArray(keyAttr,
R.styleable.Keyboard_Key_popupCharacters);
if (res.getBoolean(R.bool.config_digit_popup_characters_enabled)) {
@@ -275,7 +306,7 @@ public class Key {
}
private static boolean isDigitPopupCharacter(CharSequence label) {
- return label.length() == 1 && Character.isDigit(label.charAt(0));
+ return label != null && label.length() == 1 && Character.isDigit(label.charAt(0));
}
private static CharSequence[] filterOutDigitPopupCharacters(CharSequence[] popupCharacters) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 0b13afecb..7add43a6d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
index d464c2029..d53df788f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyStyles.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 492883caf..267abccb3 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -151,16 +151,11 @@ public class Keyboard {
* @param context the application or service context
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
* @param id keyboard identifier
+ * @param width keyboard width
*/
- public Keyboard(Context context, int xmlLayoutResId, KeyboardId id) {
- this(context, xmlLayoutResId, id,
- context.getResources().getDisplayMetrics().widthPixels,
- context.getResources().getDisplayMetrics().heightPixels);
- }
- private Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width,
- int height) {
- Resources res = context.getResources();
+ public Keyboard(Context context, int xmlLayoutResId, KeyboardId id, int width) {
+ final Resources res = context.getResources();
GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
@@ -168,7 +163,8 @@ public class Keyboard {
final int horizontalEdgesPadding = (int)res.getDimension(
R.dimen.keyboard_horizontal_edges_padding);
mDisplayWidth = width - horizontalEdgesPadding * 2;
- mDisplayHeight = height;
+ // TODO: Adjust the height by referring to the height of area available for drawing as well.
+ mDisplayHeight = res.getDisplayMetrics().heightPixels;
mDefaultHorizontalGap = 0;
setKeyWidth(mDisplayWidth / 10);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 098af214e..7e67d6f6b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index f68b68f1d..7c03ec71e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -34,35 +34,40 @@ public class KeyboardId {
public static final int MODE_URL = 1;
public static final int MODE_EMAIL = 2;
public static final int MODE_IM = 3;
- public static final int MODE_WEB = 4;
- public static final int MODE_PHONE = 5;
- public static final int MODE_NUMBER = 6;
+ public static final int MODE_PHONE = 4;
+ public static final int MODE_NUMBER = 5;
public final Locale mLocale;
public final int mOrientation;
+ public final int mWidth;
public final int mMode;
public final int mXmlId;
public final int mColorScheme;
+ public final boolean mWebInput;
public final boolean mPasswordInput;
public final boolean mHasSettingsKey;
public final boolean mVoiceKeyEnabled;
public final boolean mHasVoiceKey;
public final int mImeAction;
public final boolean mEnableShiftLock;
+
public final String mXmlName;
+ public final EditorInfo mAttribute;
private final int mHashCode;
public KeyboardId(String xmlName, int xmlId, int colorScheme, Locale locale, int orientation,
- int mode, EditorInfo attribute, boolean hasSettingsKey, boolean voiceKeyEnabled,
- boolean hasVoiceKey, boolean enableShiftLock) {
+ int width, int mode, EditorInfo attribute, boolean hasSettingsKey,
+ boolean voiceKeyEnabled, boolean hasVoiceKey, boolean enableShiftLock) {
final int inputType = (attribute != null) ? attribute.inputType : 0;
final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
this.mLocale = locale;
this.mOrientation = orientation;
+ this.mWidth = width;
this.mMode = mode;
this.mXmlId = xmlId;
this.mColorScheme = colorScheme;
+ this.mWebInput = InputTypeCompatUtils.isWebInputType(inputType);
this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType)
|| InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
this.mHasSettingsKey = hasSettingsKey;
@@ -73,14 +78,18 @@ public class KeyboardId {
this.mImeAction = imeOptions & (
EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
this.mEnableShiftLock = enableShiftLock;
+
this.mXmlName = xmlName;
+ this.mAttribute = attribute;
this.mHashCode = Arrays.hashCode(new Object[] {
locale,
orientation,
+ width,
mode,
xmlId,
colorScheme,
+ mWebInput,
mPasswordInput,
hasSettingsKey,
voiceKeyEnabled,
@@ -90,6 +99,18 @@ public class KeyboardId {
});
}
+ public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) {
+ return new KeyboardId(xmlName, xmlId, mColorScheme, mLocale, mOrientation, mWidth, mMode,
+ mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+ }
+
+ public KeyboardId cloneWithNewGeometry(int width) {
+ if (mWidth == width)
+ return this;
+ return new KeyboardId(mXmlName, mXmlId, mColorScheme, mLocale, mOrientation, width, mMode,
+ mAttribute, mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+ }
+
public int getXmlId() {
return mXmlId;
}
@@ -118,9 +139,11 @@ public class KeyboardId {
boolean equals(KeyboardId other) {
return other.mLocale.equals(this.mLocale)
&& other.mOrientation == this.mOrientation
+ && other.mWidth == this.mWidth
&& other.mMode == this.mMode
&& other.mXmlId == this.mXmlId
&& other.mColorScheme == this.mColorScheme
+ && other.mWebInput == this.mWebInput
&& other.mPasswordInput == this.mPasswordInput
&& other.mHasSettingsKey == this.mHasSettingsKey
&& other.mVoiceKeyEnabled == this.mVoiceKeyEnabled
@@ -136,18 +159,19 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s.xml %s %s %s imeAction=%s %s%s%s%s%s%s]",
+ return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s]",
mXmlName,
mLocale,
- (mOrientation == 1 ? "port" : "land"),
+ (mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
EditorInfoCompatUtils.imeOptionsName(mImeAction),
+ colorSchemeName(mColorScheme),
+ (mWebInput ? " webInput" : ""),
(mPasswordInput ? " passwordInput" : ""),
(mHasSettingsKey ? " hasSettingsKey" : ""),
(mVoiceKeyEnabled ? " voiceKeyEnabled" : ""),
(mHasVoiceKey ? " hasVoiceKey" : ""),
- (mEnableShiftLock ? " enableShiftLock" : ""),
- colorSchemeName(mColorScheme)
+ (mEnableShiftLock ? " enableShiftLock" : "")
);
}
@@ -157,7 +181,6 @@ public class KeyboardId {
case MODE_URL: return "url";
case MODE_EMAIL: return "email";
case MODE_IM: return "im";
- case MODE_WEB: return "web";
case MODE_PHONE: return "phone";
case MODE_NUMBER: return "number";
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 69ae7886a..c2db62a1c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -196,9 +196,20 @@ public class KeyboardParser {
final int keyboardHeight = (int)keyboardAttr.getDimension(
R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- // Keyboard height will not exceed maxKeyboardHeight.
- final int height = Math.min(keyboardHeight, maxKeyboardHeight);
+ R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
+ int minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
+ if (minKeyboardHeight < 0) {
+ // Specified fraction was negative, so it should be calculated against display
+ // width.
+ final int displayWidth = keyboard.getDisplayWidth();
+ minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
+ R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
+ }
+ // Keyboard height will not exceed maxKeyboardHeight and will not be less than
+ // minKeyboardHeight.
+ final int height = Math.max(
+ Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
final int width = keyboard.getDisplayWidth();
keyboard.setKeyboardHeight(height);
@@ -269,7 +280,7 @@ public class KeyboardParser {
if (TAG_KEY.equals(tag)) {
parseKey(parser, row, keys);
} else if (TAG_SPACER.equals(tag)) {
- parseSpacer(parser, keys);
+ parseSpacer(parser, row, keys);
} else if (TAG_INCLUDE.equals(tag)) {
parseIncludeRowContent(parser, row, keys);
} else if (TAG_SWITCH.equals(tag)) {
@@ -316,19 +327,32 @@ public class KeyboardParser {
}
}
- private void parseSpacer(XmlResourceParser parser, List<Key> keys)
+ private void parseSpacer(XmlResourceParser parser, Row row, List<Key> keys)
throws XmlPullParserException, IOException {
if (keys == null) {
checkEndTag(TAG_SPACER, parser);
} else {
if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER));
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ final TypedArray keyboardAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.Keyboard);
- final int gap = getDimensionOrFraction(a, R.styleable.Keyboard_horizontalGap,
- mKeyboard.getDisplayWidth(), 0);
- a.recycle();
+ if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap))
+ throw new IllegalAttribute(parser, "horizontalGap");
+ final int defaultWidth = (row != null) ? row.mDefaultWidth : 0;
+ final int keyWidth = getDimensionOrFraction(keyboardAttr, R.styleable.Keyboard_keyWidth,
+ mKeyboard.getDisplayWidth(), defaultWidth);
+ keyboardAttr.recycle();
+
+ final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
+ R.styleable.Keyboard_Key);
+ int keyXPos = KeyboardParser.getDimensionOrFraction(keyAttr,
+ R.styleable.Keyboard_Key_keyXPos, mKeyboard.getDisplayWidth(), mCurrentX);
+ if (keyXPos < 0) {
+ // If keyXPos is negative, the actual x-coordinate will be display_width + keyXPos.
+ keyXPos += mKeyboard.getDisplayWidth();
+ }
+
checkEndTag(TAG_SPACER, parser);
- setSpacer(gap);
+ setSpacer(keyXPos, keyWidth);
}
}
@@ -443,8 +467,10 @@ public class KeyboardParser {
final TypedArray viewAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.KeyboardView);
try {
- final boolean modeMatched = matchInteger(a,
- R.styleable.Keyboard_Case_mode, id.mMode);
+ final boolean modeMatched = matchTypedValue(a,
+ R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
+ final boolean webInputMatched = matchBoolean(a,
+ R.styleable.Keyboard_Case_webInput, id.mWebInput);
final boolean passwordInputMatched = matchBoolean(a,
R.styleable.Keyboard_Case_passwordInput, id.mPasswordInput);
final boolean settingsKeyMatched = matchBoolean(a,
@@ -461,26 +487,30 @@ public class KeyboardParser {
// this attribute with id.mImeOptions as integer value is enough for our purpose.
final boolean imeActionMatched = matchInteger(a,
R.styleable.Keyboard_Case_imeAction, id.mImeAction);
+ final boolean localeCodeMatched = matchString(a,
+ R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
final boolean languageCodeMatched = matchString(a,
R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
final boolean countryCodeMatched = matchString(a,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
- final boolean selected = modeMatched && passwordInputMatched && settingsKeyMatched
- && voiceEnabledMatched && voiceKeyMatched && colorSchemeMatched
- && imeActionMatched && languageCodeMatched && countryCodeMatched;
+ final boolean selected = modeMatched && webInputMatched && passwordInputMatched
+ && settingsKeyMatched && voiceEnabledMatched && voiceKeyMatched
+ && colorSchemeMatched && imeActionMatched && localeCodeMatched
+ && languageCodeMatched && countryCodeMatched;
- if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
- textAttr(KeyboardId.modeName(
- a.getInt(R.styleable.Keyboard_Case_mode, -1)), "mode"),
+ if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
+ textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
textAttr(KeyboardId.colorSchemeName(
viewAttr.getInt(
- R.styleable.KeyboardView_colorScheme, -1)), "colorSchemeName"),
+ R.styleable.KeyboardView_colorScheme, -1)), "colorScheme"),
+ booleanAttr(a, R.styleable.Keyboard_Case_webInput, "webInput"),
booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"),
booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"),
booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"),
booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"),
textAttr(EditorInfoCompatUtils.imeOptionsName(
a.getInt(R.styleable.Keyboard_Case_imeAction, -1)), "imeAction"),
+ textAttr(a.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"),
textAttr(a.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"),
Boolean.toString(selected)));
@@ -507,7 +537,30 @@ public class KeyboardParser {
private static boolean matchString(TypedArray a, int index, String value) {
// If <case> does not have "index" attribute, that means this <case> is wild-card for the
// attribute.
- return !a.hasValue(index) || a.getString(index).equals(value);
+ return !a.hasValue(index) || stringArrayContains(a.getString(index).split("\\|"), value);
+ }
+
+ private static boolean matchTypedValue(TypedArray a, int index, int intValue, String strValue) {
+ // If <case> does not have "index" attribute, that means this <case> is wild-card for the
+ // attribute.
+ final TypedValue v = a.peekValue(index);
+ if (v == null)
+ return true;
+
+ if (isIntegerValue(v)) {
+ return intValue == a.getInt(index, 0);
+ } else if (isStringValue(v)) {
+ return stringArrayContains(a.getString(index).split("\\|"), strValue);
+ }
+ return false;
+ }
+
+ private static boolean stringArrayContains(String[] array, String value) {
+ for (final String elem : array) {
+ if (elem.equals(value))
+ return true;
+ }
+ return false;
}
private boolean parseDefault(XmlResourceParser parser, Row row, List<Key> keys)
@@ -551,14 +604,14 @@ public class KeyboardParser {
private void startRow(Row row) {
mCurrentX = 0;
- setSpacer(mHorizontalEdgesPadding);
+ setSpacer(mCurrentX, mHorizontalEdgesPadding);
mCurrentRow = row;
}
private void endRow() {
if (mCurrentRow == null)
throw new InflateException("orphant end row tag");
- setSpacer(mHorizontalEdgesPadding);
+ setSpacer(mCurrentX, mHorizontalEdgesPadding);
if (mCurrentX > mMaxRowWidth)
mMaxRowWidth = mCurrentX;
mCurrentY += mCurrentRow.mDefaultHeight;
@@ -566,7 +619,7 @@ public class KeyboardParser {
}
private void endKey(Key key) {
- mCurrentX += key.mGap + key.mWidth;
+ mCurrentX = key.mX - key.mGap / 2 + key.mWidth + key.mGap;
}
private void endKeyboard(int defaultVerticalGap) {
@@ -574,23 +627,42 @@ public class KeyboardParser {
mTotalHeight = mCurrentY - defaultVerticalGap;
}
- private void setSpacer(int gap) {
- mCurrentX += gap;
+ private void setSpacer(int keyXPos, int width) {
+ mCurrentX = keyXPos + width;
}
public static int getDimensionOrFraction(TypedArray a, int index, int base, int defValue) {
final TypedValue value = a.peekValue(index);
if (value == null)
return defValue;
- if (value.type == TypedValue.TYPE_DIMENSION) {
- return a.getDimensionPixelOffset(index, defValue);
- } else if (value.type == TypedValue.TYPE_FRACTION) {
+ if (isFractionValue(value)) {
// Round it to avoid values like 47.9999 from getting truncated
return Math.round(a.getFraction(index, base, base, defValue));
+ } else if (isDimensionValue(value)) {
+ return a.getDimensionPixelOffset(index, defValue);
+ } else if (isIntegerValue(value)) {
+ // For enum value.
+ return a.getInt(index, defValue);
}
return defValue;
}
+ private static boolean isFractionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_FRACTION;
+ }
+
+ private static boolean isDimensionValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_DIMENSION;
+ }
+
+ private static boolean isIntegerValue(TypedValue v) {
+ return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
+ }
+
+ private static boolean isStringValue(TypedValue v) {
+ return v.type == TypedValue.TYPE_STRING;
+ }
+
@SuppressWarnings("serial")
public static class ParseException extends InflateException {
public ParseException(String msg, XmlResourceParser parser) {
@@ -613,6 +685,13 @@ public class KeyboardParser {
}
@SuppressWarnings("serial")
+ private static class IllegalAttribute extends ParseException {
+ public IllegalAttribute(XmlResourceParser parser, String attribute) {
+ super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
+ }
+ }
+
+ @SuppressWarnings("serial")
private static class NonEmptyTag extends ParseException {
public NonEmptyTag(String tag, XmlResourceParser parser) {
super(tag + " must be empty tag", parser);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
index d5412791d..e015b5158 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardShiftState.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 333fbc779..2512118d4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -16,6 +16,16 @@
package com.android.inputmethod.keyboard;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -24,37 +34,30 @@ import com.android.inputmethod.latin.Settings;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.util.Log;
-import android.view.InflateException;
-import android.view.inputmethod.EditorInfo;
-
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Locale;
public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
- private static final String TAG = "KeyboardSwitcher";
- private static final boolean DEBUG = false;
+ private static final String TAG = KeyboardSwitcher.class.getSimpleName();
+ private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
public static final boolean DEBUG_STATE = false;
private static String sConfigDefaultKeyboardThemeId;
public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902";
private static final int[] KEYBOARD_THEMES = {
- R.layout.input_basic,
- R.layout.input_basic_highcontrast,
- R.layout.input_stone_normal,
- R.layout.input_stone_bold,
- R.layout.input_gingerbread,
- R.layout.input_honeycomb,
+ R.style.KeyboardTheme,
+ R.style.KeyboardTheme_HighContrast,
+ R.style.KeyboardTheme_Stone,
+ R.style.KeyboardTheme_Stone_Bold,
+ R.style.KeyboardTheme_Gingerbread,
+ R.style.KeyboardTheme_Honeycomb,
};
private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
- private LatinKeyboardView mInputView;
+ private LatinKeyboardView mKeyboardView;
private LatinIME mInputMethodService;
// TODO: Combine these key state objects with auto mode switch state.
@@ -98,7 +101,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// Default is SETTINGS_KEY_MODE_AUTO.
private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
- private int mLayoutId;
+ private int mThemeIndex;
+ private int mKeyboardWidth;
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -118,11 +122,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
try {
sConfigDefaultKeyboardThemeId = ims.getString(
R.string.config_default_keyboard_theme_id);
- sInstance.mLayoutId = Integer.valueOf(
+ sInstance.mThemeIndex = Integer.valueOf(
prefs.getString(PREF_KEYBOARD_LAYOUT, sConfigDefaultKeyboardThemeId));
} catch (NumberFormatException e) {
sConfigDefaultKeyboardThemeId = "0";
- sInstance.mLayoutId = 0;
+ sInstance.mThemeIndex = 0;
}
prefs.registerOnSharedPreferenceChangeListener(sInstance);
}
@@ -142,7 +146,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void loadKeyboardInternal(EditorInfo attribute, boolean voiceButtonEnabled,
boolean voiceButtonOnPrimary, boolean isSymbols) {
- if (mInputView == null) return;
+ if (mKeyboardView == null) return;
mAttribute = attribute;
mVoiceKeyEnabled = voiceButtonEnabled;
@@ -151,15 +155,39 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// Update the settings key state because number of enabled IMEs could have been changed
mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService);
final KeyboardId id = getKeyboardId(attribute, isSymbols);
- makeSymbolsKeyboardIds(id.mMode, attribute);
- mCurrentId = id;
- mInputView.setKeyPreviewEnabled(mInputMethodService.getPopupOn());
+
+ // 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));
}
+ public void onSizeChanged() {
+ final int width = mInputMethodService.getWindow().getWindow().getDecorView().getWidth();
+ if (width == 0)
+ return;
+ mKeyboardWidth = width;
+ // Set keyboard with new width.
+ final KeyboardId newId = mCurrentId.cloneWithNewGeometry(width);
+ setKeyboard(getKeyboard(newId));
+ }
+
private void setKeyboard(final Keyboard newKeyboard) {
- final Keyboard oldKeyboard = mInputView.getKeyboard();
- mInputView.setKeyboard(newKeyboard);
+ final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
+ mKeyboardView.setKeyboard(newKeyboard);
+ mCurrentId = newKeyboard.mId;
+ final Resources res = mInputMethodService.getResources();
+ mKeyboardView.setKeyPreviewPopupEnabled(
+ Settings.Values.isKeyPreviewPopupEnabled(mPrefs, res),
+ Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, res));
final boolean localeChanged = (oldKeyboard == null)
|| !newKeyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged);
@@ -173,19 +201,19 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final Locale savedLocale = Utils.setSystemLocale(res,
mSubtypeSwitcher.getInputLocale());
- keyboard = new LatinKeyboard(mInputMethodService, id);
+ keyboard = new LatinKeyboard(mInputMethodService, id, id.mWidth);
if (id.mEnableShiftLock) {
keyboard.enableShiftLock();
}
mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard));
- if (DEBUG)
+ if (DEBUG_CACHE)
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": "
+ ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
Utils.setSystemLocale(res, savedLocale);
- } else if (DEBUG) {
+ } else if (DEBUG_CACHE) {
Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id);
}
@@ -242,33 +270,19 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
final boolean hasSettingsKey = hasSettingsKey(attribute);
final Resources res = mInputMethodService.getResources();
final int orientation = res.getConfiguration().orientation;
+ if (mKeyboardWidth == 0)
+ mKeyboardWidth = res.getDisplayMetrics().widthPixels;
final Locale locale = mSubtypeSwitcher.getInputLocale();
return new KeyboardId(
- res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation, mode,
- attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, enableShiftLock);
+ res.getResourceEntryName(xmlId), xmlId, charColorId, locale, orientation,
+ mKeyboardWidth, mode, attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey,
+ enableShiftLock);
}
- private void makeSymbolsKeyboardIds(final int mode, EditorInfo attribute) {
- final Locale locale = mSubtypeSwitcher.getInputLocale();
- final Resources res = mInputMethodService.getResources();
- final int orientation = res.getConfiguration().orientation;
- final int colorScheme = getColorScheme();
- final boolean hasVoiceKey = mVoiceKeyEnabled && !mVoiceButtonOnPrimary;
- final boolean hasSettingsKey = hasSettingsKey(attribute);
- // 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.
- int xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols;
- final String xmlName = res.getResourceEntryName(xmlId);
- mSymbolsId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
- attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
- xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift;
- mSymbolsShiftedId = new KeyboardId(xmlName, xmlId, colorScheme, locale, orientation, mode,
- attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, false);
+ 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() {
@@ -280,18 +294,18 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public boolean isInputViewShown() {
- return mInputView != null && mInputView.isShown();
+ return mKeyboardView != null && mKeyboardView.isShown();
}
public boolean isKeyboardAvailable() {
- if (mInputView != null)
- return mInputView.getKeyboard() != null;
+ if (mKeyboardView != null)
+ return mKeyboardView.getKeyboard() != null;
return false;
}
public LatinKeyboard getLatinKeyboard() {
- if (mInputView != null) {
- final Keyboard keyboard = mInputView.getKeyboard();
+ if (mKeyboardView != null) {
+ final Keyboard keyboard = mKeyboardView.getKeyboard();
if (keyboard instanceof LatinKeyboard)
return (LatinKeyboard)keyboard;
}
@@ -344,7 +358,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
latinKeyboard.setShiftLocked(false);
}
if (latinKeyboard.setShifted(shifted)) {
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
}
@@ -352,7 +366,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void setShiftLocked(boolean shiftLocked) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) {
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
@@ -394,7 +408,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null) {
latinKeyboard.setAutomaticTemporaryUpperCase();
- mInputView.invalidateAllKeys();
+ mKeyboardView.invalidateAllKeys();
}
}
@@ -489,7 +503,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// To be able to turn off caps lock by "double tap" on shift key, we should ignore
// the second tap of the "double tap" from now for a while because we just have
// already turned off caps lock above.
- mInputView.startIgnoringDoubleTap();
+ mKeyboardView.startIgnoringDoubleTap();
} else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()
&& !withSliding) {
// Shift has been pressed without chording while shifted state.
@@ -559,14 +573,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return;
final LatinKeyboard keyboard;
if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) {
- mCurrentId = mSymbolsShiftedId;
- keyboard = getKeyboard(mCurrentId);
+ 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);
} else {
- mCurrentId = mSymbolsId;
- keyboard = getKeyboard(mCurrentId);
+ keyboard = getKeyboard(mSymbolsId);
// 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);
@@ -580,11 +592,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public boolean isVibrateAndSoundFeedbackRequired() {
- return mInputView == null || !mInputView.isInSlidingKeyInput();
+ return mKeyboardView == null || !mKeyboardView.isInSlidingKeyInput();
}
private int getPointerCount() {
- return mInputView == null ? 0 : mInputView.getPointerCount();
+ return mKeyboardView == null ? 0 : mKeyboardView.getPointerCount();
}
private void toggleKeyboardMode() {
@@ -597,7 +609,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public boolean hasDistinctMultitouch() {
- return mInputView != null && mInputView.hasDistinctMultitouch();
+ return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch();
}
private static boolean isSpaceCharacter(int c) {
@@ -694,53 +706,58 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
- public LatinKeyboardView getInputView() {
- return mInputView;
+ public LatinKeyboardView getKeyboardView() {
+ return mKeyboardView;
}
- public LatinKeyboardView onCreateInputView() {
- createInputViewInternal(mLayoutId, true);
- return mInputView;
+ public View onCreateInputView() {
+ return createInputView(mThemeIndex, true);
}
- private void createInputViewInternal(int newLayout, boolean forceReset) {
- int layoutId = newLayout;
- if (mLayoutId != layoutId || mInputView == null || forceReset) {
- if (mInputView != null) {
- mInputView.closing();
- }
- if (KEYBOARD_THEMES.length <= layoutId) {
- layoutId = Integer.valueOf(sConfigDefaultKeyboardThemeId);
- }
+ // Instance variable only for {@link #createInputView(int, boolean)}.
+ private View mCurrentInputView;
- Utils.GCUtils.getInstance().reset();
- boolean tryGC = true;
- for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
- try {
- mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater(
- ).inflate(KEYBOARD_THEMES[layoutId], null);
- tryGC = false;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "load keyboard failed: " + e);
- tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
- mLayoutId + "," + layoutId, e);
- } catch (InflateException e) {
- Log.w(TAG, "load keyboard failed: " + e);
- tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
- mLayoutId + "," + layoutId, e);
- }
+ private View createInputView(final int newThemeIndex, final boolean forceRecreate) {
+ if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate)
+ return mCurrentInputView;
+
+ if (mKeyboardView != null) {
+ mKeyboardView.closing();
+ }
+ final int themeIndex = (newThemeIndex < KEYBOARD_THEMES.length) ? newThemeIndex
+ : Integer.valueOf(sConfigDefaultKeyboardThemeId);
+
+ Utils.GCUtils.getInstance().reset();
+ boolean tryGC = true;
+ for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+ try {
+ final Context themeContext = new ContextThemeWrapper(mInputMethodService,
+ KEYBOARD_THEMES[themeIndex]);
+ mCurrentInputView = LayoutInflater.from(themeContext).inflate(
+ R.layout.input_view, null);
+ tryGC = false;
+ } catch (OutOfMemoryError e) {
+ Log.w(TAG, "load keyboard failed: " + e);
+ tryGC = Utils.GCUtils.getInstance().tryGCOrWait(mThemeIndex + "," + themeIndex, e);
+ } catch (InflateException e) {
+ Log.w(TAG, "load keyboard failed: " + e);
+ tryGC = Utils.GCUtils.getInstance().tryGCOrWait(mThemeIndex + "," + themeIndex, e);
}
- mInputView.setOnKeyboardActionListener(mInputMethodService);
- mLayoutId = layoutId;
}
+
+ mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(
+ R.id.latin_keyboard_view);
+ mKeyboardView.setOnKeyboardActionListener(mInputMethodService);
+ mThemeIndex = themeIndex;
+ return mCurrentInputView;
}
- private void postSetInputView() {
+ private void postSetInputView(final View newInputView) {
mInputMethodService.mHandler.post(new Runnable() {
@Override
public void run() {
- if (mInputView != null) {
- mInputMethodService.setInputView(mInputView);
+ if (newInputView != null) {
+ mInputMethodService.setInputView(newInputView);
}
mInputMethodService.updateInputViewShown();
}
@@ -752,24 +769,22 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
if (PREF_KEYBOARD_LAYOUT.equals(key)) {
final int layoutId = Integer.valueOf(
sharedPreferences.getString(key, sConfigDefaultKeyboardThemeId));
- createInputViewInternal(layoutId, false);
- postSetInputView();
+ postSetInputView(createInputView(layoutId, false));
} else if (Settings.PREF_SETTINGS_KEY.equals(key)) {
mSettingsKeyEnabledInSettings = getSettingsKeyMode(sharedPreferences,
mInputMethodService);
- createInputViewInternal(mLayoutId, true);
- postSetInputView();
+ postSetInputView(createInputView(mThemeIndex, true));
}
}
private int getColorScheme() {
- return (mInputView != null)
- ? mInputView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE;
+ return (mKeyboardView != null)
+ ? mKeyboardView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE;
}
public void onAutoCorrectionStateChanged(boolean isAutoCorrection) {
if (isAutoCorrection != mIsAutoCorrectionActive) {
- LatinKeyboardView keyboardView = getInputView();
+ LatinKeyboardView keyboardView = getKeyboardView();
mIsAutoCorrectionActive = isAutoCorrection;
keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard())
.onAutoCorrectionStateChanged(isAutoCorrection));
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index c551ed49f..f8bce40b1 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -58,14 +58,22 @@ import java.util.WeakHashMap;
* A view that renders a virtual {@link Keyboard}. It handles rendering of keys and detecting key
* presses and touch movements.
*
+ * @attr ref R.styleable#KeyboardView_backgroundDimAmount
+ * @attr ref R.styleable#KeyboardView_colorScheme
* @attr ref R.styleable#KeyboardView_keyBackground
+ * @attr ref R.styleable#KeyboardView_keyHysteresisDistance
+ * @attr ref R.styleable#KeyboardView_keyLetterRatio
+ * @attr ref R.styleable#KeyboardView_keyLetterStyle
* @attr ref R.styleable#KeyboardView_keyPreviewLayout
* @attr ref R.styleable#KeyboardView_keyPreviewOffset
- * @attr ref R.styleable#KeyboardView_labelTextSize
- * @attr ref R.styleable#KeyboardView_keyTextSize
+ * @attr ref R.styleable#KeyboardView_keyPreviewHeight
* @attr ref R.styleable#KeyboardView_keyTextColor
+ * @attr ref R.styleable#KeyboardView_keyTextColorDisabled
+ * @attr ref R.styleable#KeyboardView_labelTextRatio
* @attr ref R.styleable#KeyboardView_verticalCorrection
* @attr ref R.styleable#KeyboardView_popupLayout
+ * @attr ref R.styleable#KeyboardView_shadowColor
+ * @attr ref R.styleable#KeyboardView_shadowRadius
*/
public class KeyboardView extends View implements PointerTracker.UIProxy {
private static final String TAG = KeyboardView.class.getSimpleName();
@@ -86,33 +94,36 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
private static final int HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL = -1;
// XML attribute
- private int mKeyLetterSize;
- private int mKeyTextColor;
- private int mKeyTextColorDisabled;
- private Typeface mKeyLetterStyle = Typeface.DEFAULT;
- private int mLabelTextSize;
- private int mColorScheme = COLOR_SCHEME_WHITE;
- private int mShadowColor;
- private float mShadowRadius;
- private Drawable mKeyBackground;
- private float mBackgroundDimAmount;
- private float mKeyHysteresisDistance;
- private float mVerticalCorrection;
- private int mPreviewOffset;
- private int mPreviewHeight;
- private int mPopupLayout;
+ private final float mKeyLetterRatio;
+ private final int mKeyTextColor;
+ private final int mKeyTextColorDisabled;
+ private final Typeface mKeyLetterStyle;
+ private final float mLabelTextRatio;
+ private final int mColorScheme;
+ private final int mShadowColor;
+ private final float mShadowRadius;
+ private final Drawable mKeyBackground;
+ private final float mBackgroundDimAmount;
+ private final float mKeyHysteresisDistance;
+ private final float mVerticalCorrection;
+ private final int mPreviewOffset;
+ private final int mPreviewHeight;
+ private final int mPopupLayout;
// Main keyboard
private Keyboard mKeyboard;
+ private int mKeyLetterSize;
+ private int mLabelTextSize;
// Key preview
private boolean mInForeground;
private TextView mPreviewText;
- private int mPreviewTextSizeLarge;
- private boolean mShowKeyPreview = true;
- private int mKeyPreviewDisplayedY;
+ private float mPreviewTextRatio;
+ private int mPreviewTextSize;
+ private boolean mShowKeyPreviewPopup = true;
+ private int mKeyPreviewPopupDisplayedY = -1;
private final int mDelayBeforePreview;
- private final int mDelayAfterPreview;
+ private int mDelayAfterPreview;
private ViewGroup mPreviewPlacer;
private final int[] mCoordinates = new int[2];
@@ -300,74 +311,36 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
- int previewLayout = 0;
- int keyTextSize = 0;
- int n = a.getIndexCount();
-
- for (int i = 0; i < n; i++) {
- int attr = a.getIndex(i);
-
- switch (attr) {
- case R.styleable.KeyboardView_keyBackground:
- mKeyBackground = a.getDrawable(attr);
- break;
- case R.styleable.KeyboardView_keyHysteresisDistance:
- mKeyHysteresisDistance = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_verticalCorrection:
- mVerticalCorrection = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewLayout:
- previewLayout = a.getResourceId(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewOffset:
- mPreviewOffset = a.getDimensionPixelOffset(attr, 0);
- break;
- case R.styleable.KeyboardView_keyPreviewHeight:
- mPreviewHeight = a.getDimensionPixelSize(attr, 80);
- break;
- case R.styleable.KeyboardView_keyLetterSize:
- mKeyLetterSize = a.getDimensionPixelSize(attr, 18);
- break;
- case R.styleable.KeyboardView_keyTextColor:
- mKeyTextColor = a.getColor(attr, 0xFF000000);
- break;
- case R.styleable.KeyboardView_keyTextColorDisabled:
- mKeyTextColorDisabled = a.getColor(attr, 0xFF000000);
- break;
- case R.styleable.KeyboardView_labelTextSize:
- mLabelTextSize = a.getDimensionPixelSize(attr, 14);
- break;
- case R.styleable.KeyboardView_popupLayout:
- mPopupLayout = a.getResourceId(attr, 0);
- break;
- case R.styleable.KeyboardView_shadowColor:
- mShadowColor = a.getColor(attr, 0);
- break;
- case R.styleable.KeyboardView_shadowRadius:
- mShadowRadius = a.getFloat(attr, 0f);
- break;
- // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
- case R.styleable.KeyboardView_backgroundDimAmount:
- mBackgroundDimAmount = a.getFloat(attr, 0.5f);
- break;
- case R.styleable.KeyboardView_keyLetterStyle:
- mKeyLetterStyle = Typeface.defaultFromStyle(a.getInt(attr, Typeface.NORMAL));
- break;
- case R.styleable.KeyboardView_colorScheme:
- mColorScheme = a.getInt(attr, COLOR_SCHEME_WHITE);
- break;
- }
- }
+ mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground);
+ mKeyHysteresisDistance = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_keyHysteresisDistance, 0);
+ mVerticalCorrection = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_verticalCorrection, 0);
+ final int previewLayout = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
+ mPreviewOffset = a.getDimensionPixelOffset(R.styleable.KeyboardView_keyPreviewOffset, 0);
+ mPreviewHeight = a.getDimensionPixelSize(R.styleable.KeyboardView_keyPreviewHeight, 80);
+ mKeyLetterRatio = getRatio(a, R.styleable.KeyboardView_keyLetterRatio);
+ mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000);
+ mKeyTextColorDisabled = a.getColor(
+ R.styleable.KeyboardView_keyTextColorDisabled, 0xFF000000);
+ mLabelTextRatio = getRatio(a, R.styleable.KeyboardView_labelTextRatio);
+ mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
+ mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
+ mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
+ // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
+ mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
+ mKeyLetterStyle = Typeface.defaultFromStyle(
+ a.getInt(R.styleable.KeyboardView_keyLetterStyle, Typeface.NORMAL));
+ mColorScheme = a.getInt(R.styleable.KeyboardView_colorScheme, COLOR_SCHEME_WHITE);
final Resources res = getResources();
if (previewLayout != 0) {
mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
- mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
+ mPreviewTextRatio = getRatio(res, R.fraction.key_preview_text_ratio);
} else {
- mShowKeyPreview = false;
+ mShowKeyPreviewPopup = false;
}
mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
@@ -376,7 +349,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mPaint = new Paint();
mPaint.setAntiAlias(true);
- mPaint.setTextSize(keyTextSize);
mPaint.setTextAlign(Align.CENTER);
mPaint.setAlpha(255);
@@ -460,6 +432,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
}
+ // Read fraction value in TypedArray as float.
+ private static float getRatio(TypedArray a, int index) {
+ return a.getFraction(index, 1000, 1000, 1) / 1000.0f;
+ }
+
+ // Read fraction value in resource as float.
+ private static float getRatio(Resources res, int id) {
+ return res.getFraction(id, 1000, 1000) / 1000.0f;
+ }
+
public void startIgnoringDoubleTap() {
if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
mHandler.startIgnoringDoubleTap();
@@ -480,6 +462,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
return mKeyboardActionListener;
}
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ // TODO: Should notify InputMethodService instead?
+ KeyboardSwitcher.getInstance().onSizeChanged();
+ }
+
/**
* Attaches a keyboard to this view. The keyboard can be switched at any time and the
* view will re-layout itself to accommodate the keyboard.
@@ -506,6 +494,10 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
invalidateAllKeys();
mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
mPopupPanelCache.clear();
+ final int keyHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
+ mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
+ mLabelTextSize = (int)(keyHeight * mLabelTextRatio);
+ mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
}
/**
@@ -530,19 +522,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
* Enables or disables the key feedback popup. This is a popup that shows a magnified
* version of the depressed key. By default the preview is enabled.
* @param previewEnabled whether or not to enable the key feedback preview
- * @see #isKeyPreviewEnabled()
+ * @param delay the delay after which the preview is dismissed
+ * @see #isKeyPreviewPopupEnabled()
*/
- public void setKeyPreviewEnabled(boolean previewEnabled) {
- mShowKeyPreview = previewEnabled;
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ mShowKeyPreviewPopup = previewEnabled;
+ mDelayAfterPreview = delay;
}
/**
* Returns the enabled state of the key feedback preview
* @return whether or not the key feedback preview is enabled
- * @see #setKeyPreviewEnabled(boolean)
+ * @see #setKeyPreviewPopupEnabled(boolean, int)
*/
- public boolean isKeyPreviewEnabled() {
- return mShowKeyPreview;
+ public boolean isKeyPreviewPopupEnabled() {
+ return mShowKeyPreviewPopup;
}
public int getColorScheme() {
@@ -865,7 +859,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
@Override
public void showKeyPreview(int keyIndex, PointerTracker tracker) {
- if (mShowKeyPreview) {
+ if (mShowKeyPreviewPopup) {
mHandler.showKeyPreview(mDelayBeforePreview, keyIndex, tracker);
} else if (mKeyboard.needSpacebarPreview(keyIndex)) {
// Show key preview (in this case, slide language switcher) without any delay.
@@ -875,13 +869,15 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
@Override
public void dismissKeyPreview(PointerTracker tracker) {
- if (mShowKeyPreview) {
+ if (mShowKeyPreviewPopup) {
mHandler.cancelShowKeyPreview(tracker);
mHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
} else if (mKeyboard.needSpacebarPreview(KeyDetector.NOT_A_KEY)) {
// Dismiss key preview (in this case, slide language switcher) without any delay.
mPreviewText.setVisibility(View.INVISIBLE);
}
+ // Clear key preview display position.
+ mKeyPreviewPopupDisplayedY = -1;
}
private void addKeyPreview(TextView keyPreview) {
@@ -938,7 +934,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyLetterSize);
previewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
- previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSize);
previewText.setTypeface(mKeyLetterStyle);
}
} else {
@@ -960,7 +956,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + mCoordinates[0];
final int previewY = key.mY - previewHeight + mCoordinates[1] + mPreviewOffset;
// Record key preview position to display mini-keyboard later at the same position
- mKeyPreviewDisplayedY = previewY;
+ mKeyPreviewPopupDisplayedY = previewY;
// Place the key preview.
// TODO: Adjust position of key previews which touch screen edges
@@ -1078,7 +1074,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
});
final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(),
- parentKey).build();
+ parentKey, mKeyboard).build();
miniKeyboardView.setKeyboard(keyboard);
container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
@@ -1111,7 +1107,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
mPopupWindow.setClippingEnabled(false);
}
mPopupMiniKeyboardPanel = popupPanel;
- popupPanel.showPanel(this, parentKey, tracker, mKeyPreviewDisplayedY, mPopupWindow);
+ popupPanel.showPanel(this, parentKey, tracker, mKeyPreviewPopupDisplayedY, mPopupWindow);
invalidateAllKeys();
return true;
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index c279769f6..fe27ab412 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -78,7 +78,7 @@ public class LatinKeyboard extends Keyboard {
// of the most common key width of this keyboard).
private static final int SPACEBAR_DRAG_WIDTH = 3;
// Minimum width of space key preview (proportional to keyboard width).
- private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
+ private static final float SPACEBAR_POPUP_MIN_RATIO = 0.5f;
// Height in space key the language name will be drawn. (proportional to space key height)
public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
// If the full language name needs to be smaller than this value to be drawn on space key,
@@ -88,8 +88,8 @@ public class LatinKeyboard extends Keyboard {
private static final String SMALL_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "small";
private static final String MEDIUM_TEXT_SIZE_OF_LANGUAGE_ON_SPACEBAR = "medium";
- public LatinKeyboard(Context context, KeyboardId id) {
- super(context, id.getXmlId(), id);
+ public LatinKeyboard(Context context, KeyboardId id, int width) {
+ super(context, id.getXmlId(), id, width);
final Resources res = context.getResources();
mContext = context;
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index c98076f35..185f1f8f7 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -16,10 +16,6 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.Utils;
-
import android.content.Context;
import android.graphics.Canvas;
import android.text.TextUtils;
@@ -27,6 +23,10 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.Utils;
+
// TODO: We should remove this class
public class LatinKeyboardView extends KeyboardView {
private static final String TAG = LatinKeyboardView.class.getSimpleName();
@@ -47,7 +47,7 @@ public class LatinKeyboardView extends KeyboardView {
private int mLastY;
public LatinKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ super(context, attrs);
}
public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
@@ -55,14 +55,14 @@ public class LatinKeyboardView extends KeyboardView {
}
@Override
- public void setKeyPreviewEnabled(boolean previewEnabled) {
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard != null
&& (latinKeyboard.isPhoneKeyboard() || latinKeyboard.isNumberKeyboard())) {
// Phone and number keyboard never shows popup preview (except language switch).
- super.setKeyPreviewEnabled(false);
+ super.setKeyPreviewPopupEnabled(false, delay);
} else {
- super.setKeyPreviewEnabled(previewEnabled);
+ super.setKeyPreviewPopupEnabled(previewEnabled, delay);
}
}
@@ -173,7 +173,8 @@ public class LatinKeyboardView extends KeyboardView {
if (!mDroppingEvents) {
mDroppingEvents = true;
// Send an up event
- MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent translated = MotionEvent.obtain(
+ me.getEventTime(), me.getEventTime(),
MotionEvent.ACTION_UP,
mLastX, mLastY, me.getMetaState());
super.onTouchEvent(translated);
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
index 5dde15e94..2d6766f2d 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc.
+ * 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
@@ -23,8 +23,8 @@ import java.util.List;
public class MiniKeyboard extends Keyboard {
private int mDefaultKeyCoordX;
- public MiniKeyboard(Context context, int xmlLayoutResId, KeyboardId id) {
- super(context, xmlLayoutResId, id);
+ public MiniKeyboard(Context context, int xmlLayoutResId, Keyboard parentKeyboard) {
+ super(context, xmlLayoutResId, null, parentKeyboard.getMinWidth());
}
public void setDefaultCoordX(int pos) {
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
index e540fa106..6e939123d 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -181,22 +181,25 @@ public class MiniKeyboardBuilder {
}
}
- public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey) {
+ public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey,
+ Keyboard parentKeyboard) {
final Context context = view.getContext();
mRes = context.getResources();
- final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null);
+ final MiniKeyboard keyboard = new MiniKeyboard(
+ context, layoutTemplateResId, parentKeyboard);
mKeyboard = keyboard;
mPopupCharacters = parentKey.mPopupCharacters;
final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, keyboard.getKeyWidth());
final MiniKeyboardLayoutParams params = new MiniKeyboardLayoutParams(
mPopupCharacters.length, parentKey.mMaxPopupColumn,
- keyWidth, keyboard.getRowHeight(),
+ keyWidth, parentKeyboard.getRowHeight(),
parentKey.mX + (parentKey.mWidth + parentKey.mGap) / 2 - keyWidth / 2,
view.getMeasuredWidth());
mParams = params;
- keyboard.setHeight(params.mNumRows * params.mRowHeight - keyboard.getVerticalGap());
+ keyboard.setRowHeight(params.mRowHeight);
+ keyboard.setHeight(params.mNumRows * params.mRowHeight);
keyboard.setMinWidth(params.mNumColumns * params.mKeyWidth);
keyboard.setDefaultCoordX(params.getDefaultKeyCoordX() + params.mKeyWidth / 2);
}
@@ -235,7 +238,7 @@ public class MiniKeyboardBuilder {
final CharSequence label = mPopupCharacters[n];
final int row = n / params.mNumColumns;
final Key key = new Key(mRes, keyboard, label, params.getX(n, row), params.getY(row),
- params.mKeyWidth, params.getRowFlags(row));
+ params.mKeyWidth, params.mRowHeight, params.getRowFlags(row));
keys.add(key);
}
return keyboard;
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index c4459f616..cc5c3bbfe 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
index f215db876..ebbc79a9e 100644
--- a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 953d487dc..6b4e9469f 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -633,8 +633,6 @@ public class PointerTracker {
private void startLongPressTimer(int keyIndex) {
Key key = getKey(keyIndex);
- if (!key.mEnabled)
- return;
if (key.mCode == Keyboard.CODE_SHIFT) {
mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
} else if (key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
index b3ed1e26f..eecbb26f3 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
index 68de8df8a..9e287c67d 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java b/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
index 32c25801d..ff78ee5c9 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupCharactersParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index 12031f1ea..60d87f789 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.keyboard;
-import com.android.inputmethod.latin.R;
-
import android.content.Context;
import android.content.res.Resources;
import android.os.SystemClock;
@@ -27,6 +25,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.PopupWindow;
+import com.android.inputmethod.latin.R;
+
/**
* A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting
* key presses and touch movements.
@@ -41,7 +41,7 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
private long mDownTime;
public PopupMiniKeyboardView(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.keyboardViewStyle);
+ this(context, attrs, R.attr.popupMiniKeyboardViewStyle);
}
public PopupMiniKeyboardView(Context context, AttributeSet attrs, int defStyle) {
@@ -55,13 +55,14 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
R.dimen.mini_keyboard_slide_allowance));
// Remove gesture detector on mini-keyboard
mGestureDetector = null;
- setKeyPreviewEnabled(false);
+ setKeyPreviewPopupEnabled(false, 0);
}
@Override
- public void setKeyPreviewEnabled(boolean previewEnabled) {
- // Mini keyboard needs no pop-up key preview displayed.
- super.setKeyPreviewEnabled(false);
+ public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a
+ // delay of 0. The delay does not matter actually since the popup is not shown anyway.
+ super.setKeyPreviewPopupEnabled(false, 0);
}
@Override
@@ -75,15 +76,17 @@ public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX()
: parentKey.mX + parentKey.mWidth / 2;
final int pointY = parentKey.mY;
- final int miniKeyboardX = pointX - miniKeyboard.getDefaultCoordX()
- - container.getPaddingLeft()
- + parentKeyboardView.getPaddingLeft() + mCoordinates[0];
+ final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX()
+ + parentKeyboardView.getPaddingLeft();
+ final int miniKeyboardX = Math.max(0, Math.min(miniKeyboardLeft,
+ parentKeyboardView.getWidth() - miniKeyboard.getMinWidth()))
+ - container.getPaddingLeft() + mCoordinates[0];
final int miniKeyboardY = pointY - parentKeyboard.getVerticalGap()
- (container.getMeasuredHeight() - container.getPaddingBottom())
+ parentKeyboardView.getPaddingTop() + mCoordinates[1];
final int x = miniKeyboardX;
- final int y = parentKeyboardView.isKeyPreviewEnabled() && miniKeyboard.isOneRowKeyboard()
- ? keyPreviewY : miniKeyboardY;
+ final int y = parentKeyboardView.isKeyPreviewPopupEnabled() &&
+ miniKeyboard.isOneRowKeyboard() && keyPreviewY >= 0 ? keyPreviewY : miniKeyboardY;
if (miniKeyboard.setShifted(parentKeyboard.isShiftedOrShiftLocked())) {
invalidateAllKeys();
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 80d6de952..33acc6907 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc.
+ * 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
diff --git a/java/src/com/android/inputmethod/keyboard/Row.java b/java/src/com/android/inputmethod/keyboard/Row.java
index 3618c0448..40d7e1472 100644
--- a/java/src/com/android/inputmethod/keyboard/Row.java
+++ b/java/src/com/android/inputmethod/keyboard/Row.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
index 9229208a9..ba15624f0 100644
--- a/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ShiftKeyState.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
index b279c1c7e..5cf31cb14 100644
--- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
+++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -38,7 +38,7 @@ import android.view.ViewConfiguration;
* movement on the spacebar.
*/
public class SlidingLocaleDrawable extends Drawable {
-
+ private static final int SLIDE_SPEED_MULTIPLIER_RATIO = 150;
private final Context mContext;
private final Resources mRes;
private final int mWidth;
@@ -90,7 +90,7 @@ public class SlidingLocaleDrawable extends Drawable {
mCurrentLanguage = null;
return;
}
- mDiff = diff;
+ mDiff = Math.max(diff, diff * SLIDE_SPEED_MULTIPLIER_RATIO / 100);
if (mDiff > mWidth) mDiff = mWidth;
if (mDiff < -mWidth) mDiff = -mWidth;
if (Math.abs(mDiff) > mThreshold) mHitThreshold = true;
diff --git a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
index 730cdc390..975b13b50 100644
--- a/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/SwipeTracker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
diff --git a/java/src/com/android/inputmethod/latin/AutoDictionary.java b/java/src/com/android/inputmethod/latin/AutoDictionary.java
index 307b81d43..460930f16 100644
--- a/java/src/com/android/inputmethod/latin/AutoDictionary.java
+++ b/java/src/com/android/inputmethod/latin/AutoDictionary.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -41,13 +41,8 @@ public class AutoDictionary extends ExpandableDictionary {
static final int FREQUENCY_FOR_PICKED = 3;
// Weight added to a user typing a new word that doesn't get corrected (or is reverted)
static final int FREQUENCY_FOR_TYPED = 1;
- // A word that is frequently typed and gets promoted to the user dictionary, uses this
- // frequency.
- static final int FREQUENCY_FOR_AUTO_ADD = 250;
// If the user touches a typed word 2 times or more, it will become valid.
private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED;
- // If the user touches a typed word 4 times or more, it will be added to the user dict.
- private static final int PROMOTION_THRESHOLD = 4 * FREQUENCY_FOR_PICKED;
private LatinIME mIme;
// Locale for which this auto dictionary is storing words
@@ -151,11 +146,6 @@ public class AutoDictionary extends ExpandableDictionary {
freq = freq < 0 ? addFrequency : freq + addFrequency;
super.addWord(word, freq);
- if (freq >= PROMOTION_THRESHOLD) {
- mIme.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
- freq = 0;
- }
-
synchronized (mPendingWritesLock) {
// Write a null frequency if it is to be deleted from the db
mPendingWrites.put(word, freq == 0 ? null : new Integer(freq));
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index d95fb9638..9748d6006 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -196,8 +196,9 @@ public class BinaryDictionary extends Dictionary {
Arrays.fill(outputChars, (char) 0);
Arrays.fill(scores, 0);
+ final int proximityInfo = keyboard == null ? 0 : keyboard.getProximityInfo();
return getSuggestionsNative(
- mNativeDict, keyboard.getProximityInfo(),
+ mNativeDict, proximityInfo,
codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize,
mFlags, outputChars, scores);
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 562580d41..7ce92920d 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -78,16 +78,20 @@ class BinaryDictionaryGetter {
} else {
try {
// If that was no-go, try to find a publicly exported dictionary.
- return BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
+ List<AssetFileAddress> listFromContentProvider =
+ BinaryDictionaryFileDumper.getDictSetFromContentProvider(locale, context);
+ if (null != listFromContentProvider) {
+ return listFromContentProvider;
+ }
+ // If the list is null, fall through and return the fallback
} catch (FileNotFoundException e) {
Log.e(TAG, "Unable to create dictionary file from provider for locale "
+ locale.toString() + ": falling back to internal dictionary");
- return Arrays.asList(loadFallbackResource(context, fallbackResId));
} catch (IOException e) {
Log.e(TAG, "Unable to read source data for locale "
+ locale.toString() + ": falling back to internal dictionary");
- return Arrays.asList(loadFallbackResource(context, fallbackResId));
}
+ return Arrays.asList(loadFallbackResource(context, fallbackResId));
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index abdf30e6b..fe3c72f4c 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
@@ -40,11 +38,12 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+
import java.util.ArrayList;
import java.util.List;
@@ -57,6 +56,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private static final boolean DBG = LatinImeLogger.sDBG;
private final ArrayList<View> mWords = new ArrayList<View>();
+ private final ArrayList<View> mDividers = new ArrayList<View>();
private final boolean mConfigCandidateHighlightFontColorEnabled;
private final CharacterStyle mInvertedForegroundColorSpan;
private final CharacterStyle mInvertedBackgroundColorSpan;
@@ -148,10 +148,11 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
tv.setOnClickListener(this);
if (i == 0)
tv.setOnLongClickListener(this);
- ImageView divider = (ImageView)v.findViewById(R.id.candidate_divider);
- // Do not display divider of first candidate.
- divider.setVisibility(i == 0 ? INVISIBLE : VISIBLE);
mWords.add(v);
+ if (i > 0) {
+ View divider = inflater.inflate(R.layout.candidate_divider, null);
+ mDividers.add(divider);
+ }
}
scrollTo(0, getScrollY());
@@ -237,6 +238,8 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
} else {
dv.setVisibility(GONE);
}
+ if (i > 0)
+ addView(mDividers.get(i - 1));
addView(v);
}
@@ -275,7 +278,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
setSuggestions(builder.build());
mShowingAddToDictionary = true;
// Disable R.string.hint_add_to_dictionary button
- TextView tv = (TextView)getChildAt(1).findViewById(R.id.candidate_word);
+ TextView tv = (TextView)mWords.get(1).findViewById(R.id.candidate_word);
tv.setClickable(false);
}
@@ -308,7 +311,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
previewText.setText(word);
previewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- View v = getChildAt(index);
+ View v = mWords.get(index);
final int[] offsetInWindow = new int[2];
v.getLocationInWindow(offsetInWindow);
final int posX = offsetInWindow[0];
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 605676d70..bba331868 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -142,6 +142,25 @@ public class DictionaryFactory {
return hasDictionary;
}
+ // TODO: Do not use the size of the dictionary as an unique dictionary ID.
+ public static Long getDictionaryId(Context context, Locale locale) {
+ final Resources res = context.getResources();
+ final Locale saveLocale = Utils.setSystemLocale(res, locale);
+
+ final int resourceId = Utils.getMainDictionaryResourceId(res);
+ final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
+ final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH)
+ ? afd.getLength()
+ : null;
+ try {
+ if (null != afd) afd.close();
+ } catch (java.io.IOException e) {
+ }
+
+ Utils.setSystemLocale(res, saveLocale);
+ return size;
+ }
+
// TODO: Find the Right Way to find out whether the resource is a placeholder or not.
// Suggestion : strip the locale, open the placeholder file and store its offset.
// Upon opening the file, if it's the same offset, then it's the placeholder.
diff --git a/java/src/com/android/inputmethod/latin/EditingUtils.java b/java/src/com/android/inputmethod/latin/EditingUtils.java
index 39e7e402f..e56aa695d 100644
--- a/java/src/com/android/inputmethod/latin/EditingUtils.java
+++ b/java/src/com/android/inputmethod/latin/EditingUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 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
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 26391fe46..97a4a1816 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -229,6 +229,7 @@ public class ExpandableDictionary extends Dictionary {
* Returns the word's frequency or -1 if not found
*/
protected int getWordFrequency(CharSequence word) {
+ // Case-sensitive search
Node node = searchNode(mRoots, word, 0, word.length());
return (node == null) ? -1 : node.mFrequency;
}
@@ -366,12 +367,16 @@ public class ExpandableDictionary extends Dictionary {
/**
* Adds bigrams to the in-memory trie structure that is being used to retrieve any word
- * @param frequency frequency for this bigrams
- * @param addFrequency if true, it adds to current frequency
+ * @param frequency frequency for this bigram
+ * @param addFrequency if true, it adds to current frequency, else it overwrites the old value
* @return returns the final frequency
*/
private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) {
- Node firstWord = searchWord(mRoots, word1, 0, null);
+ // We don't want results to be different according to case of the looked up left hand side
+ // word. We do want however to return the correct case for the right hand side.
+ // So we want to squash the case of the left hand side, and preserve that of the right
+ // hand side word.
+ Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
Node secondWord = searchWord(mRoots, word2, 0, null);
LinkedList<NextWord> bigram = firstWord.mNGrams;
if (bigram == null || bigram.size() == 0) {
@@ -437,8 +442,12 @@ public class ExpandableDictionary extends Dictionary {
}
}
- private void runReverseLookUp(final CharSequence previousWord, final WordCallback callback) {
- Node prevWord = searchNode(mRoots, previousWord, 0, previousWord.length());
+ private void runBigramReverseLookUp(final CharSequence previousWord,
+ final WordCallback callback) {
+ // Search for the lowercase version of the word only, because that's where bigrams
+ // store their sons.
+ Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0,
+ previousWord.length());
if (prevWord != null && prevWord.mNGrams != null) {
reverseLookUp(prevWord.mNGrams, callback);
}
@@ -448,7 +457,7 @@ public class ExpandableDictionary extends Dictionary {
public void getBigrams(final WordComposer codes, final CharSequence previousWord,
final WordCallback callback) {
if (!reloadDictionaryIfRequired()) {
- runReverseLookUp(previousWord, callback);
+ runBigramReverseLookUp(previousWord, callback);
}
}
@@ -494,14 +503,20 @@ public class ExpandableDictionary extends Dictionary {
}
/**
- * Search for the terminal node of the word
+ * Recursively search for the terminal node of the word.
+ *
+ * One iteration takes the full word to search for and the current index of the recursion.
+ *
+ * @param children the node of the trie to search under.
+ * @param word the word to search for. Only read [offset..length] so there may be trailing chars
+ * @param offset the index in {@code word} this recursion should operate on.
+ * @param length the length of the input word.
* @return Returns the terminal node of the word if the word exists
*/
private Node searchNode(final NodeArray children, final CharSequence word, final int offset,
final int length) {
- // TODO Consider combining with addWordRec
final int count = children.mLength;
- char currentChar = word.charAt(offset);
+ final char currentChar = word.charAt(offset);
for (int j = 0; j < count; j++) {
final Node node = children.mData[j];
if (node.mCode == currentChar) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8b130aecd..a4a04ffb1 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -16,21 +16,6 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.compat.CompatUtils;
-import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.compat.InputConnectionCompatUtils;
-import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
-import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
-import com.android.inputmethod.compat.InputTypeCompatUtils;
-import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
-import com.android.inputmethod.deprecated.VoiceProxy;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.LatinKeyboard;
-import com.android.inputmethod.keyboard.LatinKeyboardView;
-
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -58,7 +43,6 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -68,7 +52,23 @@ import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.InputConnection;
-import android.widget.LinearLayout;
+
+import com.android.inputmethod.compat.CompatUtils;
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.compat.InputTypeCompatUtils;
+import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
+import com.android.inputmethod.deprecated.VoiceProxy;
+import com.android.inputmethod.deprecated.recorrection.Recorrection;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.keyboard.LatinKeyboard;
+import com.android.inputmethod.keyboard.LatinKeyboardView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -81,7 +81,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean PERF_DEBUG = false;
private static final boolean TRACE = false;
- private static boolean DEBUG = LatinImeLogger.sDBG;
+ private static boolean DEBUG;
/**
* The private IME option used to indicate that no microphone should be
@@ -216,15 +216,15 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void handleMessage(Message msg) {
final KeyboardSwitcher switcher = mKeyboardSwitcher;
- final LatinKeyboardView inputView = switcher.getInputView();
+ final LatinKeyboardView inputView = switcher.getKeyboardView();
switch (msg.what) {
case MSG_UPDATE_SUGGESTIONS:
updateSuggestions();
break;
case MSG_UPDATE_OLD_SUGGESTIONS:
- mRecorrection.setRecorrectionSuggestions(mVoiceProxy, mCandidateView, mSuggest,
- mKeyboardSwitcher, mWord, mHasUncommittedTypedChars, mLastSelectionStart,
- mLastSelectionEnd, mSettingsValues.mWordSeparators);
+ mRecorrection.fetchAndDisplayRecorrectionSuggestions(mVoiceProxy, mCandidateView,
+ mSuggest, mKeyboardSwitcher, mWord, mHasUncommittedTypedChars,
+ mLastSelectionStart, mLastSelectionEnd, mSettingsValues.mWordSeparators);
break;
case MSG_UPDATE_SHIFT_STATE:
switcher.updateShiftState();
@@ -306,7 +306,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public void startDisplayLanguageOnSpacebar(boolean localeChanged) {
removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR);
removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR);
- final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ final LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
// The language is always displayed when the delay is negative.
@@ -357,6 +357,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mRecorrection = Recorrection.getInstance();
+ DEBUG = LatinImeLogger.sDBG;
loadSettings();
@@ -405,7 +406,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void initSuggest() {
final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
- final Locale keyboardLocale = new Locale(localeStr);
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
final Resources res = mResources;
final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale);
@@ -439,7 +440,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
/* package private */ void resetSuggestMainDict() {
final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
- final Locale keyboardLocale = new Locale(localeStr);
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
int mainDicResId = Utils.getMainDictionaryResourceId(mResources);
mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
}
@@ -486,24 +487,28 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
@Override
- public View onCreateCandidatesView() {
- LayoutInflater inflater = getLayoutInflater();
- LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null);
- mCandidateViewContainer = container;
- mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
- mCandidateView = (CandidateView) container.findViewById(R.id.candidates);
+ public void setInputView(View view) {
+ super.setInputView(view);
+ mCandidateViewContainer = view.findViewById(R.id.candidates_container);
+ mCandidateView = (CandidateView) view.findViewById(R.id.candidates);
mCandidateView.setService(this);
- setCandidatesViewShown(true);
- return container;
+ mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
+ }
+
+ @Override
+ public void setCandidatesView(View view) {
+ // To ensure that CandidatesView will never be set.
+ return;
}
@Override
public void onStartInputView(EditorInfo attribute, boolean restarting) {
final KeyboardSwitcher switcher = mKeyboardSwitcher;
- LatinKeyboardView inputView = switcher.getInputView();
+ LatinKeyboardView inputView = switcher.getKeyboardView();
if (DEBUG) {
- Log.d(TAG, "onStartInputView: " + inputView);
+ Log.d(TAG, "onStartInputView: inputType=" + ((attribute == null) ? "none"
+ : String.format("0x%08x", attribute.inputType)));
}
// In landscape mode, this method gets called without the input view being created.
if (inputView == null) {
@@ -549,13 +554,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
switcher.updateShiftState();
}
- setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ );
+ setSuggestionStripShownInternal(isCandidateStripVisible(), /* needsInputViewShown */ false);
// Delay updating suggestions because keyboard input view may not be shown at this point.
mHandler.postUpdateSuggestions();
updateCorrectionMode();
- inputView.setKeyPreviewEnabled(mSettingsValues.mPopupOn);
+ inputView.setKeyPreviewPopupEnabled(mSettingsValues.mKeyPreviewPopupOn,
+ mSettingsValues.mKeyPreviewPopupDismissDelay);
inputView.setProximityCorrectionEnabled(true);
// If we just entered a text field, maybe it has some old text that requires correction
mRecorrection.checkRecorrectionOnStart();
@@ -622,6 +628,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
@Override
+ public void onWindowHidden() {
+ super.onWindowHidden();
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
+ if (inputView != null) inputView.closing();
+ }
+
+ @Override
public void onFinishInput() {
super.onFinishInput();
@@ -630,7 +643,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing();
if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites();
if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites();
@@ -639,7 +652,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override
public void onFinishInputView(boolean finishingInput) {
super.onFinishInputView(finishingInput);
- KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.setForeground(false);
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestions();
@@ -684,7 +697,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// If the composing span has been cleared, save the typed word in the history for
// recorrection before we reset the candidate strip. Then, we'll be able to show
// suggestions for recorrection right away.
- mRecorrection.saveWordInHistory(mWord, mComposing);
+ mRecorrection.saveRecorrectionSuggestion(mWord, mComposing);
}
mComposing.setLength(0);
mHasUncommittedTypedChars = false;
@@ -795,11 +808,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// When in fullscreen mode, show completions generated by the application
setSuggestions(builder.build());
mBestWord = null;
- setCandidatesViewShown(true);
+ setSuggestionStripShown(true);
}
}
- private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) {
+ private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
// TODO: Modify this if we support candidates with hard keyboard
if (onEvaluateInputViewShown()) {
final boolean shouldShowCandidates = shown
@@ -807,26 +820,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (isExtractViewShown()) {
// No need to have extra space to show the key preview.
mCandidateViewContainer.setMinimumHeight(0);
- super.setCandidatesViewShown(shown);
+ mCandidateViewContainer.setVisibility(
+ shouldShowCandidates ? View.VISIBLE : View.GONE);
} else {
// We must control the visibility of the suggestion strip in order to avoid clipped
// key previews, even when we don't show the suggestion strip.
mCandidateViewContainer.setVisibility(
shouldShowCandidates ? View.VISIBLE : View.INVISIBLE);
- super.setCandidatesViewShown(true);
}
}
}
- @Override
- public void setCandidatesViewShown(boolean shown) {
- setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ );
+ private void setSuggestionStripShown(boolean shown) {
+ setSuggestionStripShownInternal(shown, /* needsInputViewShown */true);
}
@Override
public void onComputeInsets(InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
- final KeyboardView inputView = mKeyboardSwitcher.getInputView();
+ final KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView == null)
return;
final int containerHeight = mCandidateViewContainer.getHeight();
@@ -868,8 +880,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
- if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) {
- if (mKeyboardSwitcher.getInputView().handleBack()) {
+ if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getKeyboardView() != null) {
+ if (mKeyboardSwitcher.getKeyboardView().handleBack()) {
return true;
}
}
@@ -1005,14 +1017,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
private void onSettingsKeyPressed() {
- if (!isShowingOptionDialog()) {
- if (!mSettingsValues.mEnableShowSubtypeSettings) {
- showSubtypeSelectorAndSettings();
- } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) {
- showOptionsMenu();
- } else {
- launchSettings();
- }
+ if (isShowingOptionDialog())
+ return;
+ if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
+ showSubtypeSelectorAndSettings();
+ } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) {
+ showOptionsMenu();
+ } else {
+ launchSettings();
}
}
@@ -1221,7 +1233,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (!mHasUncommittedTypedChars) {
mHasUncommittedTypedChars = true;
mComposing.setLength(0);
- mRecorrection.saveWordInHistory(mWord, mBestWord);
+ mRecorrection.saveRecorrectionSuggestion(mWord, mBestWord);
mWord.reset();
clearSuggestions();
}
@@ -1356,7 +1368,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
commitTyped(getCurrentInputConnection());
mVoiceProxy.handleClose();
requestHideSelf(0);
- LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null)
inputView.closing();
}
@@ -1392,7 +1404,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (DEBUG) {
Log.d(TAG, "Switch to keyboard view.");
}
- View v = mKeyboardSwitcher.getInputView();
+ View v = mKeyboardSwitcher.getKeyboardView();
if (v != null) {
// Confirms that the keyboard view doesn't have parent view.
ViewParent p = v.getParent();
@@ -1401,7 +1413,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
setInputView(v);
}
- setCandidatesViewShown(isCandidateStripVisible());
+ setSuggestionStripShown(isCandidateStripVisible());
updateInputViewShown();
mHandler.postUpdateSuggestions();
}
@@ -1411,9 +1423,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
public void setSuggestions(SuggestedWords words) {
- if (mVoiceProxy.getAndResetIsShowingHint()) {
- setCandidatesView(mCandidateViewContainer);
- }
+// if (mVoiceProxy.getAndResetIsShowingHint()) {
+// setCandidatesView(mCandidateViewContainer);
+// }
if (mCandidateView != null) {
mCandidateView.setSuggestions(words);
@@ -1443,7 +1455,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
mSettingsValues.mWordSeparators);
SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
- mKeyboardSwitcher.getInputView(), word, prevWord);
+ mKeyboardSwitcher.getKeyboardView(), word, prevWord);
boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection();
final CharSequence typedWord = word.getTypedWord();
@@ -1464,14 +1476,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// in most cases, suggestion count is 1 when typed word's length is 1, but we do always
// need to clear the previous state when the user starts typing a word (i.e. typed word's
// length == 1).
- if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid
- || mCandidateView.isShowingAddToDictionaryHint()) {
- builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable);
- } else {
- final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
- if (previousSuggestions == mSettingsValues.mSuggestPuncList)
- return;
- builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ if (typedWord != null) {
+ if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid
+ || mCandidateView.isShowingAddToDictionaryHint()) {
+ builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(
+ correctionAvailable);
+ } else {
+ final SuggestedWords previousSuggestions = mCandidateView.getSuggestions();
+ if (previousSuggestions == mSettingsValues.mSuggestPuncList)
+ return;
+ builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ }
}
showSuggestions(builder.build(), typedWord);
}
@@ -1489,7 +1504,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
mBestWord = null;
}
- setCandidatesViewShown(isCandidateStripVisible());
+ setSuggestionStripShown(isCandidateStripVisible());
}
private boolean pickDefaultSuggestion(int separatorCode) {
@@ -1501,7 +1516,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (mBestWord != null && mBestWord.length() > 0) {
TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord, separatorCode);
mJustAccepted = true;
- pickSuggestion(mBestWord);
+ commitBestWord(mBestWord);
// Add the word to the auto dictionary if it's not a known word
addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED);
return true;
@@ -1548,7 +1563,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// a magic space even if it was a normal space. This is meant to help in case the user
// pressed space on purpose of displaying the suggestion strip punctuation.
final char primaryCode = suggestion.charAt(0);
- final int toLeft = (ic == null) ? 0 : ic.getTextBeforeCursor(1, 0).charAt(0);
+ final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : "";
+ final int toLeft = (ic == null || TextUtils.isEmpty(beforeText))
+ ? 0 : beforeText.charAt(0);
final boolean oldMagicSpace = mJustAddedMagicSpace;
if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true;
onCodeInput(primaryCode, new int[] { primaryCode },
@@ -1566,7 +1583,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mWord.reset();
}
mJustAccepted = true;
- pickSuggestion(suggestion);
+ commitBestWord(suggestion);
// Add the word to the auto dictionary if it's not a known word
if (index == 0) {
addToAutoAndUserBigramDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED);
@@ -1602,12 +1619,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// TextEntryState.State.PICKED_SUGGESTION state.
TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true,
WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
- // From there on onUpdateSelection() will fire so suggestions will be updated
- } else if (!showingAddToDictionaryHint) {
+ }
+ if (!showingAddToDictionaryHint) {
// If we're not showing the "Touch again to save", then show corrections again.
// In case the cursor position doesn't change, make sure we show the suggestions again.
- clearSuggestions();
- mHandler.postUpdateOldSuggestions();
+ updateBigramPredictions();
+ // Updating the predictions right away may be slow and feel unresponsive on slower
+ // terminals. On the other hand if we just postUpdateBigramPredictions() it will
+ // take a noticeable delay to update them which may feel uneasy.
}
if (showingAddToDictionaryHint) {
mCandidateView.showAddToDictionaryHint(suggestion);
@@ -1620,25 +1639,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
/**
* Commits the chosen word to the text field and saves it for later
* retrieval.
- * @param suggestion the suggestion picked by the user to be committed to
- * the text field
*/
- private void pickSuggestion(CharSequence suggestion) {
+ private void commitBestWord(CharSequence bestWord) {
KeyboardSwitcher switcher = mKeyboardSwitcher;
if (!switcher.isKeyboardAvailable())
return;
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
- mVoiceProxy.rememberReplacedWord(suggestion, mSettingsValues.mWordSeparators);
- ic.commitText(suggestion, 1);
+ mVoiceProxy.rememberReplacedWord(bestWord, mSettingsValues.mWordSeparators);
+ SuggestedWords suggestedWords = mCandidateView.getSuggestions();
+ ic.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
+ this, bestWord, suggestedWords), 1);
}
- mRecorrection.saveWordInHistory(mWord, suggestion);
+ mRecorrection.saveRecorrectionSuggestion(mWord, bestWord);
mHasUncommittedTypedChars = false;
- mCommittedLength = suggestion.length();
+ mCommittedLength = bestWord.length();
}
private static final WordComposer sEmptyWordComposer = new WordComposer();
- private void updateBigramPredictions() {
+ public void updateBigramPredictions() {
if (mSuggest == null || !isSuggestionsRequested())
return;
@@ -1650,7 +1669,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(),
mSettingsValues.mWordSeparators);
SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
- mKeyboardSwitcher.getInputView(), sEmptyWordComposer, prevWord);
+ mKeyboardSwitcher.getKeyboardView(), sEmptyWordComposer, prevWord);
if (builder.size() > 0) {
// Explicitly supply an empty typed word (the no-second-arg version of
@@ -1663,7 +1682,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
public void setPunctuationSuggestions() {
setSuggestions(mSettingsValues.mSuggestPuncList);
- setCandidatesViewShown(isCandidateStripVisible());
+ setSuggestionStripShown(isCandidateStripVisible());
}
private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) {
@@ -1872,7 +1891,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// if mAudioManager is null, we don't have the ringer state yet
// mAudioManager will be set by updateRingerMode
if (mAudioManager == null) {
- if (mKeyboardSwitcher.getInputView() != null) {
+ if (mKeyboardSwitcher.getKeyboardView() != null) {
updateRingerMode();
}
}
@@ -1899,7 +1918,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
if (!mSettingsValues.mVibrateOn) {
return;
}
- LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+ LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) {
inputView.performHapticFeedback(
HapticFeedbackConstants.KEYBOARD_TAP,
@@ -1907,18 +1926,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
- public void promoteToUserDictionary(String word, int frequency) {
- if (mUserDictionary.isValidWord(word)) return;
- mUserDictionary.addWord(word, frequency);
- }
-
public WordComposer getCurrentWord() {
return mWord;
}
- public boolean getPopupOn() {
- return mSettingsValues.mPopupOn;
- }
boolean isSoundOn() {
return mSettingsValues.mSoundOn && !mSilentModeOn;
}
@@ -2026,7 +2037,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private void showOptionsMenuInternal(CharSequence title, CharSequence[] items,
DialogInterface.OnClickListener listener) {
- final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken();
+ final IBinder windowToken = mKeyboardSwitcher.getKeyboardView().getWindowToken();
if (windowToken == null) return;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
@@ -2062,7 +2073,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
p.println(" TextEntryState.state=" + TextEntryState.getState());
p.println(" mSoundOn=" + mSettingsValues.mSoundOn);
p.println(" mVibrateOn=" + mSettingsValues.mVibrateOn);
- p.println(" mPopupOn=" + mSettingsValues.mPopupOn);
+ p.println(" mKeyPreviewPopupOn=" + mSettingsValues.mKeyPreviewPopupOn);
}
// Characters per second measurement
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 5eb365774..956c51e06 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -56,7 +56,7 @@ public class Settings extends PreferenceActivity
public static final String PREF_GENERAL_SETTINGS_KEY = "general_settings";
public static final String PREF_VIBRATE_ON = "vibrate_on";
public static final String PREF_SOUND_ON = "sound_on";
- public static final String PREF_POPUP_ON = "popup_on";
+ public static final String PREF_KEY_PREVIEW_POPUP_ON = "popup_on";
public static final String PREF_RECORRECTION_ENABLED = "recorrection_enabled";
public static final String PREF_AUTO_CAP = "auto_cap";
public static final String PREF_SETTINGS_KEY = "settings_key";
@@ -77,6 +77,9 @@ public class Settings extends PreferenceActivity
public static final String PREF_MISC_SETTINGS_KEY = "misc_settings";
+ public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
+ "pref_key_preview_popup_dismiss_delay";
+
public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
// Dialog ids
@@ -84,7 +87,6 @@ public class Settings extends PreferenceActivity
public static class Values {
// From resources:
- public final boolean mEnableShowSubtypeSettings;
public final boolean mSwipeDownDismissKeyboardEnabled;
public final int mDelayBeforeFadeoutLanguageOnSpacebar;
public final int mDelayUpdateSuggestions;
@@ -102,7 +104,8 @@ public class Settings extends PreferenceActivity
// From preferences:
public final boolean mSoundOn; // Sound setting private to Latin IME (see mSilentModeOn)
public final boolean mVibrateOn;
- public final boolean mPopupOn; // Warning : this escapes through LatinIME#isPopupOn
+ public final boolean mKeyPreviewPopupOn;
+ public final int mKeyPreviewPopupDismissDelay;
public final boolean mAutoCap;
public final boolean mQuickFixes;
public final boolean mAutoCorrectEnabled;
@@ -117,15 +120,13 @@ public class Settings extends PreferenceActivity
final Resources res = context.getResources();
final Locale savedLocale;
if (null != localeStr) {
- final Locale keyboardLocale = new Locale(localeStr);
+ final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
savedLocale = Utils.setSystemLocale(res, keyboardLocale);
} else {
savedLocale = null;
}
// Get the resources
- mEnableShowSubtypeSettings = res.getBoolean(
- R.bool.config_enable_show_subtype_settings);
mSwipeDownDismissKeyboardEnabled = res.getBoolean(
R.bool.config_swipe_down_dismiss_keyboard_enabled);
mDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger(
@@ -161,7 +162,8 @@ public class Settings extends PreferenceActivity
mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
res.getBoolean(R.bool.config_default_sound_enabled));
- mPopupOn = isPopupEnabled(prefs, res);
+ mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
+ mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res);
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
mQuickFixes = isQuickFixesEnabled(prefs, res);
@@ -172,6 +174,8 @@ public class Settings extends PreferenceActivity
&& isBigramPredictionEnabled(prefs, res);
mAutoCorrectionThreshold = getAutoCorrectionThreshold(prefs, res);
+
+ Utils.setSystemLocale(res, savedLocale);
}
public boolean isSuggestedPunctuation(int code) {
@@ -200,6 +204,7 @@ public class Settings extends PreferenceActivity
return sp.getBoolean(Settings.PREF_QUICK_FIXES, resources.getBoolean(
R.bool.config_default_quick_fixes));
}
+
private static boolean isAutoCorrectEnabled(SharedPreferences sp, Resources resources) {
final String currentAutoCorrectionSetting = sp.getString(
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
@@ -208,13 +213,24 @@ public class Settings extends PreferenceActivity
R.string.auto_correction_threshold_mode_index_off);
return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
}
- private static boolean isPopupEnabled(SharedPreferences sp, Resources resources) {
+
+ // Public to access from KeyboardSwitcher. Should it have access to some
+ // process-global instance instead?
+ public static boolean isKeyPreviewPopupEnabled(SharedPreferences sp, Resources resources) {
final boolean showPopupOption = resources.getBoolean(
R.bool.config_enable_show_popup_on_keypress_option);
if (!showPopupOption) return resources.getBoolean(R.bool.config_default_popup_preview);
- return sp.getBoolean(Settings.PREF_POPUP_ON,
+ return sp.getBoolean(Settings.PREF_KEY_PREVIEW_POPUP_ON,
resources.getBoolean(R.bool.config_default_popup_preview));
}
+
+ // Likewise
+ public static int getKeyPreviewPopupDismissDelay(SharedPreferences sp,
+ Resources resources) {
+ return Integer.parseInt(sp.getString(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Integer.toString(resources.getInteger(R.integer.config_delay_after_preview))));
+ }
+
private static boolean isBigramSuggestionEnabled(SharedPreferences sp, Resources resources,
boolean autoCorrectEnabled) {
final boolean showBigramSuggestionsOption = resources.getBoolean(
@@ -225,11 +241,13 @@ public class Settings extends PreferenceActivity
return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, resources.getBoolean(
R.bool.config_default_bigram_suggestions));
}
+
private static boolean isBigramPredictionEnabled(SharedPreferences sp,
Resources resources) {
return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, resources.getBoolean(
R.bool.config_default_bigram_prediction));
}
+
private static double getAutoCorrectionThreshold(SharedPreferences sp,
Resources resources) {
final String currentAutoCorrectionSetting = sp.getString(
@@ -255,6 +273,7 @@ public class Settings extends PreferenceActivity
}
return autoCorrectionThreshold;
}
+
private static SuggestedWords createSuggestPuncList(final String puncs) {
SuggestedWords.Builder builder = new SuggestedWords.Builder();
if (puncs != null) {
@@ -272,6 +291,7 @@ public class Settings extends PreferenceActivity
private ListPreference mSettingsKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThreshold;
+ private ListPreference mKeyPreviewPopupDismissDelay;
// Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
private CheckBoxPreference mBigramSuggestion;
// Prediction: use bigrams to predict the next word when there is no input for it yet
@@ -297,6 +317,8 @@ public class Settings extends PreferenceActivity
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ final Resources res = getResources();
+
addPreferencesFromResource(R.xml.prefs);
mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES);
mInputLanguageSelection.setOnPreferenceClickListener(this);
@@ -329,16 +351,14 @@ public class Settings extends PreferenceActivity
(PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY);
final PreferenceGroup textCorrectionGroup =
(PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY);
- final PreferenceGroup bigramGroup =
- (PreferenceGroup) findPreference(PREF_NGRAM_SETTINGS_KEY);
- final boolean showSettingsKeyOption = getResources().getBoolean(
+ final boolean showSettingsKeyOption = res.getBoolean(
R.bool.config_enable_show_settings_key_option);
if (!showSettingsKeyOption) {
generalSettings.removePreference(mSettingsKeyPreference);
}
- final boolean showVoiceKeyOption = getResources().getBoolean(
+ final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
if (!showVoiceKeyOption) {
generalSettings.removePreference(mVoicePreference);
@@ -348,43 +368,57 @@ public class Settings extends PreferenceActivity
generalSettings.removePreference(findPreference(PREF_VIBRATE_ON));
}
- final boolean showSubtypeSettings = getResources().getBoolean(
- R.bool.config_enable_show_subtype_settings);
- if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED
- && !showSubtypeSettings) {
+ if (InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED) {
generalSettings.removePreference(findPreference(PREF_SUBTYPES));
}
- final boolean showPopupOption = getResources().getBoolean(
+ final boolean showPopupOption = res.getBoolean(
R.bool.config_enable_show_popup_on_keypress_option);
if (!showPopupOption) {
- generalSettings.removePreference(findPreference(PREF_POPUP_ON));
+ generalSettings.removePreference(findPreference(PREF_KEY_PREVIEW_POPUP_ON));
}
- final boolean showRecorrectionOption = getResources().getBoolean(
+ final boolean showRecorrectionOption = res.getBoolean(
R.bool.config_enable_show_recorrection_option);
if (!showRecorrectionOption) {
generalSettings.removePreference(findPreference(PREF_RECORRECTION_ENABLED));
}
- final boolean showQuickFixesOption = getResources().getBoolean(
+ final boolean showQuickFixesOption = res.getBoolean(
R.bool.config_enable_quick_fixes_option);
if (!showQuickFixesOption) {
textCorrectionGroup.removePreference(findPreference(PREF_QUICK_FIXES));
}
- final boolean showBigramSuggestionsOption = getResources().getBoolean(
+ final boolean showBigramSuggestionsOption = res.getBoolean(
R.bool.config_enable_bigram_suggestions_option);
if (!showBigramSuggestionsOption) {
textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_SUGGESTIONS));
textCorrectionGroup.removePreference(findPreference(PREF_BIGRAM_PREDICTIONS));
}
- final boolean showUsabilityModeStudyOption = getResources().getBoolean(
+ final boolean showUsabilityModeStudyOption = res.getBoolean(
R.bool.config_enable_usability_study_mode_option);
if (!showUsabilityModeStudyOption) {
getPreferenceScreen().removePreference(findPreference(PREF_USABILITY_STUDY_MODE));
}
+
+ mKeyPreviewPopupDismissDelay =
+ (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
+ final String[] entries = new String[] {
+ res.getString(R.string.key_preview_popup_dismiss_no_delay),
+ res.getString(R.string.key_preview_popup_dismiss_default_delay),
+ };
+ final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
+ R.integer.config_delay_after_preview));
+ mKeyPreviewPopupDismissDelay.setEntries(entries);
+ mKeyPreviewPopupDismissDelay.setEntryValues(
+ new String[] { "0", popupDismissDelayDefaultValue });
+ if (null == mKeyPreviewPopupDismissDelay.getValue()) {
+ mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
+ }
+ mKeyPreviewPopupDismissDelay.setEnabled(
+ Settings.Values.isKeyPreviewPopupEnabled(prefs, res));
}
@Override
@@ -403,6 +437,7 @@ public class Settings extends PreferenceActivity
}
updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
}
@Override
@@ -421,6 +456,12 @@ public class Settings extends PreferenceActivity
.equals(mVoiceModeOff)) {
showVoiceConfirmation();
}
+ } else if (key.equals(PREF_KEY_PREVIEW_POPUP_ON)) {
+ final ListPreference popupDismissDelay =
+ (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
+ if (null != popupDismissDelay) {
+ popupDismissDelay.setEnabled(prefs.getBoolean(PREF_KEY_PREVIEW_POPUP_ON, true));
+ }
}
ensureConsistencyOfAutoCorrectionSettings();
mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff)
@@ -428,6 +469,7 @@ public class Settings extends PreferenceActivity
updateVoiceModeSummary();
updateSettingsKeySummary();
updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
}
@Override
@@ -454,6 +496,11 @@ public class Settings extends PreferenceActivity
[mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]);
}
+ private void updateKeyPreviewPopupDelaySummary() {
+ final ListPreference lp = mKeyPreviewPopupDismissDelay;
+ lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]);
+ }
+
private void showVoiceConfirmation() {
mOkClicked = false;
showDialog(VOICE_INPUT_CONFIRM_DIALOG);
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index d8012087b..8b51af880 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -92,10 +92,9 @@ public class SubtypeSwitcher {
}
public static void init(LatinIME service, SharedPreferences prefs) {
+ SubtypeLocale.init(service);
sInstance.initialize(service, prefs);
sInstance.updateAllParameters();
-
- SubtypeLocale.init(service);
}
private SubtypeSwitcher() {
@@ -281,14 +280,8 @@ public class SubtypeSwitcher {
// "en_US" --> language: en & country: US
// "en" --> language: en
// "" --> the system locale
- mLocaleSplitter.setString(inputLocaleStr);
- if (mLocaleSplitter.hasNext()) {
- String language = mLocaleSplitter.next();
- if (mLocaleSplitter.hasNext()) {
- mInputLocale = new Locale(language, mLocaleSplitter.next());
- } else {
- mInputLocale = new Locale(language);
- }
+ if (!TextUtils.isEmpty(inputLocaleStr)) {
+ mInputLocale = Utils.constructLocaleFromString(inputLocaleStr);
mInputLocaleStr = inputLocaleStr;
} else {
mInputLocale = mSystemLocale;
@@ -420,7 +413,7 @@ public class SubtypeSwitcher {
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
final LatinKeyboard keyboard = switcher.getLatinKeyboard();
if (keyboard != null) {
- keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getInputView());
+ keyboard.updateShortcutKey(isShortcutImeReady(), switcher.getKeyboardView());
}
}
@@ -510,7 +503,7 @@ public class SubtypeSwitcher {
private void triggerVoiceIME() {
if (!mService.isInputViewShown()) return;
VoiceProxy.getInstance().startListening(false,
- KeyboardSwitcher.getInstance().getInputView().getWindowToken());
+ KeyboardSwitcher.getInstance().getKeyboardView().getWindowToken());
}
//////////////////////////////////////
@@ -549,12 +542,12 @@ public class SubtypeSwitcher {
|| mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return;
mCurrentKeyboardSubtypeIndex = getCurrentIndex();
mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex);
- Locale locale = new Locale(mNextKeyboardSubtype.getLocale());
- mNextLanguage = getDisplayLanguage(locale);
+ Locale locale = Utils.constructLocaleFromString(mNextKeyboardSubtype.getLocale());
+ mNextLanguage = getFullDisplayName(locale, true);
mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal(
mCurrentKeyboardSubtypeIndex);
- locale = new Locale(mPreviousKeyboardSubtype.getLocale());
- mPreviousLanguage = getDisplayLanguage(locale);
+ locale = Utils.constructLocaleFromString(mPreviousKeyboardSubtype.getLocale());
+ mPreviousLanguage = getFullDisplayName(locale, true);
}
private int normalize(int index) {
@@ -591,11 +584,12 @@ public class SubtypeSwitcher {
}
public static String getDisplayLanguage(Locale locale) {
- return toTitleCase(locale.getDisplayLanguage(locale));
+ return toTitleCase(SubtypeLocale.getFullDisplayName(locale));
}
public static String getMiddleDisplayLanguage(Locale locale) {
- return toTitleCase((new Locale(locale.getLanguage()).getDisplayLanguage(locale)));
+ return toTitleCase((Utils.constructLocaleFromString(
+ locale.getLanguage()).getDisplayLanguage(locale)));
}
public static String getShortDisplayLanguage(Locale locale) {
diff --git a/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
new file mode 100644
index 000000000..4a3f42d5d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.android.inputmethod.compat.SuggestionSpanUtils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+public class SuggestionSpanPickedNotificationReceiver extends BroadcastReceiver {
+ private static final boolean DBG = LatinImeLogger.sDBG;
+ private static final String TAG =
+ SuggestionSpanPickedNotificationReceiver.class.getSimpleName();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (SuggestionSpanUtils.ACTION_SUGGESTION_PICKED.equals(intent.getAction())) {
+ if (DBG) {
+ final String before = intent.getStringExtra(
+ SuggestionSpanUtils.SUGGESTION_SPAN_PICKED_BEFORE);
+ final String after = intent.getStringExtra(
+ SuggestionSpanUtils.SUGGESTION_SPAN_PICKED_AFTER);
+ Log.d(TAG, "Received notification picked: " + before + "," + after);
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
index a32a6461a..5b615ca29 100644
--- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBigramDictionary.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Google Inc.
+ * Copyright (C) 2010 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
@@ -158,7 +158,7 @@ public class UserBigramDictionary extends ExpandableDictionary {
* Pair will be added to the userbigram database.
*/
public int addBigrams(String word1, String word2) {
- // remove caps
+ // remove caps if second word is autocapitalized
if (mIme != null && mIme.getCurrentWord().isAutoCapitalized()) {
word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1);
}
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index d165de32d..6bdc0a857 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.compat.InputMethodInfoCompatWrapper;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
@@ -43,7 +44,10 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
public class Utils {
@@ -108,7 +112,34 @@ public class Utils {
}
public static boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManagerCompatWrapper imm) {
- return imm.getEnabledInputMethodList().size() > 1
+ final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList();
+
+ // Filters out IMEs that have auxiliary subtypes only (including either implicitly or
+ // explicitly enabled ones).
+ final ArrayList<InputMethodInfoCompatWrapper> filteredImis =
+ new ArrayList<InputMethodInfoCompatWrapper>();
+
+ outerloop:
+ for (InputMethodInfoCompatWrapper imi : enabledImis) {
+ // We can return true immediately after we find two or more filtered IMEs.
+ if (filteredImis.size() > 1) return true;
+ final List<InputMethodSubtypeCompatWrapper> subtypes =
+ imm.getEnabledInputMethodSubtypeList(imi, true);
+ // IMEs that have no subtypes should be included.
+ if (subtypes.isEmpty()) {
+ filteredImis.add(imi);
+ continue;
+ }
+ // IMEs that have one or more non-auxiliary subtypes should be included.
+ for (InputMethodSubtypeCompatWrapper subtype : subtypes) {
+ if (!subtype.isAuxiliary()) {
+ filteredImis.add(imi);
+ continue outerloop;
+ }
+ }
+ }
+
+ return filteredImis.size() > 1
// imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
// input method subtype (The current IME should be LatinIME.)
|| imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
@@ -537,8 +568,6 @@ public class Utils {
return KeyboardId.MODE_IM;
} else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
return KeyboardId.MODE_TEXT;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
- return KeyboardId.MODE_WEB;
} else {
return KeyboardId.MODE_TEXT;
}
@@ -662,4 +691,28 @@ public class Utils {
res.updateConfiguration(conf, res.getDisplayMetrics());
return saveLocale;
}
+
+ private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>();
+
+ public static Locale constructLocaleFromString(String localeStr) {
+ if (localeStr == null)
+ return null;
+ synchronized (sLocaleCache) {
+ if (sLocaleCache.containsKey(localeStr))
+ return sLocaleCache.get(localeStr);
+ Locale retval = null;
+ String[] localeParams = localeStr.split("_", 3);
+ if (localeParams.length == 1) {
+ retval = new Locale(localeParams[0]);
+ } else if (localeParams.length == 2) {
+ retval = new Locale(localeParams[0], localeParams[1]);
+ } else if (localeParams.length == 3) {
+ retval = new Locale(localeParams[0], localeParams[1], localeParams[2]);
+ }
+ if (retval != null) {
+ sLocaleCache.put(localeStr, retval);
+ }
+ return retval;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
index 2389d4e3c..4377373d2 100644
--- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
+++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
@@ -39,6 +39,7 @@ public class WhitelistDictionary extends Dictionary {
public static WhitelistDictionary init(Context context) {
synchronized (sInstance) {
if (context != null) {
+ // Wordlist is initialized by the proper language in Suggestion.java#init
sInstance.initWordlist(
context.getResources().getStringArray(R.array.wordlist_whitelist));
} else {
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index cf0592920..af5e4b179 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -62,7 +62,7 @@ public class WordComposer {
mYCoordinates = new int[N];
}
- WordComposer(WordComposer source) {
+ public WordComposer(WordComposer source) {
init(source);
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
new file mode 100644
index 000000000..e3407a269
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellChecker.java
@@ -0,0 +1,114 @@
+/*
+ * 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.spellcheck;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.Dictionary.DataType;
+import com.android.inputmethod.latin.Dictionary.WordCallback;
+import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Implements spell checking methods.
+ */
+public class SpellChecker {
+
+ public final Dictionary mDictionary;
+
+ public SpellChecker(final Context context, final Locale locale) {
+ final Resources resources = context.getResources();
+ final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ mDictionary = DictionaryFactory.createDictionaryFromManager(context, locale,
+ fallbackResourceId);
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Finds out whether a word is in the dictionary or not.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return true if the word is in the dictionary, false otherwise.
+ */
+ public boolean isCorrect(final CharSequence text, final int start, final int end) {
+ return mDictionary.isValidWord(text.subSequence(start, end));
+ }
+
+ private static class SuggestionsGatherer implements WordCallback {
+ private final int DEFAULT_SUGGESTION_LENGTH = 16;
+ private final List<String> mSuggestions = new LinkedList<String>();
+ private int[] mScores = new int[DEFAULT_SUGGESTION_LENGTH];
+ private int mLength = 0;
+
+ synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
+ int dicTypeId, DataType dataType) {
+ if (mLength >= mScores.length) {
+ final int newLength = mScores.length * 2;
+ mScores = new int[newLength];
+ }
+ final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score);
+ // binarySearch returns the index if the element exists, and -<insertion index> - 1
+ // if it doesn't. See documentation for binarySearch.
+ final int insertionIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+ System.arraycopy(mScores, insertionIndex, mScores, insertionIndex + 1,
+ mLength - insertionIndex);
+ mLength += 1;
+ mScores[insertionIndex] = score;
+ mSuggestions.add(insertionIndex, new String(word, wordOffset, wordLength));
+ return true;
+ }
+
+ public List<String> getGatheredSuggestions() {
+ return mSuggestions;
+ }
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Gets a list of suggestions for a specific string.
+ *
+ * This returns a list of possible corrections for the text passed as an
+ * arguments. It may split or group words, and even perform grammatical
+ * analysis.
+ *
+ * @param text the sequence containing the word to check for.
+ * @param start the index of the first character of the word in text.
+ * @param end the index of the next-to-last character in text.
+ * @return a list of possible suggestions to replace the text.
+ */
+ public List<String> getSuggestions(final CharSequence text, final int start, final int end) {
+ final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer();
+ final WordComposer composer = new WordComposer();
+ for (int i = start; i < end; ++i) {
+ int character = text.charAt(i);
+ composer.add(character, new int[] { character },
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
+ }
+ mDictionary.getWords(composer, suggestionsGatherer);
+ return suggestionsGatherer.getGatheredSuggestions();
+ }
+}