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..c07b60a0b --- /dev/null +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java @@ -0,0 +1,358 @@ +/* + * 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); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @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 { + public final String mLocaleString; + private final String mDisplayName; + + public SubtypeLocaleItem(final InputMethodSubtype subtype) { + mLocaleString = subtype.getLocale(); + mDisplayName = SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale( + mLocaleString); + } + + // {@link ArrayAdapter} 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 { + 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 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} 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 { + 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 c633fc167..46fcc7106 100644 --- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java @@ -17,16 +17,12 @@ 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; @@ -39,15 +35,9 @@ 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,19 +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(); - private static final boolean DEBUG_SUBTYPE_ID = false; // 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; @@ -79,320 +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 implements Comparable { - public final String mLocaleString; - private final String mDisplayName; - - public SubtypeLocaleItem(final InputMethodSubtype subtype) { - mLocaleString = subtype.getLocale(); - mDisplayName = SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale( - mLocaleString); - } - - // {@link ArrayAdapter} 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 { - 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 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} 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 { - 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) { - 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.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.mLocaleString, layout.mLayoutName); - 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 CREATOR = - new Parcelable.Creator() { - @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,8 +115,9 @@ 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()); @@ -454,7 +130,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { && savedInstanceState.containsKey(KEY_IS_ADDING_NEW_SUBTYPE); if (mIsAddingNewSubtype) { getPreferenceScreen().addPreference( - SubtypePreference.newIncompleteSubtypePreference(context, mSubtypeProxy)); + CustomInputStylePreference.newIncompleteSubtypePreference(context, this)); } super.onActivityCreated(savedInstanceState); @@ -482,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(stylePref); + showSubtypeAlreadyExistsToast(subtype); + } - // Newly added subtype is duplicated. - final PreferenceGroup group = getPreferenceScreen(); - group.removePreference(subtypePref); - showSubtypeAlreadyExistsToast(subtype); - } + @Override + public CustomInputStylePreference.SubtypeLocaleAdapter getSubtypeLocaleAdapter() { + return mSubtypeLocaleAdapter; + } - @Override - public 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(); @@ -555,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) @@ -564,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); @@ -584,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); } } @@ -596,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()); @@ -631,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;