Add custom subtype settings

Bug: 4460018
Change-Id: I4919d79516dcf574be2761bbaf9adcdc381b2ddc
main
Tadashi G. Takaoka 2012-04-13 16:41:24 +09:00
parent 344af15674
commit c27fe6253c
11 changed files with 638 additions and 46 deletions

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2012, 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.
*/
-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:columnCount="2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip"
android:padding="8dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
style="?android:attr/textAppearanceSmall"
android:text="@string/subtype_locale" />
<Spinner
android:id="@+id/subtype_locale_spinner"
android:layout_width="wrap_content"
android:layout_marginLeft="8dip"
android:layout_marginBottom="8dip"
android:layout_marginTop="8dip"
android:layout_gravity="fill_horizontal|center_vertical"
android:prompt="@string/subtype_locale" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
style="?android:attr/textAppearanceSmall"
android:text="@string/keyboard_layout_set" />
<Spinner
android:id="@+id/keyboard_layout_set_spinner"
android:layout_width="wrap_content"
android:layout_marginLeft="8dip"
android:layout_marginBottom="8dip"
android:layout_marginTop="8dip"
android:layout_gravity="fill_horizontal|center_vertical"
android:prompt="@string/keyboard_layout_set" />
</GridLayout>

View File

@ -252,9 +252,26 @@
<string name="subtype_en_GB">English (UK)</string>
<!-- Description for English (United States) keyboard subtype [CHAR LIMIT=22] -->
<string name="subtype_en_US">English (US)</string>
<!-- Description for language agnostic keyboard subtype [CHAR LIMIT=22] -->
<string name="subtype_no_language">No language</string>
<!-- Description for language agnostic QWERTY keyboard subtype [CHAR LIMIT=22] -->
<string name="subtype_no_language_qwerty">No language (QWERTY)</string>
<!-- Title of the preference settings for custom input styles (language and keyboard layout pairs) [CHAR LIMIT=22]-->
<string name="custom_input_styles_title">Custom input styles</string>
<!-- Title of the option menu to add a new style entry in the preference settings [CHAR_LIMIT=12] -->
<string name="add_style">Add style</string>
<!-- Title of the button to add custom style entry in the settings dialog [CHAR_LIMIT=12] -->
<string name="add">Add</string>
<!-- Title of the button to remove a custom style entry in the settings dialog [CHAR_LIMIT=12] -->
<string name="remove">Remove</string>
<!-- Title of the button to save a custom style entry in the settings dialog [CHAR_LIMIT=12] -->
<string name="save">Save</string>
<!-- Title of the spinner for choosing a language of custom style in the settings dialog [CHAR_LIMIT=12] -->
<string name="subtype_locale">Language</string>
<!-- Title of the spinner for choosing a keyboard layout of custom style in the settings dialog [CHAR_LIMIT=12] -->
<string name="keyboard_layout_set">Layout</string>
<!-- Title of an option for usability study mode -->
<string name="prefs_usability_study_mode">Usability study mode</string>
<!-- Title of the settings for keypress vibration duration -->

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Items will be added at runtime -->
</PreferenceScreen>

View File

@ -100,6 +100,10 @@
android:summary="@string/include_other_imes_in_language_switch_list_summary"
android:persistent="true"
android:defaultValue="false" />
<PreferenceScreen
android:fragment="com.android.inputmethod.latin.AdditionalSubtypeSettings"
android:key="custom_input_styles"
android:title="@string/custom_input_styles_title" />
<!-- Values for popup dismiss delay are added programatically -->
<ListPreference
android:key="pref_key_preview_popup_dismiss_delay"

View File

@ -24,6 +24,11 @@ public class AdditionalSubtype {
public static final String QWERTY = "qwerty";
public static final String QWERTZ = "qwertz";
public static final String AZERTY = "azerty";
public static final String[] PREDEFINED_KEYBOARD_LAYOUT_SET = {
QWERTY,
QWERTZ,
AZERTY
};
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE = "isAdditionalSubtype";
@ -38,40 +43,60 @@ public class AdditionalSubtype {
sKeyboardLayoutToNameIdsMap.put(AZERTY, R.string.subtype_generic_azerty);
}
private AdditionalSubtype() {
// This utility class is not publicly instantiable.
}
public static boolean isAdditionalSubtype(InputMethodSubtype subtype) {
return subtype.containsExtraValueKey(SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE);
}
private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
public static final String PREF_SUBTYPE_SEPARATOR = ";";
public static InputMethodSubtype createAdditionalSubtype(
String localeString, String keyboardLayoutSetName, String extraValue) {
final String layoutExtraValue = LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET + "="
+ keyboardLayoutSetName;
final String filteredExtraValue = StringUtils.appendToCsvIfNotExists(
SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE,
StringUtils.removeFromCsvIfExists(layoutExtraValue, extraValue));
SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE, extraValue);
Integer nameId = sKeyboardLayoutToNameIdsMap.get(keyboardLayoutSetName);
if (nameId == null) nameId = R.string.subtype_generic;
return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
localeString, SUBTYPE_MODE_KEYBOARD, filteredExtraValue, false, false);
localeString, SUBTYPE_MODE_KEYBOARD,
layoutExtraValue + "," + filteredExtraValue, false, false);
}
private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
private static final String PREF_SUBTYPE_SEPARATOR = ";";
public static String getPrefSubtype(InputMethodSubtype subtype) {
final String localeString = subtype.getLocale();
final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
final String layoutExtraValue = LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET + "="
+ keyboardLayoutSetName;
final String extraValue = StringUtils.removeFromCsvIfExists(layoutExtraValue,
StringUtils.removeFromCsvIfExists(SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE,
subtype.getExtraValue()));
final String basePrefSubtype = localeString + LOCALE_AND_LAYOUT_SEPARATOR
+ keyboardLayoutSetName;
return extraValue.isEmpty() ? basePrefSubtype
: basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue;
}
public static InputMethodSubtype createAdditionalSubtype(String prefSubtype) {
final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
if (elems.length < 2 || elems.length > 3) {
throw new RuntimeException("Unknown additional subtype specified: " + prefSubtype);
}
final String localeString = elems[0];
final String keyboardLayoutSetName = elems[1];
final String extraValue = (elems.length == 3) ? elems[2] : null;
return createAdditionalSubtype(localeString, keyboardLayoutSetName, extraValue);
}
public static InputMethodSubtype[] createAdditionalSubtypesArray(String prefSubtypes) {
final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR);
final InputMethodSubtype[] subtypesArray = new InputMethodSubtype[prefSubtypeArray.length];
for (int i = 0; i < prefSubtypeArray.length; i++) {
final String prefSubtype = prefSubtypeArray[i];
final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
if (elems.length < 2 || elems.length > 3) {
throw new RuntimeException("Unknown subtype found in preference: " + prefSubtype);
}
final String localeString = elems[0];
final String keyboardLayoutSetName = elems[1];
final String extraValue = (elems.length == 3) ? elems[2] : null;
subtypesArray[i] = AdditionalSubtype.createAdditionalSubtype(
localeString, keyboardLayoutSetName, extraValue);
subtypesArray[i] = createAdditionalSubtype(prefSubtypeArray[i]);
}
return subtypesArray;
}

View File

@ -0,0 +1,438 @@
/**
* Copyright (C) 2012 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.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.DialogPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import java.util.Locale;
import java.util.TreeSet;
public class AdditionalSubtypeSettings extends PreferenceFragment {
private SharedPreferences mPrefs;
private SubtypeLocaleAdapter mSubtypeLocaleAdapter;
private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter;
private PreferenceGroup mSubtypePrefGroup;
private static final int MENU_ADD_SUBTYPE = Menu.FIRST;
static class SubtypeLocaleItem extends Pair<String, String>
implements Comparable<SubtypeLocaleItem> {
public SubtypeLocaleItem(String localeString, String displayName) {
super(localeString, displayName);
}
public SubtypeLocaleItem(String localeString) {
this(localeString, getDisplayName(localeString));
}
@Override
public String toString() {
return second;
}
@Override
public int compareTo(SubtypeLocaleItem o) {
return first.compareTo(o.first);
}
private static String getDisplayName(String localeString) {
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
}
}
static class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> {
public SubtypeLocaleAdapter(Context context) {
super(context, android.R.layout.simple_spinner_item);
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
final TreeSet<SubtypeLocaleItem> items = new TreeSet<SubtypeLocaleItem>();
final InputMethodInfo imi = ImfUtils.getInputMethodInfoOfThisIme(context);
final int count = imi.getSubtypeCount();
for (int i = 0; i < count; i++) {
final InputMethodSubtype subtype = imi.getSubtypeAt(i);
if (subtype.containsExtraValueKey(LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE)) {
items.add(createItem(context, subtype.getLocale()));
}
}
// TODO: Should filter out already existing combinations of locale and layout.
addAll(items);
}
public static SubtypeLocaleItem createItem(Context context, String localeString) {
if (localeString.equals(SubtypeLocale.NO_LANGUAGE)) {
final String displayName = context.getString(R.string.subtype_no_language);
return new SubtypeLocaleItem(localeString, displayName);
} else {
return new SubtypeLocaleItem(localeString);
}
}
}
static class KeyboardLayoutSetItem extends Pair<String, String> {
public KeyboardLayoutSetItem(String keyboardLayoutSetName) {
super(keyboardLayoutSetName, getDisplayName(keyboardLayoutSetName));
}
@Override
public String toString() {
return second;
}
private static String getDisplayName(String keyboardLayoutSetName) {
return keyboardLayoutSetName.toUpperCase();
}
}
static class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> {
public KeyboardLayoutSetAdapter(Context context) {
super(context, android.R.layout.simple_spinner_item);
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// TODO: Should filter out already existing combinations of locale and layout.
for (final String layout : AdditionalSubtype.PREDEFINED_KEYBOARD_LAYOUT_SET) {
add(new KeyboardLayoutSetItem(layout));
}
}
}
private interface SubtypeDialogProxy {
public void onRemovePressed(SubtypePreference subtypePref);
public SubtypeLocaleAdapter getSubtypeLocaleAdapter();
public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter();
}
static class SubtypePreference extends DialogPreference {
private InputMethodSubtype mSubtype;
private final SubtypeDialogProxy mProxy;
private Spinner mSubtypeLocaleSpinner;
private Spinner mKeyboardLayoutSetSpinner;
public SubtypePreference(Context context, InputMethodSubtype subtype,
SubtypeDialogProxy proxy) {
super(context, null);
setPersistent(false);
mProxy = proxy;
setSubtype(subtype);
}
public void show() {
showDialog(null);
}
public InputMethodSubtype getSubtype() {
return mSubtype;
}
public void setSubtype(InputMethodSubtype subtype) {
mSubtype = subtype;
if (subtype == null) {
setTitle(null);
setDialogTitle(R.string.add_style);
} else {
final String displayName = SubtypeLocale.getFullDisplayName(subtype);
setTitle(displayName);
setDialogTitle(displayName);
}
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
final Context context = builder.getContext();
final View v = LayoutInflater.from(context).inflate(
R.layout.additional_subtype_dialog, null);
builder.setView(v);
mSubtypeLocaleSpinner = (Spinner) v.findViewById(R.id.subtype_locale_spinner);
mSubtypeLocaleSpinner.setAdapter(mProxy.getSubtypeLocaleAdapter());
mKeyboardLayoutSetSpinner = (Spinner) v.findViewById(R.id.keyboard_layout_set_spinner);
mKeyboardLayoutSetSpinner.setAdapter(mProxy.getKeyboardLayoutSetAdapter());
if (mSubtype == null) {
builder.setPositiveButton(R.string.add, this)
.setNegativeButton(android.R.string.cancel, this);
} else {
builder.setPositiveButton(R.string.save, this)
.setNeutralButton(android.R.string.cancel, this)
.setNegativeButton(R.string.remove, this);
final SubtypeLocaleItem localeItem = SubtypeLocaleAdapter.createItem(
context, mSubtype.getLocale());
final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(
SubtypeLocale.getKeyboardLayoutSetName(mSubtype));
setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
}
}
private static void setSpinnerPosition(Spinner spinner, Object itemToSelect) {
final SpinnerAdapter adapter = spinner.getAdapter();
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
final Object item = spinner.getItemAtPosition(i);
if (item.equals(itemToSelect)) {
spinner.setSelection(i);
return;
}
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
final SubtypeLocaleItem locale =
(SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem();
final KeyboardLayoutSetItem layout =
(KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
locale.first, layout.first, LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE);
setSubtype(subtype);
notifyChanged();
break;
case DialogInterface.BUTTON_NEUTRAL:
// Nothing to do
break;
case DialogInterface.BUTTON_NEGATIVE:
mProxy.onRemovePressed(this);
break;
}
}
@Override
protected Parcelable onSaveInstanceState() {
final SavedState myState = new SavedState(super.onSaveInstanceState());
myState.mSubtype = mSubtype;
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof SavedState) {
final SavedState myState = (SavedState) state;
super.onRestoreInstanceState(state);
setSubtype(myState.mSubtype);
} else {
super.onRestoreInstanceState(state);
}
}
static class SavedState extends Preference.BaseSavedState {
InputMethodSubtype mSubtype;
private static final byte VALID = 1;
private static final byte INVALID = 0;
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
if (mSubtype != null) {
dest.writeByte(VALID);
mSubtype.writeToParcel(dest, 0);
} else {
dest.writeByte(INVALID);
}
}
public SavedState(Parcel source) {
super(source);
if (source.readByte() == VALID) {
mSubtype = source.readParcelable(null);
} else {
mSubtype = null;
}
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel source) {
return new SavedState(source);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
public AdditionalSubtypeSettings() {
// Empty constructor for fragment generation.
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.additional_subtype_settings);
setHasOptionsMenu(true);
mSubtypePrefGroup = getPreferenceScreen();
mPrefs = getPreferenceManager().getSharedPreferences();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Context context = getActivity();
mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context);
mKeyboardLayoutSetAdapter = new KeyboardLayoutSetAdapter(context);
// TODO: Restore editing dialog if any.
}
private final SubtypeDialogProxy mSubtypeProxy = new SubtypeDialogProxy() {
@Override
public void onRemovePressed(SubtypePreference subtypePref) {
final PreferenceGroup group = mSubtypePrefGroup;
if (group != null) {
group.removePreference(subtypePref);
}
}
@Override
public SubtypeLocaleAdapter getSubtypeLocaleAdapter() {
return mSubtypeLocaleAdapter;
}
@Override
public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter() {
return mKeyboardLayoutSetAdapter;
}
};
private void setPrefSubtypes(String prefSubtypes, Context context) {
final PreferenceGroup group = mSubtypePrefGroup;
group.removeAll();
final String[] prefSubtypeArray = prefSubtypes.split(
AdditionalSubtype.PREF_SUBTYPE_SEPARATOR);
for (final String prefSubtype : prefSubtypeArray) {
final InputMethodSubtype subtype =
AdditionalSubtype.createAdditionalSubtype(prefSubtype);
final SubtypePreference pref = new SubtypePreference(
context, subtype, mSubtypeProxy);
group.addPreference(pref);
}
}
private String getPrefSubtypes() {
final StringBuilder sb = new StringBuilder();
final int count = mSubtypePrefGroup.getPreferenceCount();
for (int i = 0; i < count; i++) {
final Preference pref = mSubtypePrefGroup.getPreference(i);
if (pref instanceof SubtypePreference) {
final InputMethodSubtype subtype = ((SubtypePreference)pref).getSubtype();
if (sb.length() > 0) {
sb.append(AdditionalSubtype.PREF_SUBTYPE_SEPARATOR);
}
sb.append(AdditionalSubtype.getPrefSubtype(subtype));
}
}
return sb.toString();
}
@Override
public void onResume() {
super.onResume();
final String prefSubtypes =
SettingsValues.getPrefAdditionalSubtypes(mPrefs, getResources());
setPrefSubtypes(prefSubtypes, getActivity());
}
@Override
public void onPause() {
super.onPause();
final String oldSubtypes = SettingsValues.getPrefAdditionalSubtypes(mPrefs, getResources());
final String prefSubtypes = getPrefSubtypes();
if (prefSubtypes.equals(oldSubtypes)) {
return;
}
final SharedPreferences.Editor editor = mPrefs.edit();
try {
editor.putString(Settings.PREF_CUSTOM_INPUT_STYLES, prefSubtypes);
} finally {
editor.apply();
}
final InputMethodSubtype[] subtypes =
AdditionalSubtype.createAdditionalSubtypesArray(prefSubtypes);
ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), subtypes);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// TODO: save editing dialog state.
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen prefScreen, Preference pref) {
if (pref instanceof SubtypePreference) {
return true;
}
return super.onPreferenceTreeClick(prefScreen, pref);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style);
addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
if (itemId == MENU_ADD_SUBTYPE) {
final SubtypePreference subtypePref = new SubtypePreference(
getActivity(), null, mSubtypeProxy);
mSubtypePrefGroup.addPreference(subtypePref);
subtypePref.show();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -33,6 +33,7 @@ import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
@ -255,6 +256,7 @@ public class Settings extends InputMethodSettingsFragment
}
updateShowCorrectionSuggestionsSummary();
updateKeyPreviewPopupDelaySummary();
updateCustomInputStylesSummary();
}
@Override
@ -294,6 +296,21 @@ public class Settings extends InputMethodSettingsFragment
mShowCorrectionSuggestionsPreference.getValue())]);
}
private void updateCustomInputStylesSummary() {
final PreferenceScreen customInputStyles =
(PreferenceScreen)findPreference(PREF_CUSTOM_INPUT_STYLES);
final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
final String prefSubtype = SettingsValues.getPrefAdditionalSubtypes(prefs, getResources());
final InputMethodSubtype[] subtypes =
AdditionalSubtype.createAdditionalSubtypesArray(prefSubtype);
final StringBuilder styles = new StringBuilder();
for (final InputMethodSubtype subtype : subtypes) {
if (styles.length() > 0) styles.append(", ");
styles.append(SubtypeLocale.getFullDisplayName(subtype));
}
customInputStyles.setSummary(styles);
}
private void updateKeyPreviewPopupDelaySummary() {
final ListPreference lp = mKeyPreviewPopupDismissDelay;
lp.setSummary(lp.getEntries()[lp.findIndexOfValue(lp.getValue())]);

View File

@ -20,11 +20,15 @@ import android.content.Intent;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity {
private static final String DEFAULT_FRAGMENT = Settings.class.getName();
@Override
public Intent getIntent() {
final Intent modIntent = new Intent(super.getIntent());
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, Settings.class.getName());
modIntent.putExtra(EXTRA_NO_HEADERS, true);
return modIntent;
final Intent intent = super.getIntent();
if (!intent.hasExtra(EXTRA_SHOW_FRAGMENT)) {
intent.putExtra(EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT);
}
intent.putExtra(EXTRA_NO_HEADERS, true);
return intent;
}
}

View File

@ -28,7 +28,6 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
/**
* When you call the constructor of this class, you may want to change the current system locale by
@ -148,7 +147,6 @@ public class SettingsValues {
mAutoCorrectionThresholdRawValue);
mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
mAdditionalSubtypes = AdditionalSubtype.createAdditionalSubtypesArray(
getPrefAdditionalSubtypes(prefs, res));
}

View File

@ -24,6 +24,8 @@ import java.util.HashMap;
import java.util.Locale;
public class SubtypeLocale {
private static final String TAG = SubtypeLocale.class.getSimpleName();
// Special language code to represent "no language".
public static final String NO_LANGUAGE = "zz";
@ -56,26 +58,29 @@ public class SubtypeLocale {
// zz qwerty F QWERTY QWERTY
// fr qwertz T Fr Français Français (QWERTZ)
// de qwerty T De Deutsch Deutsch (QWERTY)
// en azerty T En English English (AZERTY)
// en_US azerty T En English English (US) (AZERTY)
// zz azerty T AZERTY AZERTY
// Get InputMethodSubtype's full display name in its locale.
public static String getFullDisplayName(InputMethodSubtype subtype) {
final String value = sExceptionalDisplayNamesMap.get(subtype.getLocale());
if (value != null) {
return value;
}
if (isNoLanguage(subtype)) {
return getKeyboardLayoutSetDisplayName(subtype);
}
final String exceptionalValue = sExceptionalDisplayNamesMap.get(subtype.getLocale());
final Locale locale = getSubtypeLocale(subtype);
final String language = StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
if (AdditionalSubtype.isAdditionalSubtype(subtype)) {
return String.format("%s (%s)",
language, getKeyboardLayoutSetDisplayName(subtype));
final String language = (exceptionalValue != null) ? exceptionalValue
: StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
final String layout = getKeyboardLayoutSetDisplayName(subtype);
return String.format("%s (%s)", language, layout);
}
if (exceptionalValue != null) {
return exceptionalValue;
}
return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
}
@ -116,7 +121,11 @@ public class SubtypeLocale {
LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET);
// TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is
// fixed.
if (keyboardLayoutSet == null) return AdditionalSubtype.QWERTY;
if (keyboardLayoutSet == null) {
android.util.Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " +
getFullDisplayName(subtype) + " extraValue=" + subtype.getExtraValue());
return AdditionalSubtype.QWERTY;
}
return keyboardLayoutSet;
}
}

View File

@ -110,6 +110,7 @@ public class SubtypeLocaleTests extends AndroidTestCase {
// zz qwerty F QWERTY QWERTY
// fr qwertz T Fr Français Français (QWERTZ)
// de qwerty T De Deutsch Deutsch (QWERTY)
// en_US azerty T En English English (US) (AZERTY)
// zz azerty T AZERTY AZERTY
public void testSampleSubtypes() {
@ -168,29 +169,33 @@ public class SubtypeLocaleTests extends AndroidTestCase {
Locale.GERMAN.toString(), AdditionalSubtype.QWERTY, null);
final InputMethodSubtype FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
Locale.FRENCH.toString(), AdditionalSubtype.QWERTZ, null);
final InputMethodSubtype EN_AZERTY = AdditionalSubtype.createAdditionalSubtype(
Locale.ENGLISH.toString(), AdditionalSubtype.AZERTY, null);
final InputMethodSubtype US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
Locale.US.toString(), AdditionalSubtype.AZERTY, null);
final InputMethodSubtype ZZ_AZERTY = AdditionalSubtype.createAdditionalSubtype(
SubtypeLocale.NO_LANGUAGE, AdditionalSubtype.AZERTY, null);
assertTrue(AdditionalSubtype.isAdditionalSubtype(FR_QWERTZ));
assertTrue(AdditionalSubtype.isAdditionalSubtype(DE_QWERTY));
assertTrue(AdditionalSubtype.isAdditionalSubtype(EN_AZERTY));
assertTrue(AdditionalSubtype.isAdditionalSubtype(US_AZERTY));
assertTrue(AdditionalSubtype.isAdditionalSubtype(ZZ_AZERTY));
assertEquals("fr qwertz", "Français (QWERTZ)", SubtypeLocale.getFullDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch (QWERTY)", SubtypeLocale.getFullDisplayName(DE_QWERTY));
assertEquals("en azerty", "English (AZERTY)", SubtypeLocale.getFullDisplayName(EN_AZERTY));
assertEquals("zz azerty", "AZERTY", SubtypeLocale.getFullDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Français (QWERTZ)",
SubtypeLocale.getFullDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch (QWERTY)",
SubtypeLocale.getFullDisplayName(DE_QWERTY));
assertEquals("en_US azerty", "English (US) (AZERTY)",
SubtypeLocale.getFullDisplayName(US_AZERTY));
assertEquals("zz azerty", "AZERTY",
SubtypeLocale.getFullDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Français", SubtypeLocale.getMiddleDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch", SubtypeLocale.getMiddleDisplayName(DE_QWERTY));
assertEquals("en azerty", "English", SubtypeLocale.getMiddleDisplayName(EN_AZERTY));
assertEquals("zz azerty", "AZERTY", SubtypeLocale.getMiddleDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Français", SubtypeLocale.getMiddleDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch", SubtypeLocale.getMiddleDisplayName(DE_QWERTY));
assertEquals("en_US azerty", "English", SubtypeLocale.getMiddleDisplayName(US_AZERTY));
assertEquals("zz azerty", "AZERTY", SubtypeLocale.getMiddleDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Fr", SubtypeLocale.getShortDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "De", SubtypeLocale.getShortDisplayName(DE_QWERTY));
assertEquals("en azerty", "En", SubtypeLocale.getShortDisplayName(EN_AZERTY));
assertEquals("zz azerty", "", SubtypeLocale.getShortDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Fr", SubtypeLocale.getShortDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "De", SubtypeLocale.getShortDisplayName(DE_QWERTY));
assertEquals("en_US azerty", "En", SubtypeLocale.getShortDisplayName(US_AZERTY));
assertEquals("zz azerty", "", SubtypeLocale.getShortDisplayName(ZZ_AZERTY));
}
}