am f429d8f1: Merge "[ML1] Introduce RichInputMethodSubtype"
* commit 'f429d8f138d7e9aed8cdae774bfc8854025d3a40': [ML1] Introduce RichInputMethodSubtypemain
commit
543efa296e
|
@ -121,7 +121,7 @@ public final class MainKeyboardAccessibilityDelegate
|
|||
*/
|
||||
private void announceKeyboardLanguage(final Keyboard keyboard) {
|
||||
final String languageText = SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(
|
||||
keyboard.mId.mSubtype);
|
||||
keyboard.mId.mSubtype.getRawSubtype());
|
||||
sendWindowStateChanged(languageText);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.os.Build;
|
|||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -64,9 +64,12 @@ public final class InputMethodSubtypeCompatUtils {
|
|||
overridesImplicitlyEnabledSubtype, id);
|
||||
}
|
||||
|
||||
public static boolean isAsciiCapable(final RichInputMethodSubtype subtype) {
|
||||
return isAsciiCapable(subtype.getRawSubtype());
|
||||
}
|
||||
|
||||
public static boolean isAsciiCapable(final InputMethodSubtype subtype) {
|
||||
return isAsciiCapableWithAPI(subtype)
|
||||
|| subtype.containsExtraValueKey(Constants.Subtype.ExtraValue.ASCII_CAPABLE);
|
||||
return InputMethodSubtypeCompatUtils.isAsciiCapableWithAPI(subtype);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
|
|
|
@ -21,9 +21,9 @@ import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOAR
|
|||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.compat.EditorInfoCompatUtils;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.utils.InputTypeUtils;
|
||||
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
|
@ -62,7 +62,7 @@ public final class KeyboardId {
|
|||
public static final int ELEMENT_EMOJI_CATEGORY5 = 15;
|
||||
public static final int ELEMENT_EMOJI_CATEGORY6 = 16;
|
||||
|
||||
public final InputMethodSubtype mSubtype;
|
||||
public final RichInputMethodSubtype mSubtype;
|
||||
public final Locale mLocale;
|
||||
public final int mWidth;
|
||||
public final int mHeight;
|
||||
|
|
|
@ -28,7 +28,6 @@ import android.util.Log;
|
|||
import android.util.SparseArray;
|
||||
import android.util.Xml;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.compat.EditorInfoCompatUtils;
|
||||
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
|
||||
|
@ -37,6 +36,7 @@ import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
|||
import com.android.inputmethod.keyboard.internal.KeysCache;
|
||||
import com.android.inputmethod.latin.InputAttributes;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||
import com.android.inputmethod.latin.define.DebugFlags;
|
||||
import com.android.inputmethod.latin.utils.InputTypeUtils;
|
||||
|
@ -109,7 +109,7 @@ public final class KeyboardLayoutSet {
|
|||
boolean mVoiceInputKeyEnabled;
|
||||
boolean mNoSettingsKey;
|
||||
boolean mLanguageSwitchKeyEnabled;
|
||||
InputMethodSubtype mSubtype;
|
||||
RichInputMethodSubtype mSubtype;
|
||||
boolean mIsSpellChecker;
|
||||
int mKeyboardWidth;
|
||||
int mKeyboardHeight;
|
||||
|
@ -245,7 +245,7 @@ public final class KeyboardLayoutSet {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setSubtype(final InputMethodSubtype subtype) {
|
||||
public Builder setSubtype(final RichInputMethodSubtype subtype) {
|
||||
final boolean asciiCapable = InputMethodSubtypeCompatUtils.isAsciiCapable(subtype);
|
||||
// TODO: Consolidate with {@link InputAttributes}.
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -254,7 +254,7 @@ public final class KeyboardLayoutSet {
|
|||
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
|
||||
mParams.mEditorInfo.imeOptions)
|
||||
|| deprecatedForceAscii;
|
||||
final InputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable)
|
||||
final RichInputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable)
|
||||
? SubtypeSwitcher.getInstance().getNoLanguageSubtype()
|
||||
: subtype;
|
||||
mParams.mSubtype = keyboardSubtype;
|
||||
|
|
|
@ -34,7 +34,6 @@ import android.view.LayoutInflater;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.accessibility.AccessibilityUtils;
|
||||
import com.android.inputmethod.accessibility.MainKeyboardAccessibilityDelegate;
|
||||
|
@ -54,10 +53,10 @@ import com.android.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview;
|
|||
import com.android.inputmethod.keyboard.internal.TimerHandler;
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.SuggestedWords;
|
||||
import com.android.inputmethod.latin.settings.DebugSettings;
|
||||
import com.android.inputmethod.latin.utils.CoordinateUtils;
|
||||
import com.android.inputmethod.latin.utils.SpacebarLanguageUtils;
|
||||
import com.android.inputmethod.latin.utils.TypefaceUtils;
|
||||
|
||||
import java.util.WeakHashMap;
|
||||
|
@ -849,16 +848,16 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
|
||||
// Layout language name on spacebar.
|
||||
private String layoutLanguageOnSpacebar(final Paint paint,
|
||||
final InputMethodSubtype subtype, final int width) {
|
||||
final RichInputMethodSubtype subtype, final int width) {
|
||||
// Choose appropriate language name to fit into the width.
|
||||
if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_FULL_LOCALE) {
|
||||
final String fullText = SpacebarLanguageUtils.getFullDisplayName(subtype);
|
||||
final String fullText = subtype.getFullDisplayName();
|
||||
if (fitsTextIntoWidth(width, fullText, paint)) {
|
||||
return fullText;
|
||||
}
|
||||
}
|
||||
|
||||
final String middleText = SpacebarLanguageUtils.getMiddleDisplayName(subtype);
|
||||
final String middleText = subtype.getMiddleDisplayName();
|
||||
if (fitsTextIntoWidth(width, middleText, paint)) {
|
||||
return middleText;
|
||||
}
|
||||
|
@ -872,7 +871,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
paint.setTextAlign(Align.CENTER);
|
||||
paint.setTypeface(Typeface.DEFAULT);
|
||||
paint.setTextSize(mLanguageOnSpacebarTextSize);
|
||||
final InputMethodSubtype subtype = getKeyboard().mId.mSubtype;
|
||||
final RichInputMethodSubtype subtype = getKeyboard().mId.mSubtype;
|
||||
final String language = layoutLanguageOnSpacebar(paint, subtype, width);
|
||||
// Draw language text with shadow
|
||||
final float descent = paint.descent();
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard.internal;
|
|||
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -34,8 +35,8 @@ public final class LanguageOnSpacebarHelper {
|
|||
private List<InputMethodSubtype> mEnabledSubtypes = Collections.emptyList();
|
||||
private boolean mIsSystemLanguageSameAsInputLanguage;
|
||||
|
||||
public int getLanguageOnSpacebarFormatType(final InputMethodSubtype subtype) {
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
public int getLanguageOnSpacebarFormatType(final RichInputMethodSubtype subtype) {
|
||||
if (subtype.isNoLanguage()) {
|
||||
return FORMAT_TYPE_FULL_LOCALE;
|
||||
}
|
||||
// Only this subtype is enabled and equals to the system locale.
|
||||
|
|
|
@ -747,7 +747,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) {
|
||||
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
|
||||
// is not guaranteed. It may even be called at the same time on a different thread.
|
||||
mSubtypeSwitcher.onSubtypeChanged(subtype);
|
||||
final RichInputMethodSubtype richSubtype = new RichInputMethodSubtype(subtype);
|
||||
mSubtypeSwitcher.onSubtypeChanged(richSubtype);
|
||||
mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype));
|
||||
loadKeyboard();
|
||||
}
|
||||
|
|
|
@ -298,10 +298,14 @@ public class RichInputMethodManager {
|
|||
return INDEX_NOT_FOUND;
|
||||
}
|
||||
|
||||
public InputMethodSubtype getCurrentInputMethodSubtype(
|
||||
final InputMethodSubtype defaultSubtype) {
|
||||
public RichInputMethodSubtype getCurrentInputMethodSubtype(
|
||||
final RichInputMethodSubtype defaultSubtype) {
|
||||
final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype();
|
||||
return (currentSubtype != null) ? currentSubtype : defaultSubtype;
|
||||
if (currentSubtype == null) {
|
||||
return defaultSubtype;
|
||||
}
|
||||
// TODO: Determine locales to use for multi-lingual use.
|
||||
return new RichInputMethodSubtype(currentSubtype);
|
||||
}
|
||||
|
||||
public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) {
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.inputmethod.latin;
|
||||
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.utils.LocaleUtils;
|
||||
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Enrichment class for InputMethodSubtype to enable concurrent multi-lingual input.
|
||||
*
|
||||
* Right now, this returns the extra value of its primary subtype.
|
||||
*/
|
||||
public final class RichInputMethodSubtype {
|
||||
private final InputMethodSubtype mSubtype;
|
||||
private final Locale[] mLocales;
|
||||
|
||||
public RichInputMethodSubtype(final InputMethodSubtype subtype, final Locale... locales) {
|
||||
mSubtype = subtype;
|
||||
mLocales = new Locale[locales.length+1];
|
||||
mLocales[0] = LocaleUtils.constructLocaleFromString(mSubtype.getLocale());
|
||||
System.arraycopy(locales, 0, mLocales, 1, locales.length);
|
||||
}
|
||||
|
||||
// Extra values are determined by the primary subtype. This is probably right, but
|
||||
// we may have to revisit this later.
|
||||
public String getExtraValueOf(final String key) {
|
||||
return mSubtype.getExtraValueOf(key);
|
||||
}
|
||||
|
||||
// The mode is also determined by the primary subtype.
|
||||
public String getMode() {
|
||||
return mSubtype.getMode();
|
||||
}
|
||||
|
||||
public boolean isNoLanguage() {
|
||||
if (mLocales.length > 1) {
|
||||
return false;
|
||||
}
|
||||
return SubtypeLocaleUtils.NO_LANGUAGE.equals(mSubtype.getLocale());
|
||||
}
|
||||
|
||||
public String getNameForLogging() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
// InputMethodSubtype's display name for spacebar text in its locale.
|
||||
// isAdditionalSubtype (T=true, F=false)
|
||||
// locale layout | Middle Full
|
||||
// ------ ------- - --------- ----------------------
|
||||
// en_US qwerty F English English (US) exception
|
||||
// en_GB qwerty F English English (UK) exception
|
||||
// es_US spanish F Español Español (EE.UU.) exception
|
||||
// fr azerty F Français Français
|
||||
// fr_CA qwerty F Français Français (Canada)
|
||||
// fr_CH swiss F Français Français (Suisse)
|
||||
// de qwertz F Deutsch Deutsch
|
||||
// de_CH swiss T Deutsch Deutsch (Schweiz)
|
||||
// zz qwerty F QWERTY QWERTY
|
||||
// fr qwertz T Français Français
|
||||
// de qwerty T Deutsch Deutsch
|
||||
// en_US azerty T English English (US)
|
||||
// zz azerty T AZERTY AZERTY
|
||||
// Get the RichInputMethodSubtype's full display name in its locale.
|
||||
public String getFullDisplayName() {
|
||||
if (isNoLanguage()) {
|
||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(mSubtype);
|
||||
}
|
||||
return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(mSubtype.getLocale());
|
||||
}
|
||||
|
||||
// Get the RichInputMethodSubtype's middle display name in its locale.
|
||||
public String getMiddleDisplayName() {
|
||||
if (isNoLanguage()) {
|
||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(mSubtype);
|
||||
}
|
||||
return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(mSubtype.getLocale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof RichInputMethodSubtype)) {
|
||||
return false;
|
||||
}
|
||||
final RichInputMethodSubtype other = (RichInputMethodSubtype)o;
|
||||
return mSubtype.equals(other.mSubtype) && Arrays.equals(mLocales, other.mLocales);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mSubtype.hashCode() + Arrays.hashCode(mLocales);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Multi-lingual subtype: " + mSubtype.toString() + ", " + Arrays.toString(mLocales);
|
||||
}
|
||||
|
||||
// TODO: remove this method! We can always have several locales. Multi-lingual input will only
|
||||
// be done when this method is gone.
|
||||
public String getLocale() {
|
||||
return mSubtype.getLocale();
|
||||
}
|
||||
|
||||
// TODO: remove this method
|
||||
public InputMethodSubtype getRawSubtype() { return mSubtype; }
|
||||
}
|
|
@ -58,8 +58,8 @@ public final class SubtypeSwitcher {
|
|||
new LanguageOnSpacebarHelper();
|
||||
private InputMethodInfo mShortcutInputMethodInfo;
|
||||
private InputMethodSubtype mShortcutSubtype;
|
||||
private InputMethodSubtype mNoLanguageSubtype;
|
||||
private InputMethodSubtype mEmojiSubtype;
|
||||
private RichInputMethodSubtype mNoLanguageSubtype;
|
||||
private RichInputMethodSubtype mEmojiSubtype;
|
||||
private boolean mIsNetworkConnected;
|
||||
|
||||
private static final String KEYBOARD_MODE = "keyboard";
|
||||
|
@ -70,26 +70,26 @@ public final class SubtypeSwitcher {
|
|||
+ "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
|
||||
+ "," + Constants.Subtype.ExtraValue.ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE
|
||||
+ "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
||||
private static final InputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE =
|
||||
InputMethodSubtypeCompatUtils.newInputMethodSubtype(
|
||||
private static final RichInputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE =
|
||||
new RichInputMethodSubtype(InputMethodSubtypeCompatUtils.newInputMethodSubtype(
|
||||
R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark,
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, KEYBOARD_MODE,
|
||||
EXTRA_VALUE_OF_DUMMY_NO_LANGUAGE_SUBTYPE,
|
||||
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */,
|
||||
SUBTYPE_ID_OF_DUMMY_NO_LANGUAGE_SUBTYPE);
|
||||
SUBTYPE_ID_OF_DUMMY_NO_LANGUAGE_SUBTYPE));
|
||||
// Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}.
|
||||
// Dummy Emoji subtype. See {@link R.xml.method}.
|
||||
private static final int SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE = 0xd78b2ed0;
|
||||
private static final String EXTRA_VALUE_OF_DUMMY_EMOJI_SUBTYPE =
|
||||
"KeyboardLayoutSet=" + SubtypeLocaleUtils.EMOJI
|
||||
+ "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
||||
private static final InputMethodSubtype DUMMY_EMOJI_SUBTYPE =
|
||||
private static final RichInputMethodSubtype DUMMY_EMOJI_SUBTYPE = new RichInputMethodSubtype(
|
||||
InputMethodSubtypeCompatUtils.newInputMethodSubtype(
|
||||
R.string.subtype_emoji, R.drawable.ic_ime_switcher_dark,
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, KEYBOARD_MODE,
|
||||
EXTRA_VALUE_OF_DUMMY_EMOJI_SUBTYPE,
|
||||
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */,
|
||||
SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE);
|
||||
SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE));
|
||||
|
||||
public static SubtypeSwitcher getInstance() {
|
||||
return sInstance;
|
||||
|
@ -165,18 +165,17 @@ public final class SubtypeSwitcher {
|
|||
}
|
||||
|
||||
// Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
|
||||
public void onSubtypeChanged(final InputMethodSubtype newSubtype) {
|
||||
public void onSubtypeChanged(final RichInputMethodSubtype newSubtype) {
|
||||
if (DBG) {
|
||||
Log.w(TAG, "onSubtypeChanged: "
|
||||
+ SubtypeLocaleUtils.getSubtypeNameForLogging(newSubtype));
|
||||
Log.w(TAG, "onSubtypeChanged: " + newSubtype.getNameForLogging());
|
||||
}
|
||||
|
||||
final Locale newLocale = SubtypeLocaleUtils.getSubtypeLocale(newSubtype);
|
||||
final Locale systemLocale = mResources.getConfiguration().locale;
|
||||
final boolean sameLocale = systemLocale.equals(newLocale);
|
||||
final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage());
|
||||
final boolean implicitlyEnabled =
|
||||
mRichImm.checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype);
|
||||
final boolean implicitlyEnabled = mRichImm
|
||||
.checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype());
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(
|
||||
sameLocale || (sameLanguage && implicitlyEnabled));
|
||||
|
||||
|
@ -250,7 +249,7 @@ public final class SubtypeSwitcher {
|
|||
// Subtype Switching functions //
|
||||
//////////////////////////////////
|
||||
|
||||
public int getLanguageOnSpacebarFormatType(final InputMethodSubtype subtype) {
|
||||
public int getLanguageOnSpacebarFormatType(final RichInputMethodSubtype subtype) {
|
||||
return mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(subtype);
|
||||
}
|
||||
|
||||
|
@ -279,10 +278,10 @@ public final class SubtypeSwitcher {
|
|||
return true;
|
||||
}
|
||||
|
||||
private static InputMethodSubtype sForcedSubtypeForTesting = null;
|
||||
private static RichInputMethodSubtype sForcedSubtypeForTesting = null;
|
||||
@UsedForTesting
|
||||
void forceSubtype(final InputMethodSubtype subtype) {
|
||||
sForcedSubtypeForTesting = subtype;
|
||||
sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype);
|
||||
}
|
||||
|
||||
public Locale getCurrentSubtypeLocale() {
|
||||
|
@ -292,17 +291,18 @@ public final class SubtypeSwitcher {
|
|||
return SubtypeLocaleUtils.getSubtypeLocale(getCurrentSubtype());
|
||||
}
|
||||
|
||||
public InputMethodSubtype getCurrentSubtype() {
|
||||
public RichInputMethodSubtype getCurrentSubtype() {
|
||||
if (null != sForcedSubtypeForTesting) {
|
||||
return sForcedSubtypeForTesting;
|
||||
}
|
||||
return mRichImm.getCurrentInputMethodSubtype(getNoLanguageSubtype());
|
||||
}
|
||||
|
||||
public InputMethodSubtype getNoLanguageSubtype() {
|
||||
public RichInputMethodSubtype getNoLanguageSubtype() {
|
||||
if (mNoLanguageSubtype == null) {
|
||||
mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY);
|
||||
mNoLanguageSubtype = new RichInputMethodSubtype(
|
||||
mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY));
|
||||
}
|
||||
if (mNoLanguageSubtype != null) {
|
||||
return mNoLanguageSubtype;
|
||||
|
@ -313,10 +313,11 @@ public final class SubtypeSwitcher {
|
|||
return DUMMY_NO_LANGUAGE_SUBTYPE;
|
||||
}
|
||||
|
||||
public InputMethodSubtype getEmojiSubtype() {
|
||||
public RichInputMethodSubtype getEmojiSubtype() {
|
||||
if (mEmojiSubtype == null) {
|
||||
mEmojiSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI);
|
||||
mEmojiSubtype = new RichInputMethodSubtype(
|
||||
mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI));
|
||||
}
|
||||
if (mEmojiSubtype != null) {
|
||||
return mEmojiSubtype;
|
||||
|
@ -328,6 +329,6 @@ public final class SubtypeSwitcher {
|
|||
}
|
||||
|
||||
public String getCombiningRulesExtraValueOfCurrentSubtype() {
|
||||
return SubtypeLocaleUtils.getCombiningRulesExtraValue(getCurrentSubtype());
|
||||
return SubtypeLocaleUtils.getCombiningRulesExtraValue(getCurrentSubtype().getRawSubtype());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import com.android.inputmethod.latin.DictionaryFacilitator;
|
|||
import com.android.inputmethod.latin.DictionaryFactory;
|
||||
import com.android.inputmethod.latin.PrevWordsInfo;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
|
||||
import com.android.inputmethod.latin.UserBinaryDictionary;
|
||||
|
@ -334,7 +335,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
|||
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(this, editorInfo);
|
||||
builder.setKeyboardGeometry(
|
||||
SPELLCHECKER_DUMMY_KEYBOARD_WIDTH, SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT);
|
||||
builder.setSubtype(subtype);
|
||||
builder.setSubtype(new RichInputMethodSubtype(subtype));
|
||||
builder.setIsSpellChecker(true /* isSpellChecker */);
|
||||
builder.disableTouchPositionCorrectionData();
|
||||
return builder.build();
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.android.inputmethod.keyboard.KeyboardId;
|
|||
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
|
||||
import com.android.inputmethod.latin.DictionaryFacilitator;
|
||||
import com.android.inputmethod.latin.PrevWordsInfo;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.WordComposer;
|
||||
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
|
||||
|
@ -131,7 +132,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
|
|||
final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
|
||||
final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
|
||||
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
|
||||
builder.setSubtype(subtype);
|
||||
builder.setSubtype(new RichInputMethodSubtype(subtype));
|
||||
builder.setIsSpellChecker(false /* isSpellChecker */);
|
||||
final KeyboardLayoutSet layoutSet = builder.build();
|
||||
mKeyboard = layoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.utils;
|
||||
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
public final class SpacebarLanguageUtils {
|
||||
private SpacebarLanguageUtils() {
|
||||
// Intentional empty constructor for utility class.
|
||||
}
|
||||
|
||||
// InputMethodSubtype's display name for spacebar text in its locale.
|
||||
// isAdditionalSubtype (T=true, F=false)
|
||||
// locale layout | Middle Full
|
||||
// ------ ------- - --------- ----------------------
|
||||
// en_US qwerty F English English (US) exception
|
||||
// en_GB qwerty F English English (UK) exception
|
||||
// es_US spanish F Español Español (EE.UU.) exception
|
||||
// fr azerty F Français Français
|
||||
// fr_CA qwerty F Français Français (Canada)
|
||||
// fr_CH swiss F Français Français (Suisse)
|
||||
// de qwertz F Deutsch Deutsch
|
||||
// de_CH swiss T Deutsch Deutsch (Schweiz)
|
||||
// zz qwerty F QWERTY QWERTY
|
||||
// fr qwertz T Français Français
|
||||
// de qwerty T Deutsch Deutsch
|
||||
// en_US azerty T English English (US)
|
||||
// zz azerty T AZERTY AZERTY
|
||||
// Get InputMethodSubtype's full display name in its locale.
|
||||
public static String getFullDisplayName(final InputMethodSubtype subtype) {
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
|
||||
}
|
||||
return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
|
||||
}
|
||||
|
||||
// Get InputMethodSubtype's middle display name in its locale.
|
||||
public static String getMiddleDisplayName(final InputMethodSubtype subtype) {
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
|
||||
}
|
||||
return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(subtype.getLocale());
|
||||
}
|
||||
}
|
|
@ -27,12 +27,17 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A helper class to deal with subtype locales.
|
||||
*/
|
||||
// TODO: consolidate this into RichInputMethodSubtype
|
||||
public final class SubtypeLocaleUtils {
|
||||
private static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
|
||||
|
||||
|
@ -109,10 +114,10 @@ public final class SubtypeLocaleUtils {
|
|||
sKeyboardLayoutToNameIdsMap.put(key, noLanguageResId);
|
||||
}
|
||||
|
||||
final String[] excetionalLocaleInRootLocale = res.getStringArray(
|
||||
final String[] exceptionalLocaleInRootLocale = res.getStringArray(
|
||||
R.array.subtype_locale_displayed_in_root_locale);
|
||||
for (int i = 0; i < excetionalLocaleInRootLocale.length; i++) {
|
||||
sExceptionalLocaleDisplayedInRootLocale.add(excetionalLocaleInRootLocale[i]);
|
||||
for (int i = 0; i < exceptionalLocaleInRootLocale.length; i++) {
|
||||
sExceptionalLocaleDisplayedInRootLocale.add(exceptionalLocaleInRootLocale[i]);
|
||||
}
|
||||
|
||||
final String[] exceptionalLocales = res.getStringArray(
|
||||
|
@ -260,6 +265,7 @@ public final class SubtypeLocaleUtils {
|
|||
private static String getSubtypeDisplayNameInternal(final InputMethodSubtype subtype,
|
||||
final Locale displayLocale) {
|
||||
final String replacementString = getReplacementString(subtype, displayLocale);
|
||||
// TODO: rework this for multi-lingual subtypes
|
||||
final int nameResId = subtype.getNameResId();
|
||||
final RunInLocale<String> getSubtypeName = new RunInLocale<String>() {
|
||||
@Override
|
||||
|
@ -282,12 +288,14 @@ public final class SubtypeLocaleUtils {
|
|||
getSubtypeName.runInLocale(sResources, displayLocale), displayLocale);
|
||||
}
|
||||
|
||||
public static boolean isNoLanguage(final InputMethodSubtype subtype) {
|
||||
public static Locale getSubtypeLocale(final InputMethodSubtype subtype) {
|
||||
final String localeString = subtype.getLocale();
|
||||
return NO_LANGUAGE.equals(localeString);
|
||||
return LocaleUtils.constructLocaleFromString(localeString);
|
||||
}
|
||||
|
||||
public static Locale getSubtypeLocale(final InputMethodSubtype subtype) {
|
||||
// TODO: remove this. When RichInputMethodSubtype#getLocale is removed we can do away with this
|
||||
// method at the same time.
|
||||
public static Locale getSubtypeLocale(final RichInputMethodSubtype subtype) {
|
||||
final String localeString = subtype.getLocale();
|
||||
return LocaleUtils.constructLocaleFromString(localeString);
|
||||
}
|
||||
|
@ -301,6 +309,10 @@ public final class SubtypeLocaleUtils {
|
|||
return sKeyboardLayoutToDisplayNameMap.get(layoutName);
|
||||
}
|
||||
|
||||
public static String getKeyboardLayoutSetName(final RichInputMethodSubtype subtype) {
|
||||
return getKeyboardLayoutSetName(subtype.getRawSubtype());
|
||||
}
|
||||
|
||||
public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) {
|
||||
String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET);
|
||||
if (keyboardLayoutSet == null) {
|
||||
|
@ -336,7 +348,7 @@ public final class SubtypeLocaleUtils {
|
|||
return Arrays.binarySearch(SORTED_RTL_LANGUAGES, language) >= 0;
|
||||
}
|
||||
|
||||
public static boolean isRtlLanguage(final InputMethodSubtype subtype) {
|
||||
public static boolean isRtlLanguage(final RichInputMethodSubtype subtype) {
|
||||
return isRtlLanguage(getSubtypeLocale(subtype));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet.Builder;
|
|||
import com.android.inputmethod.latin.Constants;
|
||||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
|
||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
@ -127,7 +128,7 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
|
|||
final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
|
||||
final Builder builder = new Builder(context, editorInfo);
|
||||
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight)
|
||||
.setSubtype(subtype)
|
||||
.setSubtype(new RichInputMethodSubtype(subtype))
|
||||
.setVoiceInputKeyEnabled(voiceInputKeyEnabled)
|
||||
.setLanguageSwitchKeyEnabled(languageSwitchKeyEnabled);
|
||||
return builder.build();
|
||||
|
|
|
@ -26,6 +26,7 @@ import android.test.suitebuilder.annotation.SmallTest;
|
|||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
|
||||
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
|
@ -40,14 +41,14 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
|
||||
private RichInputMethodManager mRichImm;
|
||||
|
||||
InputMethodSubtype EN_US_QWERTY;
|
||||
InputMethodSubtype EN_GB_QWERTY;
|
||||
InputMethodSubtype FR_AZERTY;
|
||||
InputMethodSubtype FR_CA_QWERTY;
|
||||
InputMethodSubtype FR_CH_SWISS;
|
||||
InputMethodSubtype FR_CH_QWERTY;
|
||||
InputMethodSubtype FR_CH_QWERTZ;
|
||||
InputMethodSubtype ZZ_QWERTY;
|
||||
RichInputMethodSubtype EN_US_QWERTY;
|
||||
RichInputMethodSubtype EN_GB_QWERTY;
|
||||
RichInputMethodSubtype FR_AZERTY;
|
||||
RichInputMethodSubtype FR_CA_QWERTY;
|
||||
RichInputMethodSubtype FR_CH_SWISS;
|
||||
RichInputMethodSubtype FR_CH_QWERTY;
|
||||
RichInputMethodSubtype FR_CH_QWERTZ;
|
||||
RichInputMethodSubtype ZZ_QWERTY;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
|
@ -57,22 +58,22 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
mRichImm = RichInputMethodManager.getInstance();
|
||||
SubtypeLocaleUtils.init(context);
|
||||
|
||||
EN_US_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.US.toString(), "qwerty");
|
||||
EN_GB_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.UK.toString(), "qwerty");
|
||||
FR_AZERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.FRENCH.toString(), "azerty");
|
||||
FR_CA_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.CANADA_FRENCH.toString(), "qwerty");
|
||||
FR_CH_SWISS = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"fr_CH", "swiss");
|
||||
FR_CH_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
"fr_CH", "qwertz");
|
||||
FR_CH_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
"fr_CH", "qwerty");
|
||||
ZZ_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
||||
EN_US_QWERTY = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.US.toString(), "qwerty"));
|
||||
EN_GB_QWERTY = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.UK.toString(), "qwerty"));
|
||||
FR_AZERTY = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.FRENCH.toString(), "azerty"));
|
||||
FR_CA_QWERTY = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.CANADA_FRENCH.toString(), "qwerty"));
|
||||
FR_CH_SWISS = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"fr_CH", "swiss"));
|
||||
FR_CH_QWERTZ = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwertz"));
|
||||
FR_CH_QWERTY = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwerty"));
|
||||
ZZ_QWERTY = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"));
|
||||
}
|
||||
|
||||
private static List<InputMethodSubtype> asList(final InputMethodSubtype ... subtypes) {
|
||||
|
@ -80,14 +81,14 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
}
|
||||
|
||||
public void testOneSubtype() {
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY));
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY.getRawSubtype()));
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */);
|
||||
assertEquals("one same English (US)", FORMAT_TYPE_NONE,
|
||||
mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY));
|
||||
assertEquals("one same NoLanguage", FORMAT_TYPE_FULL_LOCALE,
|
||||
mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY));
|
||||
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(FR_AZERTY));
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(FR_AZERTY.getRawSubtype()));
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false /* isSame */);
|
||||
assertEquals("one diff English (US)", FORMAT_TYPE_LANGUAGE_ONLY,
|
||||
mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY));
|
||||
|
@ -96,8 +97,8 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
}
|
||||
|
||||
public void testTwoSubtypes() {
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY, FR_AZERTY));
|
||||
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY.getRawSubtype(),
|
||||
FR_AZERTY.getRawSubtype()));
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */);
|
||||
assertEquals("two same English (US)", FORMAT_TYPE_LANGUAGE_ONLY,
|
||||
mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY));
|
||||
|
@ -117,7 +118,8 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
|
||||
public void testSameLanuageSubtypes() {
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(
|
||||
asList(EN_US_QWERTY, EN_GB_QWERTY, FR_AZERTY, ZZ_QWERTY));
|
||||
asList(EN_US_QWERTY.getRawSubtype(), EN_GB_QWERTY.getRawSubtype(),
|
||||
FR_AZERTY.getRawSubtype(), ZZ_QWERTY.getRawSubtype()));
|
||||
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */);
|
||||
assertEquals("two same English (US)", FORMAT_TYPE_FULL_LOCALE,
|
||||
|
@ -138,7 +140,9 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||
|
||||
public void testMultiSameLanuageSubtypes() {
|
||||
mLanguageOnSpacebarHelper.updateEnabledSubtypes(
|
||||
asList(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTY, FR_CH_QWERTZ));
|
||||
asList(FR_AZERTY.getRawSubtype(), FR_CA_QWERTY.getRawSubtype(),
|
||||
FR_CH_SWISS.getRawSubtype(), FR_CH_QWERTY.getRawSubtype(),
|
||||
FR_CH_QWERTZ.getRawSubtype()));
|
||||
|
||||
mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */);
|
||||
assertEquals("multi same French", FORMAT_TYPE_LANGUAGE_ONLY,
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.view.inputmethod.InputMethodInfo;
|
|||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
@ -31,28 +32,28 @@ import java.util.Locale;
|
|||
@SmallTest
|
||||
public class SpacebarLanguageUtilsTests extends AndroidTestCase {
|
||||
// All input method subtypes of LatinIME.
|
||||
private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<>();
|
||||
private final ArrayList<RichInputMethodSubtype> mSubtypesList = new ArrayList<>();
|
||||
|
||||
private RichInputMethodManager mRichImm;
|
||||
private Resources mRes;
|
||||
|
||||
InputMethodSubtype EN_US;
|
||||
InputMethodSubtype EN_GB;
|
||||
InputMethodSubtype ES_US;
|
||||
InputMethodSubtype FR;
|
||||
InputMethodSubtype FR_CA;
|
||||
InputMethodSubtype FR_CH;
|
||||
InputMethodSubtype DE;
|
||||
InputMethodSubtype DE_CH;
|
||||
InputMethodSubtype HI_ZZ;
|
||||
InputMethodSubtype ZZ;
|
||||
InputMethodSubtype DE_QWERTY;
|
||||
InputMethodSubtype FR_QWERTZ;
|
||||
InputMethodSubtype EN_US_AZERTY;
|
||||
InputMethodSubtype EN_UK_DVORAK;
|
||||
InputMethodSubtype ES_US_COLEMAK;
|
||||
InputMethodSubtype ZZ_AZERTY;
|
||||
InputMethodSubtype ZZ_PC;
|
||||
RichInputMethodSubtype EN_US;
|
||||
RichInputMethodSubtype EN_GB;
|
||||
RichInputMethodSubtype ES_US;
|
||||
RichInputMethodSubtype FR;
|
||||
RichInputMethodSubtype FR_CA;
|
||||
RichInputMethodSubtype FR_CH;
|
||||
RichInputMethodSubtype DE;
|
||||
RichInputMethodSubtype DE_CH;
|
||||
RichInputMethodSubtype HI_ZZ;
|
||||
RichInputMethodSubtype ZZ;
|
||||
RichInputMethodSubtype DE_QWERTY;
|
||||
RichInputMethodSubtype FR_QWERTZ;
|
||||
RichInputMethodSubtype EN_US_AZERTY;
|
||||
RichInputMethodSubtype EN_UK_DVORAK;
|
||||
RichInputMethodSubtype ES_US_COLEMAK;
|
||||
RichInputMethodSubtype ZZ_AZERTY;
|
||||
RichInputMethodSubtype ZZ_PC;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
|
@ -67,53 +68,60 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
|
|||
final int subtypeCount = imi.getSubtypeCount();
|
||||
for (int index = 0; index < subtypeCount; index++) {
|
||||
final InputMethodSubtype subtype = imi.getSubtypeAt(index);
|
||||
mSubtypesList.add(subtype);
|
||||
mSubtypesList.add(new RichInputMethodSubtype(subtype));
|
||||
}
|
||||
|
||||
EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.US.toString(), "qwerty");
|
||||
EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.UK.toString(), "qwerty");
|
||||
ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"es_US", "spanish");
|
||||
FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.FRENCH.toString(), "azerty");
|
||||
FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.CANADA_FRENCH.toString(), "qwerty");
|
||||
FR_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"fr_CH", "swiss");
|
||||
DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.GERMAN.toString(), "qwertz");
|
||||
DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"de_CH", "swiss");
|
||||
HI_ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"hi_ZZ", "qwerty");
|
||||
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
||||
DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.GERMAN.toString(), "qwerty");
|
||||
FR_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.FRENCH.toString(), "qwertz");
|
||||
EN_US_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.US.toString(), "azerty");
|
||||
EN_UK_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.UK.toString(), "dvorak");
|
||||
ES_US_COLEMAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
"es_US", "colemak");
|
||||
ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
|
||||
ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty");
|
||||
EN_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.US.toString(), "qwerty"));
|
||||
EN_GB = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.UK.toString(), "qwerty"));
|
||||
ES_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"es_US", "spanish"));
|
||||
FR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.FRENCH.toString(), "azerty"));
|
||||
FR_CA = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.CANADA_FRENCH.toString(), "qwerty"));
|
||||
FR_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"fr_CH", "swiss"));
|
||||
DE = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
Locale.GERMAN.toString(), "qwertz"));
|
||||
DE_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"de_CH", "swiss"));
|
||||
HI_ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
"hi_ZZ", "qwerty"));
|
||||
ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"));
|
||||
DE_QWERTY = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.GERMAN.toString(), "qwerty"));
|
||||
FR_QWERTZ = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.FRENCH.toString(), "qwertz"));
|
||||
EN_US_AZERTY = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.US.toString(), "azerty"));
|
||||
EN_UK_DVORAK = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
Locale.UK.toString(), "dvorak"));
|
||||
ES_US_COLEMAK = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
"es_US", "colemak"));
|
||||
ZZ_AZERTY = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "azerty"));
|
||||
ZZ_PC = new RichInputMethodSubtype(
|
||||
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty"));
|
||||
}
|
||||
|
||||
public void testAllFullDisplayNameForSpacebar() {
|
||||
for (final InputMethodSubtype subtype : mSubtypesList) {
|
||||
for (final RichInputMethodSubtype subtype : mSubtypesList) {
|
||||
final String subtypeName = SubtypeLocaleUtils
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype);
|
||||
final String spacebarText = SpacebarLanguageUtils.getFullDisplayName(subtype);
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
|
||||
final String spacebarText = subtype.getFullDisplayName();
|
||||
final String languageName = SubtypeLocaleUtils
|
||||
.getSubtypeLocaleDisplayName(subtype.getLocale());
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
if (subtype.isNoLanguage()) {
|
||||
assertFalse(subtypeName, spacebarText.contains(languageName));
|
||||
} else {
|
||||
assertTrue(subtypeName, spacebarText.contains(languageName));
|
||||
|
@ -122,19 +130,19 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
|
|||
}
|
||||
|
||||
public void testAllMiddleDisplayNameForSpacebar() {
|
||||
for (final InputMethodSubtype subtype : mSubtypesList) {
|
||||
for (final RichInputMethodSubtype subtype : mSubtypesList) {
|
||||
final String subtypeName = SubtypeLocaleUtils
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype);
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
|
||||
if (SubtypeLocaleUtils.sExceptionalLocaleDisplayedInRootLocale.contains(
|
||||
subtype.getLocale())) {
|
||||
// Skip test because the language part of this locale string doesn't represent
|
||||
// the locale to be displayed on the spacebar (for example hi_ZZ and Hinglish).
|
||||
continue;
|
||||
}
|
||||
final String spacebarText = SpacebarLanguageUtils.getMiddleDisplayName(subtype);
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
assertEquals(subtypeName,
|
||||
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype), spacebarText);
|
||||
final String spacebarText = subtype.getMiddleDisplayName();
|
||||
if (subtype.isNoLanguage()) {
|
||||
assertEquals(subtypeName, SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(
|
||||
subtype.getRawSubtype()), spacebarText);
|
||||
} else {
|
||||
final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
|
||||
assertEquals(subtypeName,
|
||||
|
@ -166,47 +174,27 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
|
|||
private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
|
||||
@Override
|
||||
protected Void job(final Resources res) {
|
||||
assertEquals("en_US", "English (US)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(EN_US));
|
||||
assertEquals("en_GB", "English (UK)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(EN_GB));
|
||||
assertEquals("es_US", "Español (EE.UU.)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(ES_US));
|
||||
assertEquals("fr", "Français",
|
||||
SpacebarLanguageUtils.getFullDisplayName(FR));
|
||||
assertEquals("fr_CA", "Français (Canada)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(FR_CA));
|
||||
assertEquals("fr_CH", "Français (Suisse)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(FR_CH));
|
||||
assertEquals("de", "Deutsch",
|
||||
SpacebarLanguageUtils.getFullDisplayName(DE));
|
||||
assertEquals("de_CH", "Deutsch (Schweiz)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(DE_CH));
|
||||
assertEquals("hi_ZZ", "Hinglish",
|
||||
SpacebarLanguageUtils.getFullDisplayName(HI_ZZ));
|
||||
assertEquals("zz", "QWERTY",
|
||||
SpacebarLanguageUtils.getFullDisplayName(ZZ));
|
||||
assertEquals("en_US", "English (US)", EN_US.getFullDisplayName());
|
||||
assertEquals("en_GB", "English (UK)", EN_GB.getFullDisplayName());
|
||||
assertEquals("es_US", "Español (EE.UU.)", ES_US.getFullDisplayName());
|
||||
assertEquals("fr", "Français", FR.getFullDisplayName());
|
||||
assertEquals("fr_CA", "Français (Canada)", FR_CA.getFullDisplayName());
|
||||
assertEquals("fr_CH", "Français (Suisse)", FR_CH.getFullDisplayName());
|
||||
assertEquals("de", "Deutsch", DE.getFullDisplayName());
|
||||
assertEquals("de_CH", "Deutsch (Schweiz)", DE_CH.getFullDisplayName());
|
||||
assertEquals("hi_ZZ", "Hinglish", HI_ZZ.getFullDisplayName());
|
||||
assertEquals("zz", "QWERTY", ZZ.getFullDisplayName());
|
||||
|
||||
assertEquals("en_US", "English",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(EN_US));
|
||||
assertEquals("en_GB", "English",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(EN_GB));
|
||||
assertEquals("es_US", "Español",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(ES_US));
|
||||
assertEquals("fr", "Français",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(FR));
|
||||
assertEquals("fr_CA", "Français",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(FR_CA));
|
||||
assertEquals("fr_CH", "Français",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(FR_CH));
|
||||
assertEquals("de", "Deutsch",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(DE));
|
||||
assertEquals("de_CH", "Deutsch",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(DE_CH));
|
||||
assertEquals("hi_ZZ", "Hinglish",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(HI_ZZ));
|
||||
assertEquals("zz", "QWERTY",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(ZZ));
|
||||
assertEquals("en_US", "English", EN_US.getMiddleDisplayName());
|
||||
assertEquals("en_GB", "English", EN_GB.getMiddleDisplayName());
|
||||
assertEquals("es_US", "Español", ES_US.getMiddleDisplayName());
|
||||
assertEquals("fr", "Français", FR.getMiddleDisplayName());
|
||||
assertEquals("fr_CA", "Français", FR_CA.getMiddleDisplayName());
|
||||
assertEquals("fr_CH", "Français", FR_CH.getMiddleDisplayName());
|
||||
assertEquals("de", "Deutsch", DE.getMiddleDisplayName());
|
||||
assertEquals("de_CH", "Deutsch", DE_CH.getMiddleDisplayName());
|
||||
assertEquals("hi_ZZ", "Hinglish", HI_ZZ.getMiddleDisplayName());
|
||||
assertEquals("zz", "QWERTY", ZZ.getMiddleDisplayName());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -214,35 +202,21 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
|
|||
private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() {
|
||||
@Override
|
||||
protected Void job(final Resources res) {
|
||||
assertEquals("fr qwertz", "Français",
|
||||
SpacebarLanguageUtils.getFullDisplayName(FR_QWERTZ));
|
||||
assertEquals("de qwerty", "Deutsch",
|
||||
SpacebarLanguageUtils.getFullDisplayName(DE_QWERTY));
|
||||
assertEquals("en_US azerty", "English (US)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(EN_US_AZERTY));
|
||||
assertEquals("en_UK dvorak", "English (UK)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(EN_UK_DVORAK));
|
||||
assertEquals("es_US colemak", "Español (EE.UU.)",
|
||||
SpacebarLanguageUtils.getFullDisplayName(ES_US_COLEMAK));
|
||||
assertEquals("zz azerty", "AZERTY",
|
||||
SpacebarLanguageUtils.getFullDisplayName(ZZ_AZERTY));
|
||||
assertEquals("zz pc", "PC",
|
||||
SpacebarLanguageUtils.getFullDisplayName(ZZ_PC));
|
||||
assertEquals("fr qwertz", "Français", FR_QWERTZ.getFullDisplayName());
|
||||
assertEquals("de qwerty", "Deutsch", DE_QWERTY.getFullDisplayName());
|
||||
assertEquals("en_US azerty", "English (US)", EN_US_AZERTY.getFullDisplayName());
|
||||
assertEquals("en_UK dvorak", "English (UK)", EN_UK_DVORAK.getFullDisplayName());
|
||||
assertEquals("es_US colemak", "Español (EE.UU.)", ES_US_COLEMAK.getFullDisplayName());
|
||||
assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getFullDisplayName());
|
||||
assertEquals("zz pc", "PC", ZZ_PC.getFullDisplayName());
|
||||
|
||||
assertEquals("fr qwertz", "Français",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(FR_QWERTZ));
|
||||
assertEquals("de qwerty", "Deutsch",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(DE_QWERTY));
|
||||
assertEquals("en_US azerty", "English",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(EN_US_AZERTY));
|
||||
assertEquals("en_UK dvorak", "English",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(EN_UK_DVORAK));
|
||||
assertEquals("es_US colemak", "Español",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(ES_US_COLEMAK));
|
||||
assertEquals("zz azerty", "AZERTY",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(ZZ_AZERTY));
|
||||
assertEquals("zz pc", "PC",
|
||||
SpacebarLanguageUtils.getMiddleDisplayName(ZZ_PC));
|
||||
assertEquals("fr qwertz", "Français", FR_QWERTZ.getMiddleDisplayName());
|
||||
assertEquals("de qwerty", "Deutsch", DE_QWERTY.getMiddleDisplayName());
|
||||
assertEquals("en_US azerty", "English", EN_US_AZERTY.getMiddleDisplayName());
|
||||
assertEquals("en_UK dvorak", "English", EN_UK_DVORAK.getMiddleDisplayName());
|
||||
assertEquals("es_US colemak", "Español", ES_US_COLEMAK.getMiddleDisplayName());
|
||||
assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getMiddleDisplayName());
|
||||
assertEquals("zz pc", "PC", ZZ_PC.getMiddleDisplayName());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.view.inputmethod.InputMethodInfo;
|
|||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.latin.RichInputMethodManager;
|
||||
import com.android.inputmethod.latin.RichInputMethodSubtype;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
@ -31,7 +32,7 @@ import java.util.Locale;
|
|||
@SmallTest
|
||||
public class SubtypeLocaleUtilsTests extends AndroidTestCase {
|
||||
// All input method subtypes of LatinIME.
|
||||
private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<>();
|
||||
private final ArrayList<RichInputMethodSubtype> mSubtypesList = new ArrayList<>();
|
||||
|
||||
private RichInputMethodManager mRichImm;
|
||||
private Resources mRes;
|
||||
|
@ -67,7 +68,7 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
|
|||
final int subtypeCount = imi.getSubtypeCount();
|
||||
for (int index = 0; index < subtypeCount; index++) {
|
||||
final InputMethodSubtype subtype = imi.getSubtypeAt(index);
|
||||
mSubtypesList.add(subtype);
|
||||
mSubtypesList.add(new RichInputMethodSubtype(subtype));
|
||||
}
|
||||
|
||||
EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||
|
@ -107,12 +108,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
|
|||
}
|
||||
|
||||
public void testAllFullDisplayName() {
|
||||
for (final InputMethodSubtype subtype : mSubtypesList) {
|
||||
for (final RichInputMethodSubtype subtype : mSubtypesList) {
|
||||
final String subtypeName = SubtypeLocaleUtils
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype);
|
||||
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
|
||||
if (subtype.isNoLanguage()) {
|
||||
final String layoutName = SubtypeLocaleUtils
|
||||
.getKeyboardLayoutSetDisplayName(subtype);
|
||||
.getKeyboardLayoutSetDisplayName(subtype.getRawSubtype());
|
||||
assertTrue(subtypeName, subtypeName.contains(layoutName));
|
||||
} else {
|
||||
final String languageName = SubtypeLocaleUtils
|
||||
|
@ -308,9 +309,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
|
|||
.findSubtypeByLocaleAndKeyboardLayoutSet("iw", "hebrew");
|
||||
assertNotNull("Hebrew", HEBREW);
|
||||
|
||||
for (final InputMethodSubtype subtype : mSubtypesList) {
|
||||
for (final RichInputMethodSubtype subtype : mSubtypesList) {
|
||||
final String subtypeName = SubtypeLocaleUtils
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype);
|
||||
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
|
||||
if (subtype.equals(ARABIC) || subtype.equals(FARSI) || subtype.equals(HEBREW)) {
|
||||
assertTrue(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue