aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/settings
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/settings')
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java266
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java50
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java7
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java359
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java469
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java27
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java47
-rw-r--r--java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java1
-rw-r--r--java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java59
-rw-r--r--java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java3
-rw-r--r--java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java9
-rw-r--r--java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java10
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java25
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java6
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java43
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java17
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java11
-rw-r--r--java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java55
-rw-r--r--java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java30
19 files changed, 993 insertions, 501 deletions
diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
new file mode 100644
index 000000000..4bd15d037
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ACCOUNT_NAME;
+import static com.android.inputmethod.latin.settings.LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.text.TextUtils;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.accounts.LoginAccountUtils;
+import com.android.inputmethod.latin.accounts.AccountStateChangedListener;
+import com.android.inputmethod.latin.define.ProductionFlags;
+
+import javax.annotation.Nullable;
+
+/**
+ * "Accounts & Privacy" settings sub screen.
+ *
+ * This settings sub screen handles the following preferences:
+ * <li> Account selection/management for IME </li>
+ * <li> Sync preferences </li>
+ * <li> Privacy preferences </li>
+ */
+public final class AccountsSettingsFragment extends SubScreenFragment {
+ private static final String PREF_SYNC_NOW = "pref_beanstalk";
+
+ static final String PREF_ACCCOUNT_SWITCHER = "account_switcher";
+
+ private final DialogInterface.OnClickListener mAccountChangedListener =
+ new AccountChangedListener();
+ private final Preference.OnPreferenceClickListener mSyncNowListener = new SyncNowListener();
+
+ @Override
+ public void onCreate(final Bundle icicle) {
+ super.onCreate(icicle);
+ addPreferencesFromResource(R.xml.prefs_screen_accounts);
+
+ 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);
+
+ if (ProductionFlags.IS_METRICS_LOGGING_SUPPORTED) {
+ final Preference enableMetricsLogging =
+ findPreference(Settings.PREF_ENABLE_METRICS_LOGGING);
+ if (enableMetricsLogging != null) {
+ final String enableMetricsLoggingTitle = res.getString(
+ R.string.enable_metrics_logging, getApplicationName());
+ enableMetricsLogging.setTitle(enableMetricsLoggingTitle);
+ }
+ } else {
+ removePreference(Settings.PREF_ENABLE_METRICS_LOGGING);
+ }
+
+ if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
+ removePreference(PREF_ACCCOUNT_SWITCHER);
+ removePreference(PREF_ENABLE_CLOUD_SYNC);
+ removePreference(PREF_SYNC_NOW);
+ }
+ if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
+ removePreference(PREF_ENABLE_CLOUD_SYNC);
+ removePreference(PREF_SYNC_NOW);
+ } else {
+ final Preference syncNowPreference = findPreference(PREF_SYNC_NOW);
+ syncNowPreference.setOnPreferenceClickListener(mSyncNowListener);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ refreshAccountAndDependentPreferences(getSignedInAccountName());
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+ if (TextUtils.equals(key, PREF_ACCOUNT_NAME)) {
+ refreshAccountAndDependentPreferences(
+ prefs.getString(PREF_ACCOUNT_NAME, null));
+ } else if (TextUtils.equals(key, PREF_ENABLE_CLOUD_SYNC)) {
+ final boolean syncEnabled = prefs.getBoolean(PREF_ENABLE_CLOUD_SYNC, false);
+ AccountStateChangedListener.onSyncPreferenceChanged(
+ getSignedInAccountName(), syncEnabled);
+ }
+ }
+
+ private void refreshAccountAndDependentPreferences(@Nullable final String currentAccount) {
+ if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
+ return;
+ }
+
+ final Preference accountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
+ if (currentAccount == null) {
+ // No account is currently selected.
+ accountSwitcher.setSummary(getString(R.string.no_accounts_selected));
+ // Disable the sync preference UI.
+ disableSyncPreference();
+ } else {
+ // Set the currently selected account.
+ accountSwitcher.setSummary(getString(R.string.account_selected, currentAccount));
+ // Enable the sync preference UI.
+ enableSyncPreference();
+ }
+ // Set up onClick listener for the account picker preference.
+ final Context context = getActivity();
+ final String[] accountsForLogin = LoginAccountUtils.getAccountsForLogin(context);
+ accountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (accountsForLogin.length == 0) {
+ // TODO: Handle account addition.
+ Toast.makeText(getActivity(), getString(R.string.account_select_cancel),
+ Toast.LENGTH_SHORT).show();
+ } else {
+ createAccountPicker(accountsForLogin, currentAccount).show();
+ }
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Enables the Sync preference UI and updates its summary.
+ */
+ private void enableSyncPreference() {
+ if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
+ return;
+ }
+
+ final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
+ syncPreference.setEnabled(true);
+ syncPreference.setSummary(R.string.cloud_sync_summary);
+ }
+
+ /**
+ * Disables the Sync preference UI and updates its summary to indicate
+ * the fact that an account needs to be selected for sync.
+ */
+ private void disableSyncPreference() {
+ if (!ProductionFlags.ENABLE_PERSONAL_DICTIONARY_SYNC) {
+ return;
+ }
+
+ final Preference syncPreference = findPreference(PREF_ENABLE_CLOUD_SYNC);
+ syncPreference.setEnabled(false);
+ syncPreference.setSummary(R.string.cloud_sync_summary_disabled_signed_out);
+ }
+
+ @Nullable
+ String getSignedInAccountName() {
+ return getSharedPreferences().getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null);
+ }
+
+ boolean isSyncEnabled() {
+ return getSharedPreferences().getBoolean(PREF_ENABLE_CLOUD_SYNC, false);
+ }
+
+ /**
+ * Creates an account picker dialog showing the given accounts in a list and selecting
+ * the selected account by default.
+ * The list of accounts must not be null/empty.
+ *
+ * Package-private for testing.
+ */
+ @UsedForTesting
+ AlertDialog createAccountPicker(final String[] accounts,
+ final String selectedAccount) {
+ if (accounts == null || accounts.length == 0) {
+ throw new IllegalArgumentException("List of accounts must not be empty");
+ }
+
+ // See if the currently selected account is in the list.
+ // If it is, the entry is selected, and a sign-out button is provided.
+ // If it isn't, select the 0th account by default which will get picked up
+ // if the user presses OK.
+ int index = 0;
+ boolean isSignedIn = false;
+ for (int i = 0; i < accounts.length; i++) {
+ if (TextUtils.equals(accounts[i], selectedAccount)) {
+ index = i;
+ isSignedIn = true;
+ break;
+ }
+ }
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.account_select_title)
+ .setSingleChoiceItems(accounts, index, null)
+ .setPositiveButton(R.string.account_select_ok, mAccountChangedListener)
+ .setNegativeButton(R.string.account_select_cancel, null);
+ if (isSignedIn) {
+ builder.setNeutralButton(R.string.account_select_sign_out, mAccountChangedListener);
+ }
+ return builder.create();
+ }
+
+ /**
+ * Listener for a account selection changes from the picker.
+ * Persists/removes the account to/from shared preferences and sets up sync if required.
+ */
+ class AccountChangedListener implements DialogInterface.OnClickListener {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final String oldAccount = getSignedInAccountName();
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE: // Signed in
+ final ListView lv = ((AlertDialog)dialog).getListView();
+ final String newAccount =
+ (String) lv.getItemAtPosition(lv.getCheckedItemPosition());
+ getSharedPreferences()
+ .edit()
+ .putString(PREF_ACCOUNT_NAME, newAccount)
+ .apply();
+ AccountStateChangedListener.onAccountSignedIn(oldAccount, newAccount);
+ break;
+ case DialogInterface.BUTTON_NEUTRAL: // Signed out
+ AccountStateChangedListener.onAccountSignedOut(oldAccount);
+ getSharedPreferences()
+ .edit()
+ .remove(PREF_ACCOUNT_NAME)
+ .apply();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Listener that initiates the process of sync in the background.
+ */
+ class SyncNowListener implements Preference.OnPreferenceClickListener {
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ AccountStateChangedListener.forceSync(getSignedInAccountName());
+ return true;
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java
index 00f2c73dd..d2c9dbbe9 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdvancedSettingsFragment.java
@@ -93,22 +93,27 @@ public final class AdvancedSettingsFragment extends SubScreenFragment {
removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON);
}
+ // If metrics logging isn't supported, or account sign in is enabled
+ // don't show the logging preference.
+ // TODO: Eventually when we enable account sign in by default,
+ // we'll remove logging preference from here.
if (ProductionFlags.IS_METRICS_LOGGING_SUPPORTED) {
final Preference enableMetricsLogging =
findPreference(Settings.PREF_ENABLE_METRICS_LOGGING);
if (enableMetricsLogging != null) {
- final int applicationLabelRes = context.getApplicationInfo().labelRes;
- final String applicationName = res.getString(applicationLabelRes);
final String enableMetricsLoggingTitle = res.getString(
- R.string.enable_metrics_logging, applicationName);
+ R.string.enable_metrics_logging, getApplicationName());
enableMetricsLogging.setTitle(enableMetricsLoggingTitle);
}
} else {
removePreference(Settings.PREF_ENABLE_METRICS_LOGGING);
}
+ AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(context, this);
+
setupKeypressVibrationDurationSettings();
setupKeypressSoundVolumeSettings();
+ setupKeyLongpressTimeoutSettings();
refreshEnablingsOfKeypressSoundAndVibrationSettings();
}
@@ -245,4 +250,43 @@ public final class AdvancedSettingsFragment extends SubScreenFragment {
}
});
}
+
+ private void setupKeyLongpressTimeoutSettings() {
+ final SharedPreferences prefs = getSharedPreferences();
+ final Resources res = getResources();
+ 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) {
+ prefs.edit().putInt(key, value).apply();
+ }
+
+ @Override
+ public void writeDefaultValue(final String key) {
+ prefs.edit().remove(key).apply();
+ }
+
+ @Override
+ public int readValue(final String key) {
+ return Settings.readKeyLongpressTimeout(prefs, 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) {}
+ });
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java
index f5e4d33a2..554edc85c 100644
--- a/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/AppearanceSettingsFragment.java
@@ -19,7 +19,8 @@ package com.android.inputmethod.latin.settings;
import android.os.Bundle;
import com.android.inputmethod.latin.R;
-
+import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.define.ProductionFlags;
/**
* "Appearance" settings sub screen.
@@ -29,6 +30,10 @@ public final class AppearanceSettingsFragment extends SubScreenFragment {
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_appearance);
+ if (!ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED ||
+ Constants.isPhone(Settings.readScreenMetrics(getResources()))) {
+ removePreference(Settings.PREF_ENABLE_SPLIT_KEYBOARD);
+ }
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java
new file mode 100644
index 000000000..01398f467
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.DialogPreference;
+import android.preference.Preference;
+import android.util.Log;
+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 com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
+import com.android.inputmethod.compat.ViewCompatUtils;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+
+import java.util.TreeSet;
+
+final class CustomInputStylePreference extends DialogPreference
+ implements DialogInterface.OnCancelListener {
+ private static final boolean DEBUG_SUBTYPE_ID = false;
+
+ interface Listener {
+ public void onRemoveCustomInputStyle(CustomInputStylePreference stylePref);
+ public void onSaveCustomInputStyle(CustomInputStylePreference stylePref);
+ public void onAddCustomInputStyle(CustomInputStylePreference stylePref);
+ public SubtypeLocaleAdapter getSubtypeLocaleAdapter();
+ public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter();
+ }
+
+ 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 Listener mProxy;
+ private Spinner mSubtypeLocaleSpinner;
+ private Spinner mKeyboardLayoutSetSpinner;
+
+ public static CustomInputStylePreference newIncompleteSubtypePreference(
+ final Context context, final Listener proxy) {
+ return new CustomInputStylePreference(context, null, proxy);
+ }
+
+ public CustomInputStylePreference(final Context context, final InputMethodSubtype subtype,
+ final Listener 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 =
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+ setTitle(displayName);
+ setDialogTitle(displayName);
+ setKey(KEY_PREFIX + subtype.getLocale() + "_"
+ + SubtypeLocaleUtils.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());
+ // All keyboard layout names are in the Latin script and thus left to right. That means
+ // the view would align them to the left even if the system locale is RTL, but that
+ // would look strange. To fix this, we align them to the view's start, which will be
+ // natural for any direction.
+ ViewCompatUtils.setTextAlignment(
+ mKeyboardLayoutSetSpinner, ViewCompatUtils.TEXT_ALIGNMENT_VIEW_START);
+ return v;
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
+ 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 = new SubtypeLocaleItem(mSubtype);
+ 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.onRemoveCustomInputStyle(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 =
+ AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
+ locale.mLocaleString, layout.mLayoutName);
+ setSubtype(subtype);
+ notifyChanged();
+ if (isEditing) {
+ mProxy.onSaveCustomInputStyle(this);
+ } else {
+ mProxy.onAddCustomInputStyle(this);
+ }
+ break;
+ case DialogInterface.BUTTON_NEUTRAL:
+ // Nothing to do
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ mProxy.onRemoveCustomInputStyle(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];
+ }
+ };
+ }
+
+ static final class SubtypeLocaleItem implements Comparable<SubtypeLocaleItem> {
+ public final String mLocaleString;
+ private final String mDisplayName;
+
+ public SubtypeLocaleItem(final InputMethodSubtype subtype) {
+ mLocaleString = subtype.getLocale();
+ mDisplayName = SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(
+ mLocaleString);
+ }
+
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
+ @Override
+ public String toString() {
+ return mDisplayName;
+ }
+
+ @Override
+ public int compareTo(final SubtypeLocaleItem o) {
+ return mLocaleString.compareTo(o.mLocaleString);
+ }
+ }
+
+ static final class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> {
+ private static final String TAG_SUBTYPE = SubtypeLocaleAdapter.class.getSimpleName();
+
+ 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 = new TreeSet<>();
+ 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) {
+ Log.d(TAG_SUBTYPE, String.format("%-6s 0x%08x %11d %s",
+ subtype.getLocale(), subtype.hashCode(), subtype.hashCode(),
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
+ }
+ if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
+ items.add(new SubtypeLocaleItem(subtype));
+ }
+ }
+ // TODO: Should filter out already existing combinations of locale and layout.
+ addAll(items);
+ }
+ }
+
+ static final class KeyboardLayoutSetItem {
+ public final String mLayoutName;
+ private final String mDisplayName;
+
+ public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
+ mLayoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
+ mDisplayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
+ }
+
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
+ @Override
+ public String toString() {
+ return mDisplayName;
+ }
+ }
+
+ 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 : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) {
+ // This is a dummy subtype with NO_LANGUAGE, only for display.
+ final InputMethodSubtype subtype =
+ AdditionalSubtypeUtils.createDummyAdditionalSubtype(
+ SubtypeLocaleUtils.NO_LANGUAGE, layout);
+ add(new KeyboardLayoutSetItem(subtype));
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
index 9bc398654..46fcc7106 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
@@ -17,37 +17,27 @@
package com.android.inputmethod.latin.settings;
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.support.v4.view.ViewCompat;
import android.text.TextUtils;
-import android.util.Pair;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-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.compat.InputMethodSubtypeCompatUtils;
-import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
@@ -56,13 +46,18 @@ import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.ArrayList;
-import java.util.TreeSet;
-public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
+public final class CustomInputStyleSettingsFragment extends PreferenceFragment
+ implements CustomInputStylePreference.Listener {
+ private static final String TAG = CustomInputStyleSettingsFragment.class.getSimpleName();
+ // Note: We would like to turn this debug flag true in order to see what input styles are
+ // defined in a bug-report.
+ private static final boolean DEBUG_CUSTOM_INPUT_STYLES = true;
+
private RichInputMethodManager mRichImm;
private SharedPreferences mPrefs;
- private SubtypeLocaleAdapter mSubtypeLocaleAdapter;
- private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter;
+ private CustomInputStylePreference.SubtypeLocaleAdapter mSubtypeLocaleAdapter;
+ private CustomInputStylePreference.KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter;
private boolean mIsAddingNewSubtype;
private AlertDialog mSubtypeEnablerNotificationDialog;
@@ -73,326 +68,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
"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,
- SubtypeLocaleUtils.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 = new TreeSet<>();
- 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(),
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
- }
- if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
- 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(SubtypeLocaleUtils.NO_LANGUAGE)) {
- final String displayName = context.getString(R.string.subtype_no_language);
- return new SubtypeLocaleItem(localeString, displayName);
- }
- return new SubtypeLocaleItem(localeString);
- }
- }
-
- static final class KeyboardLayoutSetItem extends Pair<String, String> {
- public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
- super(SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype),
- SubtypeLocaleUtils.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 : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) {
- // This is a dummy subtype with NO_LANGUAGE, only for display.
- final InputMethodSubtype subtype =
- AdditionalSubtypeUtils.createDummyAdditionalSubtype(
- SubtypeLocaleUtils.NO_LANGUAGE, layout);
- 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 =
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
- setTitle(displayName);
- setDialogTitle(displayName);
- setKey(KEY_PREFIX + subtype.getLocale() + "_"
- + SubtypeLocaleUtils.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());
- // All keyboard layout names are in the Latin script and thus left to right. That means
- // the view would align them to the left even if the system locale is RTL, but that
- // would look strange. To fix this, we align them to the view's start, which will be
- // natural for any direction.
- ViewCompatUtils.setTextAlignment(
- mKeyboardLayoutSetSpinner, ViewCompatUtils.TEXT_ALIGNMENT_VIEW_START);
- 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 =
- AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
- locale.first, layout.first);
- 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);
- }
-
- 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 CustomInputStyleSettingsFragment() {
// Empty constructor for fragment generation.
}
@@ -440,18 +115,22 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
final Context context = getActivity();
- mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context);
- mKeyboardLayoutSetAdapter = new KeyboardLayoutSetAdapter(context);
+ mSubtypeLocaleAdapter = new CustomInputStylePreference.SubtypeLocaleAdapter(context);
+ mKeyboardLayoutSetAdapter =
+ new CustomInputStylePreference.KeyboardLayoutSetAdapter(context);
final String prefSubtypes =
Settings.readPrefAdditionalSubtypes(mPrefs, getResources());
+ if (DEBUG_CUSTOM_INPUT_STYLES) {
+ Log.i(TAG, "Load custom input styles: " + prefSubtypes);
+ }
setPrefSubtypes(prefSubtypes, context);
mIsAddingNewSubtype = (savedInstanceState != null)
&& savedInstanceState.containsKey(KEY_IS_ADDING_NEW_SUBTYPE);
if (mIsAddingNewSubtype) {
getPreferenceScreen().addPreference(
- SubtypePreference.newIncompleteSubtypePreference(context, mSubtypeProxy));
+ CustomInputStylePreference.newIncompleteSubtypePreference(context, this));
}
super.onActivityCreated(savedInstanceState);
@@ -460,8 +139,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN)) {
mSubtypePreferenceKeyForSubtypeEnabler = savedInstanceState.getString(
KEY_SUBTYPE_FOR_SUBTYPE_ENABLER);
- final SubtypePreference subtypePref = (SubtypePreference)findPreference(
- mSubtypePreferenceKeyForSubtypeEnabler);
mSubtypeEnablerNotificationDialog = createDialog();
mSubtypeEnablerNotificationDialog.show();
}
@@ -481,62 +158,60 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
}
}
- private final SubtypeDialogProxy mSubtypeProxy = new SubtypeDialogProxy() {
- @Override
- public void onRemovePressed(final SubtypePreference subtypePref) {
- mIsAddingNewSubtype = false;
- final PreferenceGroup group = getPreferenceScreen();
- group.removePreference(subtypePref);
+ @Override
+ public void onRemoveCustomInputStyle(final CustomInputStylePreference stylePref) {
+ mIsAddingNewSubtype = false;
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removePreference(stylePref);
+ mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ }
+
+ @Override
+ public void onSaveCustomInputStyle(final CustomInputStylePreference stylePref) {
+ final InputMethodSubtype subtype = stylePref.getSubtype();
+ if (!stylePref.hasBeenModified()) {
+ return;
+ }
+ if (findDuplicatedSubtype(subtype) == null) {
mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ return;
}
- @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(stylePref);
+ stylePref.revert();
+ group.addPreference(stylePref);
+ showSubtypeAlreadyExistsToast(subtype);
+ }
- // Saved subtype is duplicated.
- final PreferenceGroup group = getPreferenceScreen();
- group.removePreference(subtypePref);
- subtypePref.revert();
- group.addPreference(subtypePref);
- showSubtypeAlreadyExistsToast(subtype);
+ @Override
+ public void onAddCustomInputStyle(final CustomInputStylePreference stylePref) {
+ mIsAddingNewSubtype = false;
+ final InputMethodSubtype subtype = stylePref.getSubtype();
+ if (findDuplicatedSubtype(subtype) == null) {
+ mRichImm.setAdditionalInputMethodSubtypes(getSubtypes());
+ mSubtypePreferenceKeyForSubtypeEnabler = stylePref.getKey();
+ mSubtypeEnablerNotificationDialog = createDialog();
+ mSubtypeEnablerNotificationDialog.show();
+ return;
}
- @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();
- mSubtypeEnablerNotificationDialog.show();
- return;
- }
-
- // Newly added subtype is duplicated.
- final PreferenceGroup group = getPreferenceScreen();
- group.removePreference(subtypePref);
- showSubtypeAlreadyExistsToast(subtype);
- }
+ // Newly added subtype is duplicated.
+ final PreferenceGroup group = getPreferenceScreen();
+ group.removePreference(stylePref);
+ showSubtypeAlreadyExistsToast(subtype);
+ }
- @Override
- public SubtypeLocaleAdapter getSubtypeLocaleAdapter() {
- return mSubtypeLocaleAdapter;
- }
+ @Override
+ public CustomInputStylePreference.SubtypeLocaleAdapter getSubtypeLocaleAdapter() {
+ return mSubtypeLocaleAdapter;
+ }
- @Override
- public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter() {
- return mKeyboardLayoutSetAdapter;
- }
- };
+ @Override
+ public CustomInputStylePreference.KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter() {
+ return mKeyboardLayoutSetAdapter;
+ }
private void showSubtypeAlreadyExistsToast(final InputMethodSubtype subtype) {
final Context context = getActivity();
@@ -554,6 +229,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
}
private AlertDialog createDialog() {
+ final String imeId = mRichImm.getInputMethodIdOfThisIme();
final AlertDialog.Builder builder = new AlertDialog.Builder(
DialogUtils.getPlatformDialogThemeContext(getActivity()));
builder.setTitle(R.string.custom_input_styles_title)
@@ -563,7 +239,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent intent = IntentUtils.getInputLanguageSelectionIntent(
- mRichImm.getInputMethodIdOfThisIme(),
+ imeId,
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -583,8 +259,8 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
final InputMethodSubtype[] subtypesArray =
AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtypes);
for (final InputMethodSubtype subtype : subtypesArray) {
- final SubtypePreference pref = new SubtypePreference(
- context, subtype, mSubtypeProxy);
+ final CustomInputStylePreference pref =
+ new CustomInputStylePreference(context, subtype, this);
group.addPreference(pref);
}
}
@@ -595,8 +271,8 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
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;
+ if (pref instanceof CustomInputStylePreference) {
+ final CustomInputStylePreference subtypePref = (CustomInputStylePreference)pref;
// We should not save newly adding subtype to preference because it is incomplete.
if (subtypePref.isIncomplete()) continue;
subtypes.add(subtypePref.getSubtype());
@@ -611,6 +287,9 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
final String oldSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources());
final InputMethodSubtype[] subtypes = getSubtypes();
final String prefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(subtypes);
+ if (DEBUG_CUSTOM_INPUT_STYLES) {
+ Log.i(TAG, "Save custom input styles: " + prefSubtypes);
+ }
if (prefSubtypes.equals(oldSubtypes)) {
return;
}
@@ -627,8 +306,8 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
public boolean onOptionsItemSelected(final MenuItem item) {
final int itemId = item.getItemId();
if (itemId == R.id.action_add_style) {
- final SubtypePreference newSubtype =
- SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy);
+ final CustomInputStylePreference newSubtype =
+ CustomInputStylePreference.newIncompleteSubtypePreference(getActivity(), this);
getPreferenceScreen().addPreference(newSubtype);
newSubtype.show();
mIsAddingNewSubtype = true;
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 48f4c758c..4985c2f08 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -16,29 +16,34 @@
package com.android.inputmethod.latin.settings;
+/**
+ * Debug settings for the application.
+ *
+ * Note: Even though these settings are stored in the default shared preferences file,
+ * they shouldn't be restored across devices.
+ * If a new key is added here, it should also be blacklisted for restore in
+ * {@link LocalSettingsConstants}.
+ */
public final class DebugSettings {
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_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY =
- "force_physical_keyboard_special_key";
- public static final String PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD =
- "pref_show_ui_to_accept_typed_word";
public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
"pref_has_custom_key_preview_animation_params";
- public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
- "pref_key_preview_show_up_start_x_scale";
- public static final String PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE =
- "pref_key_preview_show_up_start_y_scale";
+ public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
+ "pref_key_preview_dismiss_duration";
public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
"pref_key_preview_dismiss_end_x_scale";
public static final String PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE =
"pref_key_preview_dismiss_end_y_scale";
public static final String PREF_KEY_PREVIEW_SHOW_UP_DURATION =
"pref_key_preview_show_up_duration";
- public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
- "pref_key_preview_dismiss_duration";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
+ "pref_key_preview_show_up_start_x_scale";
+ public static final String PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE =
+ "pref_key_preview_show_up_start_y_scale";
+ public static final String PREF_SHOULD_SHOW_LXX_SUGGESTION_UI =
+ "pref_should_show_lxx_suggestion_ui";
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";
private DebugSettings() {
// This class is not publicly instantiable.
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index 5640e2039..2e5c3c479 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -56,8 +56,8 @@ public final class DebugSettingsFragment extends SubScreenFragment
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_debug);
- if (!Settings.HAS_UI_TO_ACCEPT_TYPED_WORD) {
- removePreference(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD);
+ if (!Settings.SHOULD_SHOW_LXX_SUGGESTION_UI) {
+ removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI);
}
mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY);
@@ -73,7 +73,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
dictDumpPreferenceGroup.addPreference(pref);
}
final Resources res = getResources();
- setupKeyLongpressTimeoutSettings();
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
res.getInteger(R.integer.config_key_preview_show_up_duration));
setupKeyPreviewAnimationDuration(DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
@@ -143,8 +142,7 @@ public final class DebugSettingsFragment extends SubScreenFragment
mServiceNeedsRestart = true;
return;
}
- if (key.equals(DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH)
- || key.equals(DebugSettings.PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY)) {
+ if (key.equals(DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH)) {
mServiceNeedsRestart = true;
return;
}
@@ -163,45 +161,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
}
}
- private void setupKeyLongpressTimeoutSettings() {
- final SharedPreferences prefs = getSharedPreferences();
- final Resources res = getResources();
- final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(
- DebugSettings.PREF_KEY_LONGPRESS_TIMEOUT);
- if (pref == null) {
- return;
- }
- pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
- @Override
- public void writeValue(final int value, final String key) {
- prefs.edit().putInt(key, value).apply();
- }
-
- @Override
- public void writeDefaultValue(final String key) {
- prefs.edit().remove(key).apply();
- }
-
- @Override
- public int readValue(final String key) {
- return Settings.readKeyLongpressTimeout(prefs, 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 setupKeyPreviewAnimationScale(final String prefKey, final float defaultValue) {
final SharedPreferences prefs = getSharedPreferences();
final Resources res = getResources();
diff --git a/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
index 832fbf65a..22b0655b4 100644
--- a/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/GestureSettingsFragment.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.latin.settings;
-import android.content.SharedPreferences;
import android.os.Bundle;
import com.android.inputmethod.latin.R;
diff --git a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
new file mode 100644
index 000000000..0fd94b0f8
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+/**
+ * Collection of device specific preference constants.
+ */
+public class LocalSettingsConstants {
+ // Preference file for storing preferences that are tied to a device
+ // and are not backed up.
+ public static final String PREFS_FILE = "local_prefs";
+
+ // Preference key for the current account.
+ // Do not restore.
+ public static final String PREF_ACCOUNT_NAME = "pref_account_name";
+ // Preference key for enabling cloud sync feature.
+ // Do not restore.
+ public static final String PREF_ENABLE_CLOUD_SYNC = "pref_enable_cloud_sync";
+
+ // List of preference keys to skip from being restored by backup agent.
+ // These preferences are tied to a device and hence should not be restored.
+ // e.g. account name.
+ // Ideally they could have been kept in a separate file that wasn't backed up
+ // however the preference UI currently only deals with the default
+ // shared preferences which makes it non-trivial to move these out to
+ // a different shared preferences file.
+ public static final String[] PREFS_TO_SKIP_RESTORING = new String[] {
+ PREF_ACCOUNT_NAME,
+ PREF_ENABLE_CLOUD_SYNC,
+ // The debug settings are not restored on a new device.
+ // If a feature relies on these, it should ensure that the defaults are
+ // correctly set for it to work on a new device.
+ DebugSettings.PREF_DEBUG_MODE,
+ DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH,
+ DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS,
+ DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
+ DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
+ DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
+ DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
+ DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
+ DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI,
+ DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW
+ };
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
index b073c50a4..c5930db1e 100644
--- a/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/MultiLingualSettingsFragment.java
@@ -20,8 +20,6 @@ import android.os.Bundle;
import com.android.inputmethod.latin.R;
-import java.util.ArrayList;
-
/**
* "Multilingual options" settings sub screen.
*
@@ -38,5 +36,6 @@ public final class MultiLingualSettingsFragment extends SubScreenFragment {
removePreference(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY);
removePreference(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
}
+ AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(getActivity(), this);
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
index 31a20c4db..7603dbba5 100644
--- a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
+++ b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
@@ -22,7 +22,8 @@ public class NativeSuggestOptions {
private static final int USE_FULL_EDIT_DISTANCE = 1;
private static final int BLOCK_OFFENSIVE_WORDS = 2;
private static final int SPACE_AWARE_GESTURE_ENABLED = 3;
- private static final int OPTIONS_SIZE = 4;
+ private static final int WEIGHT_FOR_LOCALE_IN_THOUSANDS = 4;
+ private static final int OPTIONS_SIZE = 5;
private final int[] mOptions = new int[OPTIONS_SIZE
+ AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
@@ -43,6 +44,12 @@ public class NativeSuggestOptions {
setBooleanOption(SPACE_AWARE_GESTURE_ENABLED, value);
}
+ public void setWeightForLocale(final float value) {
+ // We're passing this option as a fixed point value, in thousands. This is decoded in
+ // native code by SuggestOptions#weightForLocale().
+ setIntegerOption(WEIGHT_FOR_LOCALE_IN_THOUSANDS, (int) (value * 1000));
+ }
+
public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
if (additionalOptions == null) {
return;
diff --git a/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java b/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java
index c173d4706..91444604d 100644
--- a/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java
+++ b/java/src/com/android/inputmethod/latin/settings/RadioButtonPreference.java
@@ -43,9 +43,7 @@ public class RadioButtonPreference extends Preference {
private final View.OnClickListener mClickListener = new View.OnClickListener() {
@Override
public void onClick(final View v) {
- if (mListener != null) {
- mListener.onRadioButtonClicked(RadioButtonPreference.this);
- }
+ callListenerOnRadioButtonClicked();
}
};
@@ -67,6 +65,12 @@ public class RadioButtonPreference extends Preference {
mListener = listener;
}
+ void callListenerOnRadioButtonClicked() {
+ if (mListener != null) {
+ mListener.onRadioButtonClicked(this);
+ }
+ }
+
@Override
protected void onBindView(final View view) {
super.onBindView(view);
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 0de2d8831..6d23fcb66 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -32,6 +32,7 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.StatsUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import java.util.Collections;
@@ -39,10 +40,13 @@ import java.util.Locale;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
+import javax.annotation.Nonnull;
+
public final class Settings implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = Settings.class.getSimpleName();
// Settings screens
public static final String SCREEN_PREFERENCES = "screen_preferences";
+ public static final String SCREEN_ACCOUNTS = "screen_accounts";
public static final String SCREEN_APPEARANCE = "screen_appearance";
public static final String SCREEN_THEME = "screen_theme";
public static final String SCREEN_MULTILINGUAL = "screen_multilingual";
@@ -75,14 +79,15 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS =
BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
- public static final boolean HAS_UI_TO_ACCEPT_TYPED_WORD =
- BuildCompatUtils.EFFECTIVE_SDK_INT >= BuildCompatUtils.VERSION_CODES_LXX;
+ public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI =
+ BuildCompatUtils.EFFECTIVE_SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
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_KEYBOARD_THEME = "pref_keyboard_theme";
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
+ public static final String PREF_ENABLE_SPLIT_KEYBOARD = "pref_split_keyboard";
// TODO: consolidate key preview dismiss delay with the key preview animation parameters.
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay";
@@ -90,8 +95,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_GESTURE_INPUT = "gesture_input";
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_KEYPRESS_SOUND_VOLUME = "pref_keypress_sound_volume";
+ public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
+ public static final String PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY =
+ "pref_enable_emoji_alt_physical_key";
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";
@@ -103,7 +110,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
-
// 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 =
@@ -166,13 +172,14 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return;
}
loadSettings(mContext, mSettingsValues.mLocale, mSettingsValues.mInputAttributes);
+ StatsUtils.onLoadSettings(mSettingsValues);
} finally {
mSettingsValuesLock.unlock();
}
}
public void loadSettings(final Context context, final Locale locale,
- final InputAttributes inputAttributes) {
+ @Nonnull final InputAttributes inputAttributes) {
mSettingsValuesLock.lock();
mContext = context;
try {
@@ -206,6 +213,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return mSettingsValues.mBlockPotentiallyOffensive;
}
+ public static int readScreenMetrics(final Resources res) {
+ return res.getInteger(R.integer.config_screen_metrics);
+ }
+
// Accessed from the settings interface, hence public
public static boolean readKeypressSoundEnabled(final SharedPreferences prefs,
final Resources res) {
@@ -314,7 +325,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static int readKeyLongpressTimeout(final SharedPreferences prefs,
final Resources res) {
final int milliseconds = prefs.getInt(
- DebugSettings.PREF_KEY_LONGPRESS_TIMEOUT, UNDEFINED_PREFERENCE_VALUE_INT);
+ PREF_KEY_LONGPRESS_TIMEOUT, UNDEFINED_PREFERENCE_VALUE_INT);
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
: readDefaultKeyLongpressTimeout(res);
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 4fc17387f..6c21accf6 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -25,6 +25,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.FeedbackUtils;
import com.android.inputmethodcommon.InputMethodSettingsFragment;
@@ -51,6 +52,11 @@ public final class SettingsFragment extends InputMethodSettingsFragment {
final Preference multilingualOptions = findPreference(Settings.SCREEN_MULTILINGUAL);
preferenceScreen.removePreference(multilingualOptions);
}
+ if (!ProductionFlags.ENABLE_ACCOUNT_SIGN_IN) {
+ final Preference accountsPreference = findPreference(Settings.SCREEN_ACCOUNTS);
+ preferenceScreen.removePreference(accountsPreference);
+ }
+ AdditionalFeaturesSettingUtils.addAdditionalFeaturesPreferences(getActivity(), this);
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index d8c548d8b..bdb4e64e0 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -36,11 +36,14 @@ import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
import java.util.Arrays;
import java.util.Locale;
+import javax.annotation.Nonnull;
+
/**
* 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.RunInLocale}.
*/
-public final class SettingsValues {
+// Non-final for testing via mock library.
+public class SettingsValues {
private static final String TAG = SettingsValues.class.getSimpleName();
// "floatMaxValue" and "floatNegativeInfinity" are special marker strings for
// Float.NEGATIVE_INFINITE and Float.MAX_VALUE. Currently used for auto-correction settings.
@@ -76,10 +79,15 @@ public final class SettingsValues {
public final boolean mSlidingKeyInputPreviewEnabled;
public final boolean mPhraseGestureEnabled;
public final int mKeyLongpressTimeout;
+ public final boolean mEnableEmojiAltPhysicalKey;
public final boolean mEnableMetricsLogging;
- public final boolean mShouldShowUiToAcceptTypedWord;
+ public final boolean mShouldShowLxxSuggestionUi;
+ // Use split layout for keyboard.
+ public final boolean mIsSplitKeyboardEnabled;
+ public final int mScreenMetrics;
// From the input box
+ @Nonnull
public final InputAttributes mInputAttributes;
// Deduced settings
@@ -110,7 +118,7 @@ public final class SettingsValues {
public final float mKeyPreviewDismissEndYScale;
public SettingsValues(final Context context, final SharedPreferences prefs, final Resources res,
- final InputAttributes inputAttributes) {
+ @Nonnull final InputAttributes inputAttributes) {
mLocale = res.getConfiguration().locale;
// Get the resources
mDelayInMillisecondsToUpdateOldSuggestions =
@@ -118,12 +126,7 @@ public final class SettingsValues {
mSpacingAndPunctuations = new SpacingAndPunctuations(res);
// Store the input attributes
- if (null == inputAttributes) {
- mInputAttributes = new InputAttributes(
- null, false /* isFullscreenMode */, context.getPackageName());
- } else {
- mInputAttributes = inputAttributes;
- }
+ mInputAttributes = inputAttributes;
// Get the settings preferences
mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true);
@@ -153,24 +156,29 @@ public final class SettingsValues {
mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
mHasHardwareKeyboard = Settings.readHasHardwareKeyboard(res.getConfiguration());
mEnableMetricsLogging = prefs.getBoolean(Settings.PREF_ENABLE_METRICS_LOGGING, true);
- mShouldShowUiToAcceptTypedWord = Settings.HAS_UI_TO_ACCEPT_TYPED_WORD
- && prefs.getBoolean(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD, true);
+ mIsSplitKeyboardEnabled = prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, false);
+ mScreenMetrics = Settings.readScreenMetrics(res);
+
+ mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI
+ && prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true);
// Compute other readable settings
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
mKeypressSoundVolume = Settings.readKeypressSoundVolume(prefs, res);
mKeyPreviewPopupDismissDelay = Settings.readKeyPreviewPopupDismissDelay(prefs, res);
+ mEnableEmojiAltPhysicalKey = prefs.getBoolean(
+ Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
mAutoCorrectionThreshold = readAutoCorrectionThreshold(res,
autoCorrectionThresholdRawValue);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
- mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
- Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
+ mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText
+ && prefs.getBoolean(Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
mPhraseGestureEnabled = Settings.readPhraseGestureEnabled(prefs, res);
mAutoCorrectionEnabledPerUserSettings = mAutoCorrectEnabled
&& !mInputAttributes.mInputTypeNoAutoCorrect;
mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs);
- AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(
+ AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(context,
prefs, mAdditionalFeaturesSettingValues);
mTextHighlightColorForAddToDictionaryIndicator = res.getColor(
R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color);
@@ -211,6 +219,10 @@ public final class SettingsValues {
}
}
+ public boolean isMetricsLoggingEnabled() {
+ return mEnableMetricsLogging;
+ }
+
public boolean isApplicationSpecifiedCompletionsOn() {
return mInputAttributes.mApplicationSpecifiedCompletionOn;
}
@@ -256,9 +268,8 @@ public final class SettingsValues {
final RichInputMethodManager imm = RichInputMethodManager.getInstance();
if (mIncludesOtherImesInLanguageSwitchList) {
return imm.hasMultipleEnabledIMEsOrSubtypes(false /* include aux subtypes */);
- } else {
- return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
}
+ return imm.hasMultipleEnabledSubtypesInThisIme(false /* include aux subtypes */);
}
public boolean isSameInputType(final EditorInfo editorInfo) {
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index 49d81104d..46aef89c4 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -20,9 +20,9 @@ import android.content.res.Resources;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.MoreKeySpec;
-import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.PunctuationSuggestions;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.utils.StringUtils;
import java.util.Arrays;
@@ -36,6 +36,8 @@ public final class SpacingAndPunctuations {
public final int[] mSortedWordSeparators;
public final PunctuationSuggestions mSuggestPuncList;
private final int mSentenceSeparator;
+ private final int mAbbreviationMarker;
+ private final int[] mSortedSentenceTerminators;
public final String mSentenceSeparatorAndSpace;
public final boolean mCurrentLanguageHasSpaces;
public final boolean mUsesAmericanTypography;
@@ -55,7 +57,10 @@ public final class SpacingAndPunctuations {
res.getString(R.string.symbols_word_connectors));
mSortedWordSeparators = StringUtils.toSortedCodePointArray(
res.getString(R.string.symbols_word_separators));
+ mSortedSentenceTerminators = StringUtils.toSortedCodePointArray(
+ res.getString(R.string.symbols_sentence_terminators));
mSentenceSeparator = res.getInteger(R.integer.sentence_separator);
+ mAbbreviationMarker = res.getInteger(R.integer.abbreviation_marker);
mSentenceSeparatorAndSpace = new String(new int[] {
mSentenceSeparator, Constants.CODE_SPACE }, 0, 2);
mCurrentLanguageHasSpaces = res.getBoolean(R.bool.current_language_has_spaces);
@@ -77,8 +82,10 @@ public final class SpacingAndPunctuations {
mSortedSymbolsClusteringTogether = model.mSortedSymbolsClusteringTogether;
mSortedWordConnectors = model.mSortedWordConnectors;
mSortedWordSeparators = overrideSortedWordSeparators;
+ mSortedSentenceTerminators = model.mSortedSentenceTerminators;
mSuggestPuncList = model.mSuggestPuncList;
mSentenceSeparator = model.mSentenceSeparator;
+ mAbbreviationMarker = model.mAbbreviationMarker;
mSentenceSeparatorAndSpace = model.mSentenceSeparatorAndSpace;
mCurrentLanguageHasSpaces = model.mCurrentLanguageHasSpaces;
mUsesAmericanTypography = model.mUsesAmericanTypography;
@@ -109,6 +116,14 @@ public final class SpacingAndPunctuations {
return Arrays.binarySearch(mSortedSymbolsClusteringTogether, code) >= 0;
}
+ public boolean isSentenceTerminator(final int code) {
+ return Arrays.binarySearch(mSortedSentenceTerminators, code) >= 0;
+ }
+
+ public boolean isAbbreviationMarker(final int code) {
+ return code == mAbbreviationMarker;
+ }
+
public boolean isSentenceSeparator(final int code) {
return code == mSentenceSeparator;
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
index ca5b395ce..240f8f89b 100644
--- a/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SubScreenFragment.java
@@ -20,6 +20,7 @@ import android.app.backup.BackupManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
@@ -79,6 +80,16 @@ abstract class SubScreenFragment extends PreferenceFragment
return getPreferenceManager().getSharedPreferences();
}
+ /**
+ * Gets the application name to display on the UI.
+ */
+ final String getApplicationName() {
+ final Context context = getActivity();
+ final Resources res = getResources();
+ final int applicationLabelRes = context.getApplicationInfo().labelRes;
+ return res.getString(applicationLabelRes);
+ }
+
@Override
public void addPreferencesFromResource(final int preferencesResId) {
super.addPreferencesFromResource(preferencesResId);
diff --git a/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java b/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java
new file mode 100644
index 000000000..254bc6567
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/settings/TestFragmentActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.settings;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Test activity to use when testing preference fragments. <br/>
+ * Usage: <br/>
+ * Create an ActivityInstrumentationTestCase2 for this activity
+ * and call setIntent() with an intent that specifies the fragment to load in the activity.
+ * The fragment can then be obtained from this activity and used for testing/verification.
+ */
+public final class TestFragmentActivity extends Activity {
+ /**
+ * The fragment name that should be loaded when starting this activity.
+ * This must be specified when starting this activity, as this activity is only
+ * meant to test fragments from instrumentation tests.
+ */
+ public static final String EXTRA_SHOW_FRAGMENT = "show_fragment";
+
+ public Fragment mFragment;
+
+ @Override
+ protected void onCreate(final Bundle savedState) {
+ super.onCreate(savedState);
+ final Intent intent = getIntent();
+ final String fragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
+ if (fragmentName == null) {
+ throw new IllegalArgumentException("No fragment name specified for testing");
+ }
+
+ mFragment = Fragment.instantiate(this, fragmentName);
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.beginTransaction().add(mFragment, fragmentName).commit();
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
index 5a3fc3600..29289aed2 100644
--- a/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.latin.settings;
import android.content.Context;
-import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.Preference;
@@ -32,12 +31,12 @@ import com.android.inputmethod.latin.settings.RadioButtonPreference.OnRadioButto
*/
public final class ThemeSettingsFragment extends SubScreenFragment
implements OnRadioButtonClickedListener {
- private String mSelectedThemeId;
+ private int mSelectedThemeId;
static class KeyboardThemePreference extends RadioButtonPreference {
- final String mThemeId;
+ final int mThemeId;
- KeyboardThemePreference(final Context context, final String name, final String id) {
+ KeyboardThemePreference(final Context context, final String name, final int id) {
super(context);
setTitle(name);
mThemeId = id;
@@ -45,14 +44,13 @@ public final class ThemeSettingsFragment extends SubScreenFragment
}
static void updateKeyboardThemeSummary(final Preference pref) {
- final Resources res = pref.getContext().getResources();
- final SharedPreferences prefs = pref.getSharedPreferences();
- final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
- final String keyboardThemeId = String.valueOf(keyboardTheme.mThemeId);
+ final Context context = pref.getContext();
+ final Resources res = context.getResources();
+ final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(context);
final String[] keyboardThemeNames = res.getStringArray(R.array.keyboard_theme_names);
- final String[] keyboardThemeIds = res.getStringArray(R.array.keyboard_theme_ids);
+ final int[] keyboardThemeIds = res.getIntArray(R.array.keyboard_theme_ids);
for (int index = 0; index < keyboardThemeNames.length; index++) {
- if (keyboardThemeId.equals(keyboardThemeIds[index])) {
+ if (keyboardTheme.mThemeId == keyboardThemeIds[index]) {
pref.setSummary(keyboardThemeNames[index]);
return;
}
@@ -64,18 +62,18 @@ public final class ThemeSettingsFragment extends SubScreenFragment
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_theme);
final PreferenceScreen screen = getPreferenceScreen();
+ final Context context = getActivity();
final Resources res = getResources();
final String[] keyboardThemeNames = res.getStringArray(R.array.keyboard_theme_names);
- final String[] keyboardThemeIds = res.getStringArray(R.array.keyboard_theme_ids);
+ final int[] keyboardThemeIds = res.getIntArray(R.array.keyboard_theme_ids);
for (int index = 0; index < keyboardThemeNames.length; index++) {
final KeyboardThemePreference pref = new KeyboardThemePreference(
- getActivity(), keyboardThemeNames[index], keyboardThemeIds[index]);
+ context, keyboardThemeNames[index], keyboardThemeIds[index]);
screen.addPreference(pref);
pref.setOnRadioButtonClickedListener(this);
}
- final SharedPreferences prefs = getSharedPreferences();
- final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
- mSelectedThemeId = String.valueOf(keyboardTheme.mThemeId);
+ final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(context);
+ mSelectedThemeId = keyboardTheme.mThemeId;
}
@Override
@@ -106,7 +104,7 @@ public final class ThemeSettingsFragment extends SubScreenFragment
final Preference preference = screen.getPreference(index);
if (preference instanceof KeyboardThemePreference) {
final KeyboardThemePreference pref = (KeyboardThemePreference)preference;
- final boolean selected = mSelectedThemeId.equals(pref.mThemeId);
+ final boolean selected = (mSelectedThemeId == pref.mThemeId);
pref.setSelected(selected);
}
}