Merge remote-tracking branch 'goog/master' into merge

Conflicts:
	java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java

Change-Id: Iba0f2202bc2561f29b850dc22e9de52f84943a9c
main
satok 2011-04-14 13:47:25 +09:00
commit 7c06332be2
20 changed files with 150 additions and 223 deletions

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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 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.
*/
-->
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
>
<alpha
android:fromAlpha="0.5"
android:toAlpha="1.0"
android:duration="@integer/config_preview_fadein_anim_time" />
</set>

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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 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.
*/
-->
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="@integer/config_preview_fadeout_anim_time" />
</set>

View File

@ -25,5 +25,5 @@
<alpha <alpha
android:fromAlpha="0.5" android:fromAlpha="0.5"
android:toAlpha="1.0" android:toAlpha="1.0"
android:duration="@integer/config_preview_fadein_anim_time" /> android:duration="@integer/config_mini_keyboard_fadein_anim_time" />
</set> </set>

View File

@ -25,5 +25,5 @@
<alpha <alpha
android:fromAlpha="1.0" android:fromAlpha="1.0"
android:toAlpha="0.0" android:toAlpha="0.0"
android:duration="@integer/config_preview_fadeout_anim_time" /> android:duration="@integer/config_mini_keyboard_fadeout_anim_time" />
</set> </set>

View File

@ -21,25 +21,33 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="bottom"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="@dimen/candidate_strip_minimum_height"
>
<!-- On tablets, the candidate strip is centered with horizontal paddings on both sides because
width of the landscape mode is too long for the candidate strip. This LinearLayout is
required to hold the paddings. -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="@dimen/candidate_strip_height"
android:background="@drawable/keyboard_suggest_strip_holo" android:background="@drawable/keyboard_suggest_strip_holo"
android:paddingRight="@dimen/candidate_strip_padding" android:paddingRight="@dimen/candidate_strip_padding"
android:paddingLeft="@dimen/candidate_strip_padding" android:paddingLeft="@dimen/candidate_strip_padding"
> >
<HorizontalScrollView <HorizontalScrollView
android:id="@+id/candidates_scroll_view" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="horizontal" android:fadingEdge="horizontal"
android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
android:scrollbars="none" android:scrollbars="none"
> >
<com.android.inputmethod.latin.CandidateView <com.android.inputmethod.latin.CandidateView
android:id="@+id/candidates" android:id="@+id/candidates"
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/candidate_strip_height" android:layout_height="match_parent" />
android:background="@drawable/keyboard_suggest_strip_holo" />
</HorizontalScrollView> </HorizontalScrollView>
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -21,25 +21,24 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="bottom"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/keyboard_suggest_strip" android:minHeight="@dimen/candidate_strip_minimum_height"
android:paddingRight="@dimen/candidate_strip_padding" android:paddingRight="@dimen/candidate_strip_padding"
android:paddingLeft="@dimen/candidate_strip_padding" android:paddingLeft="@dimen/candidate_strip_padding"
> >
<HorizontalScrollView <HorizontalScrollView
android:id="@+id/candidates_scroll_view" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="@dimen/candidate_strip_height"
android:layout_height="wrap_content" android:background="@drawable/keyboard_suggest_strip"
android:fadingEdge="horizontal" android:fadingEdge="horizontal"
android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length"
android:scrollbars="none" android:scrollbars="none"
> >
<com.android.inputmethod.latin.CandidateView <com.android.inputmethod.latin.CandidateView
android:id="@+id/candidates" android:id="@+id/candidates"
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/candidate_strip_height" android:layout_height="match_parent" />
android:background="@drawable/keyboard_suggest_strip" />
</HorizontalScrollView> </HorizontalScrollView>
</LinearLayout> </LinearLayout>

View File

@ -46,6 +46,9 @@
<dimen name="key_preview_offset_holo">8.0mm</dimen> <dimen name="key_preview_offset_holo">8.0mm</dimen>
<dimen name="candidate_strip_height">46dip</dimen> <dimen name="candidate_strip_height">46dip</dimen>
<!-- candidate_strip_minimum_height =
key_preview_height_holo - key_preview_offset_holo + alpha -->
<dimen name="candidate_strip_minimum_height">18mm</dimen>
<dimen name="candidate_strip_padding">15.0mm</dimen> <dimen name="candidate_strip_padding">15.0mm</dimen>
<dimen name="candidate_min_width">0.3in</dimen> <dimen name="candidate_min_width">0.3in</dimen>
<dimen name="candidate_padding">12dip</dimen> <dimen name="candidate_padding">12dip</dimen>

View File

@ -49,8 +49,6 @@
<integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer> <integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer>
<integer name="config_delay_before_preview">0</integer> <integer name="config_delay_before_preview">0</integer>
<integer name="config_delay_after_preview">10</integer> <integer name="config_delay_after_preview">10</integer>
<integer name="config_preview_fadein_anim_time">0</integer>
<integer name="config_preview_fadeout_anim_time">70</integer>
<integer name="config_mini_keyboard_fadein_anim_time">0</integer> <integer name="config_mini_keyboard_fadein_anim_time">0</integer>
<integer name="config_mini_keyboard_fadeout_anim_time">100</integer> <integer name="config_mini_keyboard_fadeout_anim_time">100</integer>
<integer name="config_delay_before_key_repeat_start">400</integer> <integer name="config_delay_before_key_repeat_start">400</integer>

View File

@ -52,6 +52,9 @@
<dimen name="key_preview_offset_holo">0.193in</dimen> <dimen name="key_preview_offset_holo">0.193in</dimen>
<dimen name="candidate_strip_height">42dip</dimen> <dimen name="candidate_strip_height">42dip</dimen>
<!-- candidate_strip_minimum_height =
key_preview_height_holo - key_preview_offset_holo + alpha -->
<dimen name="candidate_strip_minimum_height">100sp</dimen>
<dimen name="candidate_strip_fading_edge_length">63dip</dimen> <dimen name="candidate_strip_fading_edge_length">63dip</dimen>
<dimen name="candidate_strip_padding">0dip</dimen> <dimen name="candidate_strip_padding">0dip</dimen>
<dimen name="candidate_min_width">0.3in</dimen> <dimen name="candidate_min_width">0.3in</dimen>

View File

@ -35,10 +35,6 @@
<item name="backgroundDimAmount">0.5</item> <item name="backgroundDimAmount">0.5</item>
<item name="colorScheme">white</item> <item name="colorScheme">white</item>
</style> </style>
<style name="KeyPreviewAnimation">
<item name="android:windowEnterAnimation">@anim/key_preview_fadein</item>
<item name="android:windowExitAnimation">@anim/key_preview_fadeout</item>
</style>
<style name="MiniKeyboardAnimation"> <style name="MiniKeyboardAnimation">
<item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item> <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item>
<item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item> <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item>

View File

@ -107,7 +107,8 @@ public class InputMethodManagerCompatWrapper {
public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
if (!SUBTYPE_SUPPORTED) { if (!SUBTYPE_SUPPORTED) {
String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(); String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(
allowsImplicitlySelectedSubtypes);
List<InputMethodSubtypeCompatWrapper> subtypeList = List<InputMethodSubtypeCompatWrapper> subtypeList =
new ArrayList<InputMethodSubtypeCompatWrapper>(); new ArrayList<InputMethodSubtypeCompatWrapper>();
for (String lang: languages) { for (String lang: languages) {
@ -195,10 +196,6 @@ public class InputMethodManagerCompatWrapper {
public void setInputMethodAndSubtype( public void setInputMethodAndSubtype(
IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) {
if (!SUBTYPE_SUPPORTED) {
mLanguageSwitcherProxy.setLocale(subtype.getLocale());
return;
}
CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype,
token, id, subtype.getOriginalObject()); token, id, subtype.getOriginalObject());
} }

View File

@ -16,23 +16,13 @@
package com.android.inputmethod.compat; package com.android.inputmethod.compat;
import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.SubtypeSwitcher;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.view.View;
// import android.view.inputmethod.InputMethodSubtype; // import android.view.inputmethod.InputMethodSubtype;
import android.widget.HorizontalScrollView;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class InputMethodServiceCompatWrapper extends InputMethodService { public class InputMethodServiceCompatWrapper extends InputMethodService {
private static final Method METHOD_HorizontalScrollView_setOverScrollMode =
CompatUtils.getMethod(HorizontalScrollView.class, "setOverScrollMode", int.class);
private static final Field FIELD_View_OVER_SCROLL_NEVER =
CompatUtils.getField(View.class, "OVER_SCROLL_NEVER");
private static final Integer View_OVER_SCROLL_NEVER =
(Integer)CompatUtils.getFieldValue(null, null, FIELD_View_OVER_SCROLL_NEVER);
// CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10 // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10
// or previous. Note that InputMethodSubtype was added in the API level 11. // or previous. Note that InputMethodSubtype was added in the API level 11.
// For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged(). // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged().
@ -62,17 +52,13 @@ public class InputMethodServiceCompatWrapper extends InputMethodService {
subtype = mImm.getCurrentInputMethodSubtype(); subtype = mImm.getCurrentInputMethodSubtype();
} }
if (subtype != null) { if (subtype != null) {
if (!InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) {
LanguageSwitcherProxy.getInstance().setLocale(subtype.getLocale());
}
SubtypeSwitcher.getInstance().updateSubtype(subtype); SubtypeSwitcher.getInstance().updateSubtype(subtype);
} }
} }
protected static void setOverScrollModeNever(HorizontalScrollView scrollView) {
if (View_OVER_SCROLL_NEVER != null) {
CompatUtils.invoke(scrollView, null, METHOD_HorizontalScrollView_setOverScrollMode,
View_OVER_SCROLL_NEVER);
}
}
////////////////////////////////////// //////////////////////////////////////
// Functions using API v11 or later // // Functions using API v11 or later //
////////////////////////////////////// //////////////////////////////////////

View File

@ -19,6 +19,7 @@ package com.android.inputmethod.deprecated;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher; import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.Settings;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
@ -26,7 +27,7 @@ import android.content.res.Configuration;
import java.util.Locale; import java.util.Locale;
// This class is used only when the IME doesn't use method.xml for language switching. // This class is used only when the IME doesn't use method.xml for language switching.
public class LanguageSwitcherProxy { public class LanguageSwitcherProxy implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy(); private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy();
private LanguageSwitcher mLanguageSwitcher; private LanguageSwitcher mLanguageSwitcher;
private SharedPreferences mPrefs; private SharedPreferences mPrefs;
@ -42,6 +43,7 @@ public class LanguageSwitcherProxy {
sInstance.mLanguageSwitcher = new LanguageSwitcher(service); sInstance.mLanguageSwitcher = new LanguageSwitcher(service);
sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale); sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale);
sInstance.mPrefs = prefs; sInstance.mPrefs = prefs;
prefs.registerOnSharedPreferenceChangeListener(sInstance);
} }
public static void onConfigurationChanged(Configuration conf) { public static void onConfigurationChanged(Configuration conf) {
@ -58,8 +60,8 @@ public class LanguageSwitcherProxy {
return mLanguageSwitcher.getLocaleCount(); return mLanguageSwitcher.getLocaleCount();
} }
public String[] getEnabledLanguages() { public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
return mLanguageSwitcher.getEnabledLanguages(); return mLanguageSwitcher.getEnabledLanguages(allowImplicitlySelectedLanguages);
} }
public Locale getInputLocale() { public Locale getInputLocale() {
@ -70,4 +72,14 @@ public class LanguageSwitcherProxy {
mLanguageSwitcher.setLocale(localeStr); mLanguageSwitcher.setLocale(localeStr);
mLanguageSwitcher.persist(mPrefs); mLanguageSwitcher.persist(mPrefs);
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// PREF_SELECTED_LANGUAGES: enabled input subtypes
// PREF_INPUT_LANGUAGE: current input subtype
if (key.equals(Settings.PREF_SELECTED_LANGUAGES)
|| key.equals(Settings.PREF_INPUT_LANGUAGE)) {
mLanguageSwitcher.loadLocales(prefs, null);
}
}
} }

View File

@ -18,6 +18,7 @@ package com.android.inputmethod.deprecated.languageswitcher;
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.Settings; import com.android.inputmethod.latin.Settings;
import com.android.inputmethod.latin.SharedPreferencesCompat; import com.android.inputmethod.latin.SharedPreferencesCompat;
@ -25,6 +26,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
@ -34,12 +36,14 @@ import java.util.Locale;
* input language that the user has selected. * input language that the user has selected.
*/ */
public class LanguageSwitcher { public class LanguageSwitcher {
private static final String TAG = LanguageSwitcher.class.getSimpleName();
private static final String KEYBOARD_MODE = "keyboard"; private static final String KEYBOARD_MODE = "keyboard";
private static final String[] EMPTY_STIRNG_ARRAY = new String[0];
private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); private final ArrayList<Locale> mLocales = new ArrayList<Locale>();
private final LatinIME mIme; private final LatinIME mIme;
private String[] mSelectedLanguageArray; private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
private String mSelectedLanguages; private String mSelectedLanguages;
private int mCurrentIndex = 0; private int mCurrentIndex = 0;
private String mDefaultInputLanguage; private String mDefaultInputLanguage;
@ -69,12 +73,16 @@ public class LanguageSwitcher {
* @return whether there was any change * @return whether there was any change
*/ */
public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { public boolean loadLocales(SharedPreferences sp, Locale systemLocale) {
if (LatinImeLogger.sDBG) {
Log.d(TAG, "load locales");
}
if (systemLocale != null) { if (systemLocale != null) {
setSystemLocale(systemLocale); setSystemLocale(systemLocale);
} }
String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null);
String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null);
if (selectedLanguages == null || selectedLanguages.length() < 1) { if (TextUtils.isEmpty(selectedLanguages)) {
mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
loadDefaults(); loadDefaults();
if (mLocales.size() == 0) { if (mLocales.size() == 0) {
return false; return false;
@ -104,6 +112,9 @@ public class LanguageSwitcher {
} }
private void loadDefaults() { private void loadDefaults() {
if (LatinImeLogger.sDBG) {
Log.d(TAG, "load default locales:");
}
mDefaultInputLocale = mIme.getResources().getConfiguration().locale; mDefaultInputLocale = mIme.getResources().getConfiguration().locale;
String country = mDefaultInputLocale.getCountry(); String country = mDefaultInputLocale.getCountry();
mDefaultInputLanguage = mDefaultInputLocale.getLanguage() + mDefaultInputLanguage = mDefaultInputLocale.getLanguage() +
@ -132,7 +143,10 @@ public class LanguageSwitcher {
/** /**
* Returns the list of enabled language codes. * Returns the list of enabled language codes.
*/ */
public String[] getEnabledLanguages() { public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) {
return new String[] { mDefaultInputLanguage };
}
return mSelectedLanguageArray; return mSelectedLanguageArray;
} }
@ -218,9 +232,5 @@ public class LanguageSwitcher {
Editor editor = prefs.edit(); Editor editor = prefs.edit();
editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage());
SharedPreferencesCompat.apply(editor); SharedPreferencesCompat.apply(editor);
// When the current language is changed, the event for this change should be handled
// internally as a subtype switching.
mIme.notifyOnCurrentInputMethodSubtypeChanged(new InputMethodSubtypeCompatWrapper(
0, 0, getInputLocale().toString(), KEYBOARD_MODE, ""));
} }
} }

View File

@ -45,8 +45,8 @@ import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup;
import android.view.WindowManager; import android.widget.FrameLayout;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.TextView; import android.widget.TextView;
@ -110,14 +110,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// Key preview popup // Key preview popup
private boolean mInForeground; private boolean mInForeground;
private TextView mPreviewText; private TextView mPreviewText;
private PopupWindow mPreviewPopup;
private int mPreviewTextSizeLarge; private int mPreviewTextSizeLarge;
private int[] mOffsetInWindow; private final int[] mOffsetInWindow = new int[2];
private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY; private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY;
private boolean mShowPreview = true; private boolean mShowPreview = true;
private int mPopupPreviewOffsetX; private int mPopupPreviewOffsetX;
private int mPopupPreviewOffsetY; private int mPopupPreviewOffsetY;
private int mWindowY;
private int mPopupPreviewDisplayedY; private int mPopupPreviewDisplayedY;
private final int mDelayBeforePreview; private final int mDelayBeforePreview;
private final int mDelayAfterPreview; private final int mDelayAfterPreview;
@ -125,7 +123,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
// Popup mini keyboard // Popup mini keyboard
private PopupWindow mMiniKeyboardPopup; private PopupWindow mMiniKeyboardPopup;
private KeyboardView mMiniKeyboardView; private KeyboardView mMiniKeyboardView;
private View mMiniKeyboardParent;
private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>();
private int mMiniKeyboardOriginX; private int mMiniKeyboardOriginX;
private int mMiniKeyboardOriginY; private int mMiniKeyboardOriginY;
@ -204,7 +201,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
showKey(msg.arg1, (PointerTracker)msg.obj); showKey(msg.arg1, (PointerTracker)msg.obj);
break; break;
case MSG_DISMISS_PREVIEW: case MSG_DISMISS_PREVIEW:
mPreviewPopup.dismiss(); mPreviewText.setVisibility(View.INVISIBLE);
break; break;
case MSG_REPEAT_KEY: { case MSG_REPEAT_KEY: {
final PointerTracker tracker = (PointerTracker)msg.obj; final PointerTracker tracker = (PointerTracker)msg.obj;
@ -227,12 +224,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { public void popupPreview(long delay, int keyIndex, PointerTracker tracker) {
removeMessages(MSG_POPUP_PREVIEW); removeMessages(MSG_POPUP_PREVIEW);
if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { if (mPreviewText.getVisibility() == VISIBLE) {
// Show right away, if it's already visible and finger is moving around // Show right away, if it's already visible and finger is moving around
showKey(keyIndex, tracker); showKey(keyIndex, tracker);
} else { } else {
sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), delay);
delay);
} }
} }
@ -241,10 +237,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
public void dismissPreview(long delay) { public void dismissPreview(long delay) {
if (mPreviewPopup.isShowing()) {
sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay);
} }
}
public void cancelDismissPreview() { public void cancelDismissPreview() {
removeMessages(MSG_DISMISS_PREVIEW); removeMessages(MSG_DISMISS_PREVIEW);
@ -366,24 +360,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final Resources res = getResources(); final Resources res = getResources();
mPreviewPopup = new PopupWindow(context);
if (previewLayout != 0) { if (previewLayout != 0) {
mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null); mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null);
mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large);
mPreviewPopup.setContentView(mPreviewText);
mPreviewPopup.setBackgroundDrawable(null);
} else { } else {
mShowPreview = false; mShowPreview = false;
} }
mPreviewPopup.setTouchable(false);
mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
mPreviewPopup.setClippingEnabled(false);
mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview);
mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview);
mKeyLabelHorizontalPadding = (int)res.getDimension( mKeyLabelHorizontalPadding = (int)res.getDimension(
R.dimen.key_label_horizontal_alignment_padding); R.dimen.key_label_horizontal_alignment_padding);
mMiniKeyboardParent = this;
mMiniKeyboardPopup = new PopupWindow(context); mMiniKeyboardPopup = new PopupWindow(context);
mMiniKeyboardPopup.setBackgroundDrawable(null); mMiniKeyboardPopup.setBackgroundDrawable(null);
mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation);
@ -583,7 +570,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
public void setPopupOffset(int x, int y) { public void setPopupOffset(int x, int y) {
mPopupPreviewOffsetX = x; mPopupPreviewOffsetX = x;
mPopupPreviewOffsetY = y; mPopupPreviewOffsetY = y;
mPreviewPopup.dismiss();
} }
/** /**
@ -915,8 +901,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
} }
// TODO Must fix popup preview on xlarge layout // TODO: Introduce minimum duration for displaying key previews
// TODO: Display up to two key previews when the user presses two keys at the same time
private void showKey(final int keyIndex, PointerTracker tracker) { private void showKey(final int keyIndex, PointerTracker tracker) {
// If the preview popup has no parent view yet, add it to the screen FrameLayout.
if (mPreviewText.getParent() == null) {
final FrameLayout screenContent = (FrameLayout) getRootView()
.findViewById(android.R.id.content);
screenContent.addView(mPreviewText, new FrameLayout.LayoutParams(0, 0));
}
Key key = tracker.getKey(keyIndex); Key key = tracker.getKey(keyIndex);
// If keyIndex is invalid or IME is already closed, we must not show key preview. // If keyIndex is invalid or IME is already closed, we must not show key preview.
// Trying to show preview PopupWindow while root window is closed causes // Trying to show preview PopupWindow while root window is closed causes
@ -948,7 +942,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), keyDrawWidth int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), keyDrawWidth
+ mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
final int popupHeight = mPreviewHeight; final int popupHeight = mPreviewHeight;
LayoutParams lp = mPreviewText.getLayoutParams(); final ViewGroup.LayoutParams lp = mPreviewText.getLayoutParams();
if (lp != null) { if (lp != null) {
lp.width = popupWidth; lp.width = popupWidth;
lp.height = popupHeight; lp.height = popupHeight;
@ -958,47 +952,23 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
int popupPreviewY = key.mY - popupHeight + mPreviewOffset; int popupPreviewY = key.mY - popupHeight + mPreviewOffset;
mHandler.cancelDismissPreview(); mHandler.cancelDismissPreview();
if (mOffsetInWindow == null) {
mOffsetInWindow = new int[2];
getLocationInWindow(mOffsetInWindow); getLocationInWindow(mOffsetInWindow);
mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero
mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero
int[] windowLocation = new int[2];
getLocationOnScreen(windowLocation);
mWindowY = windowLocation[1];
}
// Set the preview background state // Set the preview background state
mPreviewText.getBackground().setState( mPreviewText.getBackground().setState(
key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
popupPreviewX += mOffsetInWindow[0]; popupPreviewX += mOffsetInWindow[0];
popupPreviewY += mOffsetInWindow[1]; popupPreviewY += mOffsetInWindow[1];
// If the popup cannot be shown above the key, put it on the side // Place the key preview.
if (popupPreviewY + mWindowY < 0) { // TODO: Adjust position of key previews which touch screen edges
// If the key you're pressing is on the left side of the keyboard, show the popup on if (lp instanceof ViewGroup.MarginLayoutParams) {
// the right, offset by enough to see at least one key to the left/right. ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp;
if (keyDrawX + keyDrawWidth <= getWidth() / 2) { mlp.setMargins(popupPreviewX, popupPreviewY, 0, 0);
popupPreviewX += (int) (keyDrawWidth * 2.5);
} else {
popupPreviewX -= (int) (keyDrawWidth * 2.5);
} }
popupPreviewY += popupHeight; // Record popup preview position to display mini-keyboard later at the same position
}
try {
if (mPreviewPopup.isShowing()) {
mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight);
} else {
mPreviewPopup.setWidth(popupWidth);
mPreviewPopup.setHeight(popupHeight);
mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
popupPreviewX, popupPreviewY);
}
} catch (WindowManager.BadTokenException e) {
// Swallow the exception which will be happened when IME is already closed.
Log.w(TAG, "LatinIME is already closed when tried showing key preview.");
}
// Record popup preview position to display mini-keyboard later at the same positon
mPopupPreviewDisplayedY = popupPreviewY; mPopupPreviewDisplayedY = popupPreviewY;
mPreviewText.setVisibility(VISIBLE); mPreviewText.setVisibility(VISIBLE);
} }
@ -1114,7 +1084,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(), final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(),
popupKey).build(); popupKey).build();
miniKeyboardView.setKeyboard(keyboard); miniKeyboardView.setKeyboard(keyboard);
miniKeyboardView.mMiniKeyboardParent = this;
container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
@ -1349,7 +1318,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
} }
public void closing() { public void closing() {
mPreviewPopup.dismiss(); mPreviewText.setVisibility(View.GONE);
mHandler.cancelAllMessages(); mHandler.cancelAllMessages();
dismissPopupKeyboard(); dismissPopupKeyboard();

View File

@ -549,7 +549,6 @@ public class PointerTracker {
final Key key = getKey(keyIndex); final Key key = getKey(keyIndex);
if (key != null && !key.mEnabled) if (key != null && !key.mEnabled)
return; return;
updateKeyGraphics(keyIndex);
// The modifier key, such as shift key, should not be shown as preview when multi-touch is // The modifier key, such as shift key, should not be shown as preview when multi-touch is
// supported. On the other hand, if multi-touch is not supported, the modifier key should // supported. On the other hand, if multi-touch is not supported, the modifier key should
// be shown as preview. If accessibility is turned on, the modifier key should be shown as // be shown as preview. If accessibility is turned on, the modifier key should be shown as
@ -559,6 +558,7 @@ public class PointerTracker {
} else { } else {
mProxy.showPreview(keyIndex, this); mProxy.showPreview(keyIndex, this);
} }
updateKeyGraphics(keyIndex);
} }
private void startLongPressTimer(int keyIndex) { private void startLongPressTimer(int keyIndex) {

View File

@ -133,7 +133,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.WRAP_CONTENT);
mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setContentView(mPreviewText);
mPreviewPopup.setBackgroundDrawable(null); mPreviewPopup.setBackgroundDrawable(null);
mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation);
mConfigCandidateHighlightFontColorEnabled = mConfigCandidateHighlightFontColorEnabled =
res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled); res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled);
mColorNormal = res.getColor(R.color.candidate_normal); mColorNormal = res.getColor(R.color.candidate_normal);

View File

@ -57,7 +57,6 @@ import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.PrintWriterPrinter; import android.util.PrintWriterPrinter;
import android.util.Printer; import android.util.Printer;
import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -71,8 +70,6 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import java.io.FileDescriptor; import java.io.FileDescriptor;
@ -144,6 +141,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}; };
private View mCandidateViewContainer; private View mCandidateViewContainer;
private int mCandidateStripHeight;
private CandidateView mCandidateView; private CandidateView mCandidateView;
private Suggest mSuggest; private Suggest mSuggest;
private CompletionInfo[] mApplicationSpecifiedCompletions; private CompletionInfo[] mApplicationSpecifiedCompletions;
@ -377,10 +375,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
mPrefs = prefs; mPrefs = prefs;
LatinImeLogger.init(this, prefs); LatinImeLogger.init(this, prefs);
LanguageSwitcherProxy.init(this, prefs);
SubtypeSwitcher.init(this, prefs); SubtypeSwitcher.init(this, prefs);
KeyboardSwitcher.init(this, prefs); KeyboardSwitcher.init(this, prefs);
AccessibilityUtils.init(this, prefs); AccessibilityUtils.init(this, prefs);
LanguageSwitcherProxy.init(this, prefs);
super.onCreate(); super.onCreate();
@ -533,12 +531,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LayoutInflater inflater = getLayoutInflater(); LayoutInflater inflater = getLayoutInflater();
LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null);
mCandidateViewContainer = container; mCandidateViewContainer = container;
if (container.getPaddingRight() != 0) { mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
HorizontalScrollView scrollView =
(HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view);
setOverScrollModeNever(scrollView);
container.setGravity(Gravity.CENTER_HORIZONTAL);
}
mCandidateView = (CandidateView) container.findViewById(R.id.candidates); mCandidateView = (CandidateView) container.findViewById(R.id.candidates);
mCandidateView.setService(this); mCandidateView.setService(this);
setCandidatesViewShown(true); setCandidatesViewShown(true);
@ -586,8 +579,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
switcher.updateShiftState(); switcher.updateShiftState();
} }
setCandidatesViewShownInternal(isCandidateStripVisible(), setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ );
false /* needsInputViewShown */ );
// Delay updating suggestions because keyboard input view may not be shown at this point. // Delay updating suggestions because keyboard input view may not be shown at this point.
mHandler.postUpdateSuggestions(); mHandler.postUpdateSuggestions();
@ -877,10 +869,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} }
private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) {
// TODO: Remove this if we support candidates with hard keyboard // TODO: Modify this if we support candidates with hard keyboard
if (onEvaluateInputViewShown()) { if (onEvaluateInputViewShown()) {
super.setCandidatesViewShown(shown final boolean shouldShowCandidates = shown
&& (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true);
if (isExtractViewShown()) {
// No need to have extra space to show the key preview.
mCandidateViewContainer.setMinimumHeight(0);
super.setCandidatesViewShown(shown);
} 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);
}
} }
} }
@ -892,35 +895,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
@Override @Override
public void onComputeInsets(InputMethodService.Insets outInsets) { public void onComputeInsets(InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets); super.onComputeInsets(outInsets);
if (!isFullscreenMode()) { final KeyboardView inputView = mKeyboardSwitcher.getInputView();
outInsets.contentTopInsets = outInsets.visibleTopInsets;
}
KeyboardView inputView = mKeyboardSwitcher.getInputView();
// Need to set touchable region only if input view is being shown // Need to set touchable region only if input view is being shown
if (inputView != null && mKeyboardSwitcher.isInputViewShown()) { if (inputView != null && mKeyboardSwitcher.isInputViewShown()) {
final int x = 0; final int containerHeight = mCandidateViewContainer.getHeight();
int y = 0; int touchY = containerHeight;
final int width = inputView.getWidth(); if (mCandidateViewContainer.getVisibility() == View.VISIBLE) {
int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT; touchY -= mCandidateStripHeight;
if (mCandidateViewContainer != null) {
ViewParent candidateParent = mCandidateViewContainer.getParent();
if (candidateParent instanceof FrameLayout) {
FrameLayout fl = (FrameLayout) candidateParent;
if (fl != null) {
// Check frame layout's visibility
if (fl.getVisibility() == View.INVISIBLE) {
y = fl.getHeight();
height += y;
} else if (fl.getVisibility() == View.VISIBLE) {
height += fl.getHeight();
}
}
}
} }
outInsets.contentTopInsets = touchY;
outInsets.visibleTopInsets = touchY;
final int touchWidth = inputView.getWidth();
final int touchHeight = inputView.getHeight() + containerHeight
// Extend touchable region below the keyboard.
+ EXTENDED_TOUCHABLE_REGION_HEIGHT;
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height); Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth
+ " height=" + touchHeight);
} }
setTouchableRegionCompat(outInsets, x, y, width, height); setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight);
} }
} }

View File

@ -138,13 +138,14 @@ static void prof_out(void) {
#define SUGGEST_WORDS_WITH_SPACE_PROXIMITY true #define SUGGEST_WORDS_WITH_SPACE_PROXIMITY true
// The following "rate"s are used as a multiplier before dividing by 100, so they are in percent. // The following "rate"s are used as a multiplier before dividing by 100, so they are in percent.
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 90 #define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 80
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X 12 #define WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X 12
#define WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE 80 #define WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE 80
#define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75 #define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75
#define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75 #define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75
#define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60 #define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60
#define FULL_MATCHED_WORDS_PROMOTION_RATE 120 #define FULL_MATCHED_WORDS_PROMOTION_RATE 120
#define WORDS_WITH_JUST_ONE_PROXIMITY_CHARACTER_PROMOTION_RATE 110
// This should be greater than or equal to MAX_WORD_LENGTH defined in BinaryDictionary.java // This should be greater than or equal to MAX_WORD_LENGTH defined in BinaryDictionary.java
// This is only used for the size of array. Not to be used in c functions. // This is only used for the size of array. Not to be used in c functions.

View File

@ -523,6 +523,9 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
* (10 * mInputLength - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X) * (10 * mInputLength - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X)
/ (10 * mInputLength / (10 * mInputLength
- WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10); - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10);
if (DEBUG_DICT) {
LOGI("Demotion rate for missing character is %d.", demotionRate);
}
multiplyRate(demotionRate, &finalFreq); multiplyRate(demotionRate, &finalFreq);
} else { } else {
finalFreq = 0; finalFreq = 0;
@ -539,6 +542,7 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
int lengthFreq = TYPED_LETTER_MULTIPLIER; int lengthFreq = TYPED_LETTER_MULTIPLIER;
for (int i = 0; i < depth; ++i) lengthFreq *= TYPED_LETTER_MULTIPLIER; for (int i = 0; i < depth; ++i) lengthFreq *= TYPED_LETTER_MULTIPLIER;
if (lengthFreq == matchWeight) { if (lengthFreq == matchWeight) {
// Full exact match
if (depth > 1) { if (depth > 1) {
if (DEBUG_DICT) { if (DEBUG_DICT) {
LOGI("Found full matched word."); LOGI("Found full matched word.");
@ -548,6 +552,13 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
if (sameLength && transposedPos < 0 && skipPos < 0 && excessivePos < 0) { if (sameLength && transposedPos < 0 && skipPos < 0 && excessivePos < 0) {
finalFreq = capped255MultForFullMatchAccentsOrCapitalizationDifference(finalFreq); finalFreq = capped255MultForFullMatchAccentsOrCapitalizationDifference(finalFreq);
} }
} else if (lengthFreq / 2 == matchWeight && transposedPos < 0 && skipPos < 0
&& excessivePos < 0 && depth > 1) {
// Full match except only one proximity correction
if (DEBUG_DICT) {
LOGI("Found one proximity correction.");
}
multiplyRate(WORDS_WITH_JUST_ONE_PROXIMITY_CHARACTER_PROMOTION_RATE, &finalFreq);
} }
if (sameLength) finalFreq *= FULL_WORD_MULTIPLIER; if (sameLength) finalFreq *= FULL_WORD_MULTIPLIER;
return finalFreq; return finalFreq;