aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/settings
diff options
context:
space:
mode:
authorKen Wakasa <kwakasa@google.com>2013-07-22 08:01:11 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-07-22 08:01:11 +0000
commita6906a62483dbb2a60ef1477c46b84035a26e6b7 (patch)
tree5d45572349a42d00d8a57b81c75a7302011065a3 /java/src/com/android/inputmethod/latin/settings
parent71dc7a3876de2f8b10ca3cdc3b70015a29d2b978 (diff)
parenta7d2fc6befa1b16883200a653fc01deb4d94944d (diff)
downloadlatinime-a6906a62483dbb2a60ef1477c46b84035a26e6b7.tar.gz
latinime-a6906a62483dbb2a60ef1477c46b84035a26e6b7.tar.xz
latinime-a6906a62483dbb2a60ef1477c46b84035a26e6b7.zip
Merge "Move settings related classes to "settings""
Diffstat (limited to 'java/src/com/android/inputmethod/latin/settings')
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java47
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java602
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java133
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsActivity.java41
-rw-r--r--java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java53
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SeekBarDialogPreference.java147
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java333
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsActivity.java35
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java505
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java306
10 files changed, 2202 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
new file mode 100644
index 000000000..139f5e290
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.android.inputmethodcommon.InputMethodSettingsFragment;
+
+/**
+ * Utility class for managing additional features settings.
+ */
+public class AdditionalFeaturesSettingUtils {
+ public static final int ADDITIONAL_FEATURES_SETTINGS_SIZE = 0;
+
+ private AdditionalFeaturesSettingUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public static void addAdditionalFeaturesPreferences(
+ final Context context, final InputMethodSettingsFragment settingsFragment) {
+ // do nothing.
+ }
+
+ public static void readAdditionalFeaturesPreferencesIntoArray(
+ final SharedPreferences prefs, final int[] additionalFeaturesPreferences) {
+ // do nothing.
+ }
+
+ public static int[] getAdditionalNativeSuggestOptions() {
+ return Settings.getInstance().getCurrent().mAdditionalFeaturesSettingValues;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
new file mode 100644
index 000000000..2ef555e95
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
@@ -0,0 +1,602 @@
+/*
+ * 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.settings;
+
+import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+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.util.Pair;
+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 android.widget.Toast;
+
+import com.android.inputmethod.latin.AdditionalSubtype;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.SubtypeLocale;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.IntentUtils;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+
+public final class AdditionalSubtypeSettings extends PreferenceFragment {
+ private RichInputMethodManager mRichImm;
+ private SharedPreferences mPrefs;
+ private SubtypeLocaleAdapter mSubtypeLocaleAdapter;
+ private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter;
+
+ private boolean mIsAddingNewSubtype;
+ private AlertDialog mSubtypeEnablerNotificationDialog;
+ private String mSubtypePreferenceKeyForSubtypeEnabler;
+
+ private static final int MENU_ADD_SUBTYPE = Menu.FIRST;
+ private static final String KEY_IS_ADDING_NEW_SUBTYPE = "is_adding_new_subtype";
+ private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN =
+ "is_subtype_enabler_notification_dialog_open";
+ private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler";
+
+ static final class SubtypeLocaleItem extends Pair<String, String>
+ implements Comparable<SubtypeLocaleItem> {
+ public SubtypeLocaleItem(final String localeString, final String displayName) {
+ super(localeString, displayName);
+ }
+
+ public SubtypeLocaleItem(final String localeString) {
+ this(localeString,
+ SubtypeLocale.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
+ }
+
+ @Override
+ public String toString() {
+ return second;
+ }
+
+ @Override
+ public int compareTo(final SubtypeLocaleItem o) {
+ return first.compareTo(o.first);
+ }
+ }
+
+ static final class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> {
+ private static final String TAG = SubtypeLocaleAdapter.class.getSimpleName();
+ private static final boolean DEBUG_SUBTYPE_ID = false;
+
+ public SubtypeLocaleAdapter(final Context context) {
+ super(context, android.R.layout.simple_spinner_item);
+ setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+
+ final TreeSet<SubtypeLocaleItem> items = CollectionUtils.newTreeSet();
+ final InputMethodInfo imi = RichInputMethodManager.getInstance()
+ .getInputMethodInfoOfThisIme();
+ final int count = imi.getSubtypeCount();
+ for (int i = 0; i < count; i++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(i);
+ if (DEBUG_SUBTYPE_ID) {
+ android.util.Log.d(TAG, String.format("%-6s 0x%08x %11d %s",
+ subtype.getLocale(), subtype.hashCode(), subtype.hashCode(),
+ SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype)));
+ }
+ if (subtype.containsExtraValueKey(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(final Context context,
+ final 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 final class KeyboardLayoutSetItem extends Pair<String, String> {
+ public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
+ super(SubtypeLocale.getKeyboardLayoutSetName(subtype),
+ SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype));
+ }
+
+ @Override
+ public String toString() {
+ return second;
+ }
+ }
+
+ static final class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> {
+ public KeyboardLayoutSetAdapter(final 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 : SubtypeLocale.getPredefinedKeyboardLayoutSet()) {
+ // This is a dummy subtype with NO_LANGUAGE, only for display.
+ final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
+ SubtypeLocale.NO_LANGUAGE, layout, null);
+ add(new KeyboardLayoutSetItem(subtype));
+ }
+ }
+ }
+
+ private interface SubtypeDialogProxy {
+ public void onRemovePressed(SubtypePreference subtypePref);
+ public void onSavePressed(SubtypePreference subtypePref);
+ public void onAddPressed(SubtypePreference subtypePref);
+ public SubtypeLocaleAdapter getSubtypeLocaleAdapter();
+ public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter();
+ }
+
+ static final class SubtypePreference extends DialogPreference
+ implements DialogInterface.OnCancelListener {
+ private static final String KEY_PREFIX = "subtype_pref_";
+ private static final String KEY_NEW_SUBTYPE = KEY_PREFIX + "new";
+
+ private InputMethodSubtype mSubtype;
+ private InputMethodSubtype mPreviousSubtype;
+
+ private final SubtypeDialogProxy mProxy;
+ private Spinner mSubtypeLocaleSpinner;
+ private Spinner mKeyboardLayoutSetSpinner;
+
+ public static SubtypePreference newIncompleteSubtypePreference(final Context context,
+ final SubtypeDialogProxy proxy) {
+ return new SubtypePreference(context, null, proxy);
+ }
+
+ public SubtypePreference(final Context context, final InputMethodSubtype subtype,
+ final SubtypeDialogProxy proxy) {
+ super(context, null);
+ setDialogLayoutResource(R.layout.additional_subtype_dialog);
+ setPersistent(false);
+ mProxy = proxy;
+ setSubtype(subtype);
+ }
+
+ public void show() {
+ showDialog(null);
+ }
+
+ public final boolean isIncomplete() {
+ return mSubtype == null;
+ }
+
+ public InputMethodSubtype getSubtype() {
+ return mSubtype;
+ }
+
+ public void setSubtype(final InputMethodSubtype subtype) {
+ mPreviousSubtype = mSubtype;
+ mSubtype = subtype;
+ if (isIncomplete()) {
+ setTitle(null);
+ setDialogTitle(R.string.add_style);
+ setKey(KEY_NEW_SUBTYPE);
+ } else {
+ final String displayName =
+ SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
+ setTitle(displayName);
+ setDialogTitle(displayName);
+ setKey(KEY_PREFIX + subtype.getLocale() + "_"
+ + SubtypeLocale.getKeyboardLayoutSetName(subtype));
+ }
+ }
+
+ public void revert() {
+ setSubtype(mPreviousSubtype);
+ }
+
+ public boolean hasBeenModified() {
+ return mSubtype != null && !mSubtype.equals(mPreviousSubtype);
+ }
+
+ @Override
+ protected View onCreateDialogView() {
+ final View v = super.onCreateDialogView();
+ 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());
+ return v;
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
+ final Context context = builder.getContext();
+ builder.setCancelable(true).setOnCancelListener(this);
+ if (isIncomplete()) {
+ 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(mSubtype);
+ setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
+ setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
+ }
+ }
+
+ private static void setSpinnerPosition(final Spinner spinner, final 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 onCancel(final DialogInterface dialog) {
+ if (isIncomplete()) {
+ mProxy.onRemovePressed(this);
+ }
+ }
+
+ @Override
+ public void onClick(final DialogInterface dialog, final int which) {
+ super.onClick(dialog, which);
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ final boolean isEditing = !isIncomplete();
+ final SubtypeLocaleItem locale =
+ (SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem();
+ final KeyboardLayoutSetItem layout =
+ (KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
+ final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
+ locale.first, layout.first, ASCII_CAPABLE);
+ setSubtype(subtype);
+ notifyChanged();
+ if (isEditing) {
+ mProxy.onSavePressed(this);
+ } else {
+ mProxy.onAddPressed(this);
+ }
+ break;
+ case DialogInterface.BUTTON_NEUTRAL:
+ // Nothing to do
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ mProxy.onRemovePressed(this);
+ break;
+ }
+ }
+
+ private static int getSpinnerPosition(final Spinner spinner) {
+ if (spinner == null) return -1;
+ return spinner.getSelectedItemPosition();
+ }
+
+ private static void setSpinnerPosition(final Spinner spinner, final int position) {
+ if (spinner == null || position < 0) return;
+ spinner.setSelection(position);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ final Dialog dialog = getDialog();
+ if (dialog == null || !dialog.isShowing()) {
+ return superState;
+ }
+
+ final SavedState myState = new SavedState(superState);
+ myState.mSubtype = mSubtype;
+ myState.mSubtypeLocaleSelectedPos = getSpinnerPosition(mSubtypeLocaleSpinner);
+ myState.mKeyboardLayoutSetSelectedPos = getSpinnerPosition(mKeyboardLayoutSetSpinner);
+ return myState;
+ }
+
+ @Override
+ protected void onRestoreInstanceState(final Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ final SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+ setSpinnerPosition(mSubtypeLocaleSpinner, myState.mSubtypeLocaleSelectedPos);
+ setSpinnerPosition(mKeyboardLayoutSetSpinner, myState.mKeyboardLayoutSetSelectedPos);
+ setSubtype(myState.mSubtype);
+ }
+
+ static final class SavedState extends Preference.BaseSavedState {
+ InputMethodSubtype mSubtype;
+ int mSubtypeLocaleSelectedPos;
+ int mKeyboardLayoutSetSelectedPos;
+
+ public SavedState(final Parcelable superState) {
+ super(superState);
+ }
+
+ @Override
+ public void writeToParcel(final Parcel dest, final int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mSubtypeLocaleSelectedPos);
+ dest.writeInt(mKeyboardLayoutSetSelectedPos);
+ dest.writeParcelable(mSubtype, 0);
+ }
+
+ public SavedState(final Parcel source) {
+ super(source);
+ mSubtypeLocaleSelectedPos = source.readInt();
+ mKeyboardLayoutSetSelectedPos = source.readInt();
+ mSubtype = (InputMethodSubtype)source.readParcelable(null);
+ }
+
+ @SuppressWarnings("hiding")
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ @Override
+ public SavedState createFromParcel(final Parcel source) {
+ return new SavedState(source);
+ }
+
+ @Override
+ public SavedState[] newArray(final int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+ }
+
+ public AdditionalSubtypeSettings() {
+ // Empty constructor for fragment generation.
+ }
+
+ @Override
+ public void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mPrefs = getPreferenceManager().getSharedPreferences();
+ RichInputMethodManager.init(getActivity());
+ mRichImm = RichInputMethodManager.getInstance();
+ addPreferencesFromResource(R.xml.additional_subtype_settings);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onActivityCreated(final Bundle savedInstanceState) {
+ final Context context = getActivity();
+ mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context);
+ mKeyboardLayoutSetAdapter = new KeyboardLayoutSetAdapter(context);
+
+ final String prefSubtypes =
+ Settings.readPrefAdditionalSubtypes(mPrefs, getResources());
+ setPrefSubtypes(prefSubtypes, context);
+
+ mIsAddingNewSubtype = (savedInstanceState != null)
+ && savedInstanceState.containsKey(KEY_IS_ADDING_NEW_SUBTYPE);
+ if (mIsAddingNewSubtype) {
+ getPreferenceScreen().addPreference(
+ SubtypePreference.newIncompleteSubtypePreference(context, mSubtypeProxy));
+ }
+
+ super.onActivityCreated(savedInstanceState);
+
+ if (savedInstanceState != null && savedInstanceState.containsKey(
+ KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN)) {
+ mSubtypePreferenceKeyForSubtypeEnabler = savedInstanceState.getString(
+ KEY_SUBTYPE_FOR_SUBTYPE_ENABLER);
+ final SubtypePreference subtypePref = (SubtypePreference)findPreference(
+ mSubtypePreferenceKeyForSubtypeEnabler);
+ mSubtypeEnablerNotificationDialog = createDialog(subtypePref);
+ mSubtypeEnablerNotificationDialog.show();
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (mIsAddingNewSubtype) {
+ outState.putBoolean(KEY_IS_ADDING_NEW_SUBTYPE, true);
+ }
+ if (mSubtypeEnablerNotificationDialog != null
+ && mSubtypeEnablerNotificationDialog.isShowing()) {
+ outState.putBoolean(KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN, true);
+ outState.putString(
+ KEY_SUBTYPE_FOR_SUBTYPE_ENABLER, mSubtypePreferenceKeyForSubtypeEnabler);
+ }
+ }
+
+ private final SubtypeDialogProxy mSubtypeProxy = new SubtypeDialogProxy() {
+ @Override
+ public void onRemovePressed(final SubtypePreference subtypePref) {
+ mIsAddingNewSubtype = false;
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removePreference(subtypePref);
+ mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ }
+
+ @Override
+ public void onSavePressed(final SubtypePreference subtypePref) {
+ final InputMethodSubtype subtype = subtypePref.getSubtype();
+ if (!subtypePref.hasBeenModified()) {
+ return;
+ }
+ if (findDuplicatedSubtype(subtype) == null) {
+ mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ return;
+ }
+
+ // Saved subtype is duplicated.
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removePreference(subtypePref);
+ subtypePref.revert();
+ group.addPreference(subtypePref);
+ showSubtypeAlreadyExistsToast(subtype);
+ }
+
+ @Override
+ public void onAddPressed(final SubtypePreference subtypePref) {
+ mIsAddingNewSubtype = false;
+ final InputMethodSubtype subtype = subtypePref.getSubtype();
+ if (findDuplicatedSubtype(subtype) == null) {
+ mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ mSubtypePreferenceKeyForSubtypeEnabler = subtypePref.getKey();
+ mSubtypeEnablerNotificationDialog = createDialog(subtypePref);
+ mSubtypeEnablerNotificationDialog.show();
+ return;
+ }
+
+ // Newly added subtype is duplicated.
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removePreference(subtypePref);
+ showSubtypeAlreadyExistsToast(subtype);
+ }
+
+ @Override
+ public SubtypeLocaleAdapter getSubtypeLocaleAdapter() {
+ return mSubtypeLocaleAdapter;
+ }
+
+ @Override
+ public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter() {
+ return mKeyboardLayoutSetAdapter;
+ }
+ };
+
+ private void showSubtypeAlreadyExistsToast(final InputMethodSubtype subtype) {
+ final Context context = getActivity();
+ final Resources res = context.getResources();
+ final String message = res.getString(R.string.custom_input_style_already_exists,
+ SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype));
+ Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
+ }
+
+ private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) {
+ final String localeString = subtype.getLocale();
+ final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
+ return mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ localeString, keyboardLayoutSetName);
+ }
+
+ private AlertDialog createDialog(
+ @SuppressWarnings("unused") final SubtypePreference subtypePref) {
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.custom_input_styles_title)
+ .setMessage(R.string.custom_input_style_note_message)
+ .setNegativeButton(R.string.not_now, null)
+ .setPositiveButton(R.string.enable, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final Intent intent = IntentUtils.getInputLanguageSelectionIntent(
+ mRichImm.getInputMethodIdOfThisIme(),
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ // TODO: Add newly adding subtype to extra value of the intent as a hint
+ // for the input language selection activity.
+ // intent.putExtra("newlyAddedSubtype", subtypePref.getSubtype());
+ startActivity(intent);
+ }
+ });
+
+ return builder.create();
+ }
+
+ private void setPrefSubtypes(final String prefSubtypes, final Context context) {
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removeAll();
+ final InputMethodSubtype[] subtypesArray =
+ AdditionalSubtype.createAdditionalSubtypesArray(prefSubtypes);
+ for (final InputMethodSubtype subtype : subtypesArray) {
+ final SubtypePreference pref = new SubtypePreference(
+ context, subtype, mSubtypeProxy);
+ group.addPreference(pref);
+ }
+ }
+
+ private InputMethodSubtype[] getSubtypes() {
+ final PreferenceGroup group = getPreferenceScreen();
+ final ArrayList<InputMethodSubtype> subtypes = CollectionUtils.newArrayList();
+ final int count = group.getPreferenceCount();
+ for (int i = 0; i < count; i++) {
+ final Preference pref = group.getPreference(i);
+ if (pref instanceof SubtypePreference) {
+ final SubtypePreference subtypePref = (SubtypePreference)pref;
+ // We should not save newly adding subtype to preference because it is incomplete.
+ if (subtypePref.isIncomplete()) continue;
+ subtypes.add(subtypePref.getSubtype());
+ }
+ }
+ return subtypes.toArray(new InputMethodSubtype[subtypes.size()]);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ final String oldSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources());
+ final InputMethodSubtype[] subtypes = getSubtypes();
+ final String prefSubtypes = AdditionalSubtype.createPrefSubtypes(subtypes);
+ if (prefSubtypes.equals(oldSubtypes)) {
+ return;
+ }
+ Settings.writePrefAdditionalSubtypes(mPrefs, prefSubtypes);
+ mRichImm.setAdditionalInputMethodSubtypes(subtypes);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(final Menu menu, final 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(final MenuItem item) {
+ final int itemId = item.getItemId();
+ if (itemId == MENU_ADD_SUBTYPE) {
+ final SubtypePreference newSubtype =
+ SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy);
+ getPreferenceScreen().addPreference(newSubtype);
+ newSubtype.show();
+ mIsAddingNewSubtype = true;
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
new file mode 100644
index 000000000..34ea2279d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of 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.settings;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Process;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug;
+import com.android.inputmethod.latin.utils.ApplicationUtils;
+
+public final class DebugSettings extends PreferenceFragment
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final String TAG = DebugSettings.class.getSimpleName();
+
+ public static final String PREF_DEBUG_MODE = "debug_mode";
+ public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
+ public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
+ public static final String PREF_STATISTICS_LOGGING = "enable_logging";
+ private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary";
+ private static final boolean SHOW_STATISTICS_LOGGING = false;
+
+ private boolean mServiceNeedsRestart = false;
+ private CheckBoxPreference mDebugMode;
+ private CheckBoxPreference mStatisticsLoggingPref;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_for_debug);
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+
+ final Preference usabilityStudyPref = findPreference(PREF_USABILITY_STUDY_MODE);
+ if (usabilityStudyPref instanceof CheckBoxPreference) {
+ final CheckBoxPreference checkbox = (CheckBoxPreference)usabilityStudyPref;
+ checkbox.setChecked(prefs.getBoolean(PREF_USABILITY_STUDY_MODE,
+ LatinImeLogger.getUsabilityStudyMode(prefs)));
+ checkbox.setSummary(R.string.settings_warning_researcher_mode);
+ }
+ final Preference statisticsLoggingPref = findPreference(PREF_STATISTICS_LOGGING);
+ if (statisticsLoggingPref instanceof CheckBoxPreference) {
+ mStatisticsLoggingPref = (CheckBoxPreference) statisticsLoggingPref;
+ if (!SHOW_STATISTICS_LOGGING) {
+ getPreferenceScreen().removePreference(statisticsLoggingPref);
+ }
+ }
+
+ PreferenceScreen readExternalDictionary =
+ (PreferenceScreen) findPreference(PREF_READ_EXTERNAL_DICTIONARY);
+ if (null != readExternalDictionary) {
+ readExternalDictionary.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(final Preference arg0) {
+ ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(
+ getActivity());
+ mServiceNeedsRestart = true;
+ return true;
+ }
+ });
+ }
+
+ mServiceNeedsRestart = false;
+ mDebugMode = (CheckBoxPreference) findPreference(PREF_DEBUG_MODE);
+ updateDebugMode();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (mServiceNeedsRestart) Process.killProcess(Process.myPid());
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (key.equals(PREF_DEBUG_MODE)) {
+ if (mDebugMode != null) {
+ mDebugMode.setChecked(prefs.getBoolean(PREF_DEBUG_MODE, false));
+ final boolean checked = mDebugMode.isChecked();
+ if (mStatisticsLoggingPref != null) {
+ if (checked) {
+ getPreferenceScreen().addPreference(mStatisticsLoggingPref);
+ } else {
+ getPreferenceScreen().removePreference(mStatisticsLoggingPref);
+ }
+ }
+ updateDebugMode();
+ mServiceNeedsRestart = true;
+ }
+ } else if (key.equals(PREF_FORCE_NON_DISTINCT_MULTITOUCH)
+ || key.equals(KeyboardSwitcher.PREF_KEYBOARD_LAYOUT)) {
+ mServiceNeedsRestart = true;
+ }
+ }
+
+ private void updateDebugMode() {
+ if (mDebugMode == null) {
+ return;
+ }
+ boolean isDebugMode = mDebugMode.isChecked();
+ final String version = getResources().getString(
+ R.string.version_text, ApplicationUtils.getVersionName(getActivity()));
+ if (!isDebugMode) {
+ mDebugMode.setTitle(version);
+ mDebugMode.setSummary("");
+ } else {
+ mDebugMode.setTitle(getResources().getString(R.string.prefs_debug_mode));
+ mDebugMode.setSummary(version);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsActivity.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsActivity.java
new file mode 100644
index 000000000..b499c26b6
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsActivity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.settings;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+import com.android.inputmethod.latin.R;
+
+public final class DebugSettingsActivity extends PreferenceActivity {
+ private static final String DEFAULT_FRAGMENT = DebugSettings.class.getName();
+
+ @Override
+ public Intent getIntent() {
+ final Intent intent = super.getIntent();
+ intent.putExtra(EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT);
+ intent.putExtra(EXTRA_NO_HEADERS, true);
+ return intent;
+ }
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTitle(R.string.english_ime_debug_settings);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
new file mode 100644
index 000000000..878c505bd
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+public class NativeSuggestOptions {
+ // Need to update suggest_options.h when you add, remove or reorder options.
+ private static final int IS_GESTURE = 0;
+ private static final int USE_FULL_EDIT_DISTANCE = 1;
+ private static final int OPTIONS_SIZE = 2;
+
+ private final int[] mOptions = new int[OPTIONS_SIZE
+ + AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
+
+ public void setIsGesture(final boolean value) {
+ setBooleanOption(IS_GESTURE, value);
+ }
+
+ public void setUseFullEditDistance(final boolean value) {
+ setBooleanOption(USE_FULL_EDIT_DISTANCE, value);
+ }
+
+ public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
+ for (int i = 0; i < additionalOptions.length; i++) {
+ setIntegerOption(OPTIONS_SIZE + i, additionalOptions[i]);
+ }
+ }
+
+ public int[] getOptions() {
+ return mOptions;
+ }
+
+ private void setBooleanOption(final int key, final boolean value) {
+ mOptions[key] = value ? 1 : 0;
+ }
+
+ private void setIntegerOption(final int key, final int value) {
+ mOptions[key] = value;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/SeekBarDialogPreference.java b/java/src/com/android/inputmethod/latin/settings/SeekBarDialogPreference.java
new file mode 100644
index 000000000..802574aa8
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SeekBarDialogPreference.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.TypedArray;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.android.inputmethod.latin.R;
+
+public final class SeekBarDialogPreference extends DialogPreference
+ implements SeekBar.OnSeekBarChangeListener {
+ public interface ValueProxy {
+ public int readValue(final String key);
+ public int readDefaultValue(final String key);
+ public void writeValue(final int value, final String key);
+ public void writeDefaultValue(final String key);
+ public String getValueText(final int value);
+ public void feedbackValue(final int value);
+ }
+
+ private final int mMaxValue;
+ private final int mMinValue;
+ private final int mStepValue;
+
+ private TextView mValueView;
+ private SeekBar mSeekBar;
+
+ private ValueProxy mValueProxy;
+
+ public SeekBarDialogPreference(final Context context, final AttributeSet attrs) {
+ super(context, attrs);
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.SeekBarDialogPreference, 0, 0);
+ mMaxValue = a.getInt(R.styleable.SeekBarDialogPreference_maxValue, 0);
+ mMinValue = a.getInt(R.styleable.SeekBarDialogPreference_minValue, 0);
+ mStepValue = a.getInt(R.styleable.SeekBarDialogPreference_stepValue, 0);
+ a.recycle();
+ setDialogLayoutResource(R.layout.seek_bar_dialog);
+ }
+
+ public void setInterface(final ValueProxy proxy) {
+ mValueProxy = proxy;
+ final int value = mValueProxy.readValue(getKey());
+ setSummary(mValueProxy.getValueText(value));
+ }
+
+ @Override
+ protected View onCreateDialogView() {
+ final View view = super.onCreateDialogView();
+ mSeekBar = (SeekBar)view.findViewById(R.id.seek_bar_dialog_bar);
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ mSeekBar.setOnSeekBarChangeListener(this);
+ mValueView = (TextView)view.findViewById(R.id.seek_bar_dialog_value);
+ return view;
+ }
+
+ private int getProgressFromValue(final int value) {
+ return value - mMinValue;
+ }
+
+ private int getValueFromProgress(final int progress) {
+ return progress + mMinValue;
+ }
+
+ private int clipValue(final int value) {
+ final int clippedValue = Math.min(mMaxValue, Math.max(mMinValue, value));
+ if (mStepValue <= 1) {
+ return clippedValue;
+ }
+ return clippedValue - (clippedValue % mStepValue);
+ }
+
+ private int getClippedValueFromProgress(final int progress) {
+ return clipValue(getValueFromProgress(progress));
+ }
+
+ @Override
+ protected void onBindDialogView(final View view) {
+ final int value = mValueProxy.readValue(getKey());
+ mValueView.setText(mValueProxy.getValueText(value));
+ mSeekBar.setProgress(getProgressFromValue(clipValue(value)));
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
+ builder.setPositiveButton(android.R.string.ok, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .setNeutralButton(R.string.button_default, this);
+ }
+
+ @Override
+ public void onClick(final DialogInterface dialog, final int which) {
+ super.onClick(dialog, which);
+ final String key = getKey();
+ if (which == DialogInterface.BUTTON_NEUTRAL) {
+ final int value = mValueProxy.readDefaultValue(key);
+ setSummary(mValueProxy.getValueText(value));
+ mValueProxy.writeDefaultValue(key);
+ return;
+ }
+ if (which == DialogInterface.BUTTON_POSITIVE) {
+ final int value = getClippedValueFromProgress(mSeekBar.getProgress());
+ setSummary(mValueProxy.getValueText(value));
+ mValueProxy.writeValue(value, key);
+ return;
+ }
+ }
+
+ @Override
+ public void onProgressChanged(final SeekBar seekBar, final int progress,
+ final boolean fromUser) {
+ final int value = getClippedValueFromProgress(progress);
+ mValueView.setText(mValueProxy.getValueText(value));
+ if (!fromUser) {
+ mSeekBar.setProgress(getProgressFromValue(value));
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(final SeekBar seekBar) {}
+
+ @Override
+ public void onStopTrackingTouch(final SeekBar seekBar) {
+ mValueProxy.feedbackValue(getClippedValueFromProgress(seekBar.getProgress()));
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
new file mode 100644
index 000000000..674263dee
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2013 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.settings;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.res.Resources;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
+import com.android.inputmethod.latin.AdditionalSubtype;
+import com.android.inputmethod.latin.InputAttributes;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final String TAG = Settings.class.getSimpleName();
+ // In the same order as xml/prefs.xml
+ public static final String PREF_GENERAL_SETTINGS = "general_settings";
+ public static final String PREF_AUTO_CAP = "auto_cap";
+ public static final String PREF_VIBRATE_ON = "vibrate_on";
+ public static final String PREF_SOUND_ON = "sound_on";
+ public static final String PREF_POPUP_ON = "popup_on";
+ public static final String PREF_VOICE_MODE = "voice_mode";
+ public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
+ public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
+ public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
+ public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
+ public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting";
+ public static final String PREF_MISC_SETTINGS = "misc_settings";
+ public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME =
+ "last_user_dictionary_write_time";
+ public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
+ public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
+ public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD =
+ "pref_key_use_double_space_period";
+ public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE =
+ "pref_key_block_potentially_offensive";
+ public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
+ "pref_show_language_switch_key";
+ public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
+ "pref_include_other_imes_in_language_switch_list";
+ public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
+ public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
+ "pref_key_preview_popup_dismiss_delay";
+ public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
+ public static final String PREF_GESTURE_SETTINGS = "gesture_typing_settings";
+ public static final String PREF_GESTURE_INPUT = "gesture_input";
+ public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
+ public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
+ public static final String PREF_VIBRATION_DURATION_SETTINGS =
+ "pref_vibration_duration_settings";
+ public static final String PREF_KEYPRESS_SOUND_VOLUME =
+ "pref_keypress_sound_volume";
+ public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail";
+ public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
+ "pref_gesture_floating_preview_text";
+ public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
+
+ public static final String PREF_INPUT_LANGUAGE = "input_language";
+ public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
+ public static final String PREF_DEBUG_SETTINGS = "debug_settings";
+ public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
+
+ // This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead.
+ // This is being used only for the backward compatibility.
+ private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
+ "pref_suppress_language_switch_key";
+
+ public static final String PREF_SEND_FEEDBACK = "send_feedback";
+ public static final String PREF_ABOUT_KEYBOARD = "about_keyboard";
+
+ private Resources mRes;
+ private SharedPreferences mPrefs;
+ private Locale mCurrentLocale;
+ private SettingsValues mSettingsValues;
+
+ private static final Settings sInstance = new Settings();
+
+ public static Settings getInstance() {
+ return sInstance;
+ }
+
+ public static void init(final Context context) {
+ sInstance.onCreate(context);
+ }
+
+ private Settings() {
+ // Intentional empty constructor for singleton.
+ }
+
+ private void onCreate(final Context context) {
+ mRes = context.getResources();
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ mPrefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ public void onDestroy() {
+ mPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+ if (mSettingsValues == null) {
+ // TODO: Introduce a static function to register this class and ensure that
+ // loadSettings must be called before "onSharedPreferenceChanged" is called.
+ Log.w(TAG, "onSharedPreferenceChanged called before loadSettings.");
+ return;
+ }
+ loadSettings(mCurrentLocale, mSettingsValues.mInputAttributes);
+ }
+
+ public void loadSettings(final Locale locale, final InputAttributes inputAttributes) {
+ mCurrentLocale = locale;
+ final SharedPreferences prefs = mPrefs;
+ final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() {
+ @Override
+ protected SettingsValues job(final Resources res) {
+ return new SettingsValues(prefs, res, inputAttributes);
+ }
+ };
+ mSettingsValues = job.runInLocale(mRes, locale);
+ }
+
+ // TODO: Remove this method and add proxy method to SettingsValues.
+ public SettingsValues getCurrent() {
+ return mSettingsValues;
+ }
+
+ public boolean isInternal() {
+ return mSettingsValues.mIsInternal;
+ }
+
+ public String getWordSeparators() {
+ return mSettingsValues.mWordSeparators;
+ }
+
+ public boolean isWordSeparator(final int code) {
+ return mSettingsValues.isWordSeparator(code);
+ }
+
+ public Locale getCurrentLocale() {
+ return mCurrentLocale;
+ }
+
+ public boolean getBlockPotentiallyOffensive() {
+ return mSettingsValues.mBlockPotentiallyOffensive;
+ }
+
+ // Accessed from the settings interface, hence public
+ public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_SOUND_ON,
+ res.getBoolean(R.bool.config_default_sound_enabled));
+ }
+
+ public static boolean readVibrationEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ final boolean hasVibrator = AudioAndHapticFeedbackManager.getInstance().hasVibrator();
+ return hasVibrator && prefs.getBoolean(PREF_VIBRATE_ON,
+ res.getBoolean(R.bool.config_default_vibration_enabled));
+ }
+
+ public static boolean readAutoCorrectEnabled(final String currentAutoCorrectionSetting,
+ final Resources res) {
+ final String autoCorrectionOff = res.getString(
+ R.string.auto_correction_threshold_mode_index_off);
+ return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
+ }
+
+ public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE,
+ res.getBoolean(R.bool.config_block_potentially_offensive));
+ }
+
+ public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) {
+ return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config);
+ }
+
+ public static boolean readGestureInputEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return readFromBuildConfigIfGestureInputEnabled(res)
+ && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
+ }
+
+ public static boolean readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(
+ final Resources res) {
+ return res.getBoolean(R.bool.config_enable_show_option_of_key_preview_popup);
+ }
+
+ public static boolean readKeyPreviewPopupEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ final boolean defaultKeyPreviewPopup = res.getBoolean(
+ R.bool.config_default_key_preview_popup);
+ if (!readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+ return defaultKeyPreviewPopup;
+ }
+ return prefs.getBoolean(PREF_POPUP_ON, defaultKeyPreviewPopup);
+ }
+
+ public static int readKeyPreviewPopupDismissDelay(final SharedPreferences prefs,
+ final Resources res) {
+ return Integer.parseInt(prefs.getString(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Integer.toString(res.getInteger(
+ R.integer.config_key_preview_linger_timeout))));
+ }
+
+ public static boolean readShowsLanguageSwitchKey(final SharedPreferences prefs) {
+ if (prefs.contains(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) {
+ final boolean suppressLanguageSwitchKey = prefs.getBoolean(
+ PREF_SUPPRESS_LANGUAGE_SWITCH_KEY, false);
+ final SharedPreferences.Editor editor = prefs.edit();
+ editor.remove(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY);
+ editor.putBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, !suppressLanguageSwitchKey);
+ editor.apply();
+ }
+ return prefs.getBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, true);
+ }
+
+ public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
+ final Resources res) {
+ final String predefinedPrefSubtypes = AdditionalSubtype.createPrefSubtypes(
+ res.getStringArray(R.array.predefined_subtypes));
+ return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes);
+ }
+
+ public static void writePrefAdditionalSubtypes(final SharedPreferences prefs,
+ final String prefSubtypes) {
+ prefs.edit().putString(Settings.PREF_CUSTOM_INPUT_STYLES, prefSubtypes).apply();
+ }
+
+ public static float readKeypressSoundVolume(final SharedPreferences prefs,
+ final Resources res) {
+ final float volume = prefs.getFloat(PREF_KEYPRESS_SOUND_VOLUME, -1.0f);
+ return (volume >= 0) ? volume : readDefaultKeypressSoundVolume(res);
+ }
+
+ public static float readDefaultKeypressSoundVolume(final Resources res) {
+ return Float.parseFloat(
+ ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_volumes));
+ }
+
+ public static int readKeyLongpressTimeout(final SharedPreferences prefs,
+ final Resources res) {
+ final int ms = prefs.getInt(PREF_KEY_LONGPRESS_TIMEOUT, -1);
+ return (ms >= 0) ? ms : readDefaultKeyLongpressTimeout(res);
+ }
+
+ public static int readDefaultKeyLongpressTimeout(final Resources res) {
+ return res.getInteger(R.integer.config_default_longpress_key_timeout);
+ }
+
+ public static int readKeypressVibrationDuration(final SharedPreferences prefs,
+ final Resources res) {
+ final int ms = prefs.getInt(PREF_VIBRATION_DURATION_SETTINGS, -1);
+ return (ms >= 0) ? ms : readDefaultKeypressVibrationDuration(res);
+ }
+
+ public static int readDefaultKeypressVibrationDuration(final Resources res) {
+ return Integer.parseInt(
+ ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_vibration_durations));
+ }
+
+ public static boolean readUsabilityStudyMode(final SharedPreferences prefs) {
+ return prefs.getBoolean(DebugSettings.PREF_USABILITY_STUDY_MODE, true);
+ }
+
+ public static long readLastUserHistoryWriteTime(final SharedPreferences prefs,
+ final String locale) {
+ final String str = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, "");
+ final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(str);
+ if (map.containsKey(locale)) {
+ return map.get(locale);
+ }
+ return 0;
+ }
+
+ public static void writeLastUserHistoryWriteTime(final SharedPreferences prefs,
+ final String locale) {
+ final String oldStr = prefs.getString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, "");
+ final HashMap<String, Long> map = LocaleUtils.localeAndTimeStrToHashMap(oldStr);
+ map.put(locale, System.currentTimeMillis());
+ final String newStr = LocaleUtils.localeAndTimeHashMapToStr(map);
+ prefs.edit().putString(PREF_LAST_USER_DICTIONARY_WRITE_TIME, newStr).apply();
+ }
+
+ public static boolean readUseFullscreenMode(final Resources res) {
+ return res.getBoolean(R.bool.config_use_fullscreen_mode);
+ }
+
+ public static boolean readShowSetupWizardIcon(final SharedPreferences prefs,
+ final Context context) {
+ final boolean enableSetupWizardByConfig = context.getResources().getBoolean(
+ R.bool.config_setup_wizard_available);
+ if (!enableSetupWizardByConfig) {
+ return false;
+ }
+ if (!prefs.contains(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) {
+ final ApplicationInfo appInfo = context.getApplicationInfo();
+ final boolean isApplicationInSystemImage =
+ (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ // Default value
+ return !isApplicationInSystemImage;
+ }
+ return prefs.getBoolean(Settings.PREF_SHOW_SETUP_WIZARD_ICON, false);
+ }
+
+ public static boolean isInternal(final SharedPreferences prefs) {
+ return prefs.getBoolean(Settings.PREF_KEY_IS_INTERNAL, false);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
new file mode 100644
index 000000000..6c3818651
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
@@ -0,0 +1,35 @@
+/*
+ * 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.settings;
+
+import android.content.Intent;
+import android.preference.PreferenceActivity;
+
+public final class SettingsActivity extends PreferenceActivity {
+ private static final String DEFAULT_FRAGMENT = SettingsFragment.class.getName();
+
+ @Override
+ public Intent getIntent() {
+ final Intent intent = super.getIntent();
+ final String fragment = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
+ if (fragment == null) {
+ intent.putExtra(EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT);
+ }
+ intent.putExtra(EXTRA_NO_HEADERS, true);
+ return intent;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
new file mode 100644
index 000000000..4b62a5389
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of 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.settings;
+
+import android.app.Activity;
+import android.app.backup.BackupManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
+import com.android.inputmethod.latin.AdditionalSubtype;
+import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeLocale;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.define.ProductionFlag;
+import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
+import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
+import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
+import com.android.inputmethod.latin.utils.ApplicationUtils;
+import com.android.inputmethod.latin.utils.FeedbackUtils;
+import com.android.inputmethod.research.ResearchLogger;
+import com.android.inputmethodcommon.InputMethodSettingsFragment;
+
+import java.util.TreeSet;
+
+public final class SettingsFragment extends InputMethodSettingsFragment
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
+ private static final String TAG = SettingsFragment.class.getSimpleName();
+ private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false;
+ private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS =
+ DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
+ || Build.VERSION.SDK_INT <= 18 /* Build.VERSION.JELLY_BEAN_MR2 */;
+
+ private ListPreference mVoicePreference;
+ private ListPreference mShowCorrectionSuggestionsPreference;
+ private ListPreference mAutoCorrectionThresholdPreference;
+ private ListPreference mKeyPreviewPopupDismissDelay;
+ // Use bigrams to predict the next word when there is no input for it yet
+ private CheckBoxPreference mBigramPrediction;
+
+ private void setPreferenceEnabled(final String preferenceKey, final boolean enabled) {
+ final Preference preference = findPreference(preferenceKey);
+ if (preference != null) {
+ preference.setEnabled(enabled);
+ }
+ }
+
+ private static void removePreference(final String preferenceKey, final PreferenceGroup parent) {
+ if (parent == null) {
+ return;
+ }
+ final Preference preference = parent.findPreference(preferenceKey);
+ if (preference != null) {
+ parent.removePreference(preference);
+ }
+ }
+
+ @Override
+ public void onCreate(final Bundle icicle) {
+ super.onCreate(icicle);
+ setInputMethodSettingsCategoryTitle(R.string.language_selection_title);
+ setSubtypeEnablerTitle(R.string.select_language);
+ addPreferencesFromResource(R.xml.prefs);
+ final PreferenceScreen preferenceScreen = getPreferenceScreen();
+ if (preferenceScreen != null) {
+ preferenceScreen.setTitle(
+ ApplicationUtils.getAcitivityTitleResId(getActivity(), SettingsActivity.class));
+ }
+
+ final Resources res = getResources();
+ final Context context = getActivity();
+
+ // When we are called from the Settings application but we are not already running, some
+ // singleton and utility classes may not have been initialized. We have to call
+ // initialization method of these classes here. See {@link LatinIME#onCreate()}.
+ SubtypeSwitcher.init(context);
+ SubtypeLocale.init(context);
+ AudioAndHapticFeedbackManager.init(context);
+
+ mVoicePreference = (ListPreference) findPreference(Settings.PREF_VOICE_MODE);
+ mShowCorrectionSuggestionsPreference =
+ (ListPreference) findPreference(Settings.PREF_SHOW_SUGGESTIONS_SETTING);
+ final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ prefs.registerOnSharedPreferenceChangeListener(this);
+
+ mAutoCorrectionThresholdPreference =
+ (ListPreference) findPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD);
+ mBigramPrediction = (CheckBoxPreference) findPreference(Settings.PREF_BIGRAM_PREDICTIONS);
+ ensureConsistencyOfAutoCorrectionSettings();
+
+ final PreferenceGroup generalSettings =
+ (PreferenceGroup) findPreference(Settings.PREF_GENERAL_SETTINGS);
+ final PreferenceGroup miscSettings =
+ (PreferenceGroup) findPreference(Settings.PREF_MISC_SETTINGS);
+
+ final Preference debugSettings = findPreference(Settings.PREF_DEBUG_SETTINGS);
+ if (debugSettings != null) {
+ if (Settings.isInternal(prefs)) {
+ final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
+ debugSettingsIntent.setClassName(
+ context.getPackageName(), DebugSettingsActivity.class.getName());
+ debugSettings.setIntent(debugSettingsIntent);
+ } else {
+ miscSettings.removePreference(debugSettings);
+ }
+ }
+
+ final Preference feedbackSettings = findPreference(Settings.PREF_SEND_FEEDBACK);
+ final Preference aboutSettings = findPreference(Settings.PREF_ABOUT_KEYBOARD);
+ if (feedbackSettings != null) {
+ if (FeedbackUtils.isFeedbackFormSupported()) {
+ feedbackSettings.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(final Preference pref) {
+ if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+ // Use development-only feedback mechanism
+ ResearchLogger.getInstance().presentFeedbackDialogFromSettings();
+ } else {
+ FeedbackUtils.showFeedbackForm(getActivity());
+ }
+ return true;
+ }
+ });
+ aboutSettings.setTitle(FeedbackUtils.getAboutKeyboardTitleResId());
+ aboutSettings.setIntent(FeedbackUtils.getAboutKeyboardIntent(getActivity()));
+ } else {
+ miscSettings.removePreference(feedbackSettings);
+ miscSettings.removePreference(aboutSettings);
+ }
+ }
+ if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+ // The about screen contains items that may be confusing in development-only versions.
+ miscSettings.removePreference(aboutSettings);
+ }
+
+ final boolean showVoiceKeyOption = res.getBoolean(
+ R.bool.config_enable_show_voice_key_option);
+ if (!showVoiceKeyOption) {
+ generalSettings.removePreference(mVoicePreference);
+ }
+
+ final PreferenceGroup advancedSettings =
+ (PreferenceGroup) findPreference(Settings.PREF_ADVANCED_SETTINGS);
+ if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
+ removePreference(Settings.PREF_VIBRATE_ON, generalSettings);
+ removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
+ }
+
+ mKeyPreviewPopupDismissDelay =
+ (ListPreference) findPreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
+ if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupSettingsOption(res)) {
+ removePreference(Settings.PREF_POPUP_ON, generalSettings);
+ removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedSettings);
+ } else {
+ final String popupDismissDelayDefaultValue = Integer.toString(res.getInteger(
+ R.integer.config_key_preview_linger_timeout));
+ mKeyPreviewPopupDismissDelay.setEntries(new String[] {
+ res.getString(R.string.key_preview_popup_dismiss_no_delay),
+ res.getString(R.string.key_preview_popup_dismiss_default_delay),
+ });
+ mKeyPreviewPopupDismissDelay.setEntryValues(new String[] {
+ "0",
+ popupDismissDelayDefaultValue
+ });
+ if (null == mKeyPreviewPopupDismissDelay.getValue()) {
+ mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
+ }
+ mKeyPreviewPopupDismissDelay.setEnabled(
+ Settings.readKeyPreviewPopupEnabled(prefs, res));
+ }
+
+ if (!res.getBoolean(R.bool.config_setup_wizard_available)) {
+ removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON, advancedSettings);
+ }
+
+ setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
+ Settings.readShowsLanguageSwitchKey(prefs));
+
+ final PreferenceGroup textCorrectionGroup =
+ (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
+ final PreferenceScreen dictionaryLink =
+ (PreferenceScreen) findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
+ final Intent intent = dictionaryLink.getIntent();
+ intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName());
+ final int number = context.getPackageManager().queryIntentActivities(intent, 0).size();
+ if (0 >= number) {
+ textCorrectionGroup.removePreference(dictionaryLink);
+ }
+
+ final Preference editPersonalDictionary =
+ findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
+ final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
+ final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS ? null
+ : context.getPackageManager().resolveActivity(
+ editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (ri == null) {
+ overwriteUserDictionaryPreference(editPersonalDictionary);
+ }
+
+ if (!Settings.readFromBuildConfigIfGestureInputEnabled(res)) {
+ removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen());
+ } else {
+ AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
+ }
+
+ setupKeyLongpressTimeoutSettings(prefs, res);
+ setupKeypressVibrationDurationSettings(prefs, res);
+ setupKeypressSoundVolumeSettings(prefs, res);
+ refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, res);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
+ if (isShortcutImeEnabled) {
+ updateVoiceModeSummary();
+ } else {
+ getPreferenceScreen().removePreference(mVoicePreference);
+ }
+ final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ final CheckBoxPreference showSetupWizardIcon =
+ (CheckBoxPreference)findPreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON);
+ if (showSetupWizardIcon != null) {
+ showSetupWizardIcon.setChecked(Settings.readShowSetupWizardIcon(prefs, getActivity()));
+ }
+ updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
+ updateCustomInputStylesSummary();
+ }
+
+ @Override
+ public void onDestroy() {
+ getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
+ this);
+ super.onDestroy();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ // TODO: Introduce a static function to register this class and ensure that
+ // onCreate must be called before "onSharedPreferenceChanged" is called.
+ Log.w(TAG, "onSharedPreferenceChanged called before activity starts.");
+ return;
+ }
+ (new BackupManager(activity)).dataChanged();
+ final Resources res = getResources();
+ if (key.equals(Settings.PREF_POPUP_ON)) {
+ setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
+ Settings.readKeyPreviewPopupEnabled(prefs, res));
+ } else if (key.equals(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY)) {
+ setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
+ Settings.readShowsLanguageSwitchKey(prefs));
+ } else if (key.equals(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) {
+ LauncherIconVisibilityManager.updateSetupWizardIconVisibility(getActivity());
+ }
+ ensureConsistencyOfAutoCorrectionSettings();
+ updateVoiceModeSummary();
+ updateShowCorrectionSuggestionsSummary();
+ updateKeyPreviewPopupDelaySummary();
+ refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
+ }
+
+ private void ensureConsistencyOfAutoCorrectionSettings() {
+ final String autoCorrectionOff = getResources().getString(
+ R.string.auto_correction_threshold_mode_index_off);
+ final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
+ mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+ }
+
+ private void updateShowCorrectionSuggestionsSummary() {
+ mShowCorrectionSuggestionsPreference.setSummary(
+ getResources().getStringArray(R.array.prefs_suggestion_visibilities)
+ [mShowCorrectionSuggestionsPreference.findIndexOfValue(
+ mShowCorrectionSuggestionsPreference.getValue())]);
+ }
+
+ private void updateCustomInputStylesSummary() {
+ final PreferenceScreen customInputStyles =
+ (PreferenceScreen)findPreference(Settings.PREF_CUSTOM_INPUT_STYLES);
+ final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ final Resources res = getResources();
+ final String prefSubtype = Settings.readPrefAdditionalSubtypes(prefs, res);
+ 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.getSubtypeDisplayNameInSystemLocale(subtype));
+ }
+ customInputStyles.setSummary(styles);
+ }
+
+ private void updateKeyPreviewPopupDelaySummary() {
+ final ListPreference lp = mKeyPreviewPopupDismissDelay;
+ final CharSequence[] entries = lp.getEntries();
+ if (entries == null || entries.length <= 0) return;
+ lp.setSummary(entries[lp.findIndexOfValue(lp.getValue())]);
+ }
+
+ private void updateVoiceModeSummary() {
+ mVoicePreference.setSummary(
+ getResources().getStringArray(R.array.voice_input_modes_summary)
+ [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
+ }
+
+ private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
+ final SharedPreferences sp, final Resources res) {
+ setPreferenceEnabled(Settings.PREF_VIBRATION_DURATION_SETTINGS,
+ Settings.readVibrationEnabled(sp, res));
+ setPreferenceEnabled(Settings.PREF_KEYPRESS_SOUND_VOLUME,
+ Settings.readKeypressSoundEnabled(sp, res));
+ }
+
+ private void setupKeypressVibrationDurationSettings(final SharedPreferences sp,
+ final Resources res) {
+ final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
+ Settings.PREF_VIBRATION_DURATION_SETTINGS);
+ if (pref == null) {
+ return;
+ }
+ pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
+ @Override
+ public void writeValue(final int value, final String key) {
+ sp.edit().putInt(key, value).apply();
+ }
+
+ @Override
+ public void writeDefaultValue(final String key) {
+ sp.edit().remove(key).apply();
+ }
+
+ @Override
+ public int readValue(final String key) {
+ return Settings.readKeypressVibrationDuration(sp, res);
+ }
+
+ @Override
+ public int readDefaultValue(final String key) {
+ return Settings.readDefaultKeypressVibrationDuration(res);
+ }
+
+ @Override
+ public void feedbackValue(final int value) {
+ AudioAndHapticFeedbackManager.getInstance().vibrate(value);
+ }
+
+ @Override
+ public String getValueText(final int value) {
+ if (value < 0) {
+ return res.getString(R.string.settings_system_default);
+ }
+ return res.getString(R.string.abbreviation_unit_milliseconds, value);
+ }
+ });
+ }
+
+ private void setupKeyLongpressTimeoutSettings(final SharedPreferences sp,
+ final Resources res) {
+ final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
+ Settings.PREF_KEY_LONGPRESS_TIMEOUT);
+ if (pref == null) {
+ return;
+ }
+ pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
+ @Override
+ public void writeValue(final int value, final String key) {
+ sp.edit().putInt(key, value).apply();
+ }
+
+ @Override
+ public void writeDefaultValue(final String key) {
+ sp.edit().remove(key).apply();
+ }
+
+ @Override
+ public int readValue(final String key) {
+ return Settings.readKeyLongpressTimeout(sp, res);
+ }
+
+ @Override
+ public int readDefaultValue(final String key) {
+ return Settings.readDefaultKeyLongpressTimeout(res);
+ }
+
+ @Override
+ public String getValueText(final int value) {
+ return res.getString(R.string.abbreviation_unit_milliseconds, value);
+ }
+
+ @Override
+ public void feedbackValue(final int value) {}
+ });
+ }
+
+ private void setupKeypressSoundVolumeSettings(final SharedPreferences sp, final Resources res) {
+ final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
+ Settings.PREF_KEYPRESS_SOUND_VOLUME);
+ if (pref == null) {
+ return;
+ }
+ final AudioManager am = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);
+ pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
+ private static final float PERCENTAGE_FLOAT = 100.0f;
+
+ private float getValueFromPercentage(final int percentage) {
+ return percentage / PERCENTAGE_FLOAT;
+ }
+
+ private int getPercentageFromValue(final float floatValue) {
+ return (int)(floatValue * PERCENTAGE_FLOAT);
+ }
+
+ @Override
+ public void writeValue(final int value, final String key) {
+ sp.edit().putFloat(key, getValueFromPercentage(value)).apply();
+ }
+
+ @Override
+ public void writeDefaultValue(final String key) {
+ sp.edit().remove(key).apply();
+ }
+
+ @Override
+ public int readValue(final String key) {
+ return getPercentageFromValue(Settings.readKeypressSoundVolume(sp, res));
+ }
+
+ @Override
+ public int readDefaultValue(final String key) {
+ return getPercentageFromValue(Settings.readDefaultKeypressSoundVolume(res));
+ }
+
+ @Override
+ public String getValueText(final int value) {
+ if (value < 0) {
+ return res.getString(R.string.settings_system_default);
+ }
+ return Integer.toString(value);
+ }
+
+ @Override
+ public void feedbackValue(final int value) {
+ am.playSoundEffect(
+ AudioManager.FX_KEYPRESS_STANDARD, getValueFromPercentage(value));
+ }
+ });
+ }
+
+ private void overwriteUserDictionaryPreference(Preference userDictionaryPreference) {
+ final Activity activity = getActivity();
+ final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
+ if (null == localeList) {
+ // The locale list is null if and only if the user dictionary service is
+ // not present or disabled. In this case we need to remove the preference.
+ getPreferenceScreen().removePreference(userDictionaryPreference);
+ } else if (localeList.size() <= 1) {
+ userDictionaryPreference.setFragment(UserDictionarySettings.class.getName());
+ // If the size of localeList is 0, we don't set the locale parameter in the
+ // extras. This will be interpreted by the UserDictionarySettings class as
+ // meaning "the current locale".
+ // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
+ // the locale list always has at least one element, since it always includes the current
+ // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
+ if (localeList.size() == 1) {
+ final String locale = (String)localeList.toArray()[0];
+ userDictionaryPreference.getExtras().putString("locale", locale);
+ }
+ } else {
+ userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
new file mode 100644
index 000000000..fbfaf7c9a
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+
+import com.android.inputmethod.keyboard.internal.KeySpecParser;
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.InputAttributes;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * When you call the constructor of this class, you may want to change the current system locale by
+ * using {@link com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale}.
+ */
+public final class SettingsValues {
+ private static final String TAG = SettingsValues.class.getSimpleName();
+ // "floatNegativeInfinity" is a special marker string for Float.NEGATIVE_INFINITE
+ // currently used for auto-correction
+ private static final String FLOAT_NEGATIVE_INFINITY_MARKER_STRING = "floatNegativeInfinity";
+
+ // From resources:
+ public final int mDelayUpdateOldSuggestions;
+ public final int[] mSymbolsPrecededBySpace;
+ public final int[] mSymbolsFollowedBySpace;
+ public final int[] mWordConnectors;
+ public final SuggestedWords mSuggestPuncList;
+ public final String mWordSeparators;
+ public final CharSequence mHintToSaveText;
+
+ // From preferences, in the same order as xml/prefs.xml:
+ public final boolean mAutoCap;
+ public final boolean mVibrateOn;
+ public final boolean mSoundOn;
+ public final boolean mKeyPreviewPopupOn;
+ private final String mVoiceMode;
+ public final boolean mIncludesOtherImesInLanguageSwitchList;
+ public final boolean mShowsLanguageSwitchKey;
+ public final boolean mUseContactsDict;
+ public final boolean mUseDoubleSpacePeriod;
+ public final boolean mBlockPotentiallyOffensive;
+ // Use bigrams to predict the next word when there is no input for it yet
+ public final boolean mBigramPredictionEnabled;
+ public final boolean mGestureInputEnabled;
+ public final boolean mGesturePreviewTrailEnabled;
+ public final boolean mGestureFloatingPreviewTextEnabled;
+ public final boolean mSlidingKeyInputPreviewEnabled;
+ public final int mKeyLongpressTimeout;
+
+ // From the input box
+ public final InputAttributes mInputAttributes;
+
+ // Deduced settings
+ public final int mKeypressVibrationDuration;
+ public final float mKeypressSoundVolume;
+ public final int mKeyPreviewPopupDismissDelay;
+ private final boolean mAutoCorrectEnabled;
+ public final float mAutoCorrectionThreshold;
+ public final boolean mCorrectionEnabled;
+ public final int mSuggestionVisibility;
+ private final boolean mVoiceKeyEnabled;
+ private final boolean mVoiceKeyOnMain;
+
+ // Setting values for additional features
+ public final int[] mAdditionalFeaturesSettingValues =
+ new int[AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
+
+ // Debug settings
+ public final boolean mIsInternal;
+
+ public SettingsValues(final SharedPreferences prefs, final Resources res,
+ final InputAttributes inputAttributes) {
+ // Get the resources
+ mDelayUpdateOldSuggestions = res.getInteger(R.integer.config_delay_update_old_suggestions);
+ mSymbolsPrecededBySpace =
+ StringUtils.toCodePointArray(res.getString(R.string.symbols_preceded_by_space));
+ Arrays.sort(mSymbolsPrecededBySpace);
+ mSymbolsFollowedBySpace =
+ StringUtils.toCodePointArray(res.getString(R.string.symbols_followed_by_space));
+ Arrays.sort(mSymbolsFollowedBySpace);
+ mWordConnectors =
+ StringUtils.toCodePointArray(res.getString(R.string.symbols_word_connectors));
+ Arrays.sort(mWordConnectors);
+ final String[] suggestPuncsSpec = KeySpecParser.splitKeySpecs(res.getString(
+ R.string.suggested_punctuations));
+ mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
+ mWordSeparators = res.getString(R.string.symbols_word_separators);
+ mHintToSaveText = res.getText(R.string.hint_add_to_dictionary);
+
+ // Store the input attributes
+ if (null == inputAttributes) {
+ mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
+ } else {
+ mInputAttributes = inputAttributes;
+ }
+
+ // Get the settings preferences
+ mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
+ mVibrateOn = Settings.readVibrationEnabled(prefs, res);
+ mSoundOn = Settings.readKeypressSoundEnabled(prefs, res);
+ mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);
+ mSlidingKeyInputPreviewEnabled = prefs.getBoolean(
+ Settings.PREF_SLIDING_KEY_INPUT_PREVIEW, true);
+ final String voiceModeMain = res.getString(R.string.voice_mode_main);
+ final String voiceModeOff = res.getString(R.string.voice_mode_off);
+ mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
+ final String autoCorrectionThresholdRawValue = prefs.getString(
+ Settings.PREF_AUTO_CORRECTION_THRESHOLD,
+ res.getString(R.string.auto_correction_threshold_mode_index_modest));
+ mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean(
+ Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false);
+ mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs);
+ mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
+ mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
+ mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res);
+ mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
+ mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
+
+ // Compute other readable settings
+ mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
+ mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
+ mKeypressSoundVolume = Settings.readKeypressSoundVolume(prefs, res);
+ mKeyPreviewPopupDismissDelay = Settings.readKeyPreviewPopupDismissDelay(prefs, res);
+ mAutoCorrectionThreshold = readAutoCorrectionThreshold(res,
+ autoCorrectionThresholdRawValue);
+ mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
+ mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
+ mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
+ mGesturePreviewTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
+ mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
+ Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
+ mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
+ final String showSuggestionsSetting = prefs.getString(
+ Settings.PREF_SHOW_SUGGESTIONS_SETTING,
+ res.getString(R.string.prefs_suggestion_visibility_default_value));
+ mSuggestionVisibility = createSuggestionVisibility(res, showSuggestionsSetting);
+ AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(
+ prefs, mAdditionalFeaturesSettingValues);
+ mIsInternal = Settings.isInternal(prefs);
+ }
+
+ public boolean isApplicationSpecifiedCompletionsOn() {
+ return mInputAttributes.mApplicationSpecifiedCompletionOn;
+ }
+
+ public boolean isSuggestionsRequested(final int displayOrientation) {
+ return mInputAttributes.mIsSettingsSuggestionStripOn
+ && (mCorrectionEnabled
+ || isSuggestionStripVisibleInOrientation(displayOrientation));
+ }
+
+ public boolean isSuggestionStripVisibleInOrientation(final int orientation) {
+ return (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_VALUE)
+ || (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE
+ && orientation == Configuration.ORIENTATION_PORTRAIT);
+ }
+
+ public boolean isWordSeparator(final int code) {
+ return mWordSeparators.contains(String.valueOf((char)code));
+ }
+
+ public boolean isWordConnector(final int code) {
+ return Arrays.binarySearch(mWordConnectors, code) >= 0;
+ }
+
+ public boolean isUsuallyPrecededBySpace(final int code) {
+ return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
+ }
+
+ public boolean isUsuallyFollowedBySpace(final int code) {
+ return Arrays.binarySearch(mSymbolsFollowedBySpace, code) >= 0;
+ }
+
+ public boolean shouldInsertSpacesAutomatically() {
+ return mInputAttributes.mShouldInsertSpacesAutomatically;
+ }
+
+ public boolean isVoiceKeyEnabled(final EditorInfo editorInfo) {
+ final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
+ final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
+ return shortcutImeEnabled && mVoiceKeyEnabled
+ && !InputTypeUtils.isPasswordInputType(inputType);
+ }
+
+ public boolean isVoiceKeyOnMain() {
+ return mVoiceKeyOnMain;
+ }
+
+ public boolean isLanguageSwitchKeyEnabled() {
+ if (!mShowsLanguageSwitchKey) {
+ return false;
+ }
+ final RichInputMethodManager imm = RichInputMethodManager.getInstance();
+ if (mIncludesOtherImesInLanguageSwitchList) {
+ return imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */);
+ } else {
+ return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
+ }
+ }
+
+ public boolean isSameInputType(final EditorInfo editorInfo) {
+ return mInputAttributes.isSameInputType(editorInfo);
+ }
+
+ // Helper functions to create member values.
+ private static SuggestedWords createSuggestPuncList(final String[] puncs) {
+ final ArrayList<SuggestedWordInfo> puncList = CollectionUtils.newArrayList();
+ if (puncs != null) {
+ for (final String puncSpec : puncs) {
+ // TODO: Stop using KeySpceParser.getLabel().
+ puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec),
+ SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED,
+ Dictionary.TYPE_HARDCODED));
+ }
+ }
+ return new SuggestedWords(puncList,
+ false /* typedWordValid */,
+ false /* hasAutoCorrectionCandidate */,
+ true /* isPunctuationSuggestions */,
+ false /* isObsoleteSuggestions */,
+ false /* isPrediction */);
+ }
+
+ private static final int SUGGESTION_VISIBILITY_SHOW_VALUE =
+ R.string.prefs_suggestion_visibility_show_value;
+ private static final int SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE =
+ R.string.prefs_suggestion_visibility_show_only_portrait_value;
+ private static final int SUGGESTION_VISIBILITY_HIDE_VALUE =
+ R.string.prefs_suggestion_visibility_hide_value;
+ private static final int[] SUGGESTION_VISIBILITY_VALUE_ARRAY = new int[] {
+ SUGGESTION_VISIBILITY_SHOW_VALUE,
+ SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE,
+ SUGGESTION_VISIBILITY_HIDE_VALUE
+ };
+
+ private static int createSuggestionVisibility(final Resources res,
+ final String suggestionVisiblityStr) {
+ for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) {
+ if (suggestionVisiblityStr.equals(res.getString(visibility))) {
+ return visibility;
+ }
+ }
+ throw new RuntimeException("Bug: visibility string is not configured correctly");
+ }
+
+ private static boolean readBigramPredictionEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, res.getBoolean(
+ R.bool.config_default_next_word_prediction));
+ }
+
+ private static float readAutoCorrectionThreshold(final Resources res,
+ final String currentAutoCorrectionSetting) {
+ final String[] autoCorrectionThresholdValues = res.getStringArray(
+ R.array.auto_correction_threshold_values);
+ // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off.
+ float autoCorrectionThreshold = Float.MAX_VALUE;
+ try {
+ final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting);
+ if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) {
+ final String val = autoCorrectionThresholdValues[arrayIndex];
+ if (FLOAT_NEGATIVE_INFINITY_MARKER_STRING.equals(val)) {
+ autoCorrectionThreshold = Float.NEGATIVE_INFINITY;
+ } else {
+ autoCorrectionThreshold = Float.parseFloat(val);
+ }
+ }
+ } catch (NumberFormatException e) {
+ // Whenever the threshold settings are correct, never come here.
+ autoCorrectionThreshold = Float.MAX_VALUE;
+ Log.w(TAG, "Cannot load auto correction threshold setting."
+ + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting
+ + ", autoCorrectionThresholdValues: "
+ + Arrays.toString(autoCorrectionThresholdValues), e);
+ }
+ return autoCorrectionThreshold;
+ }
+}