From cd6fdead7c7a42f4a18a37523bb4feef230559c0 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 10 Jul 2014 15:37:28 +0900 Subject: [PATCH] Reorganize spell checkers settings Bug: 15976603 Bug: 16115751 Change-Id: I3b23d7f01d8d39da27215a5263b12304ac64db0f --- res/layout/preference_inputmethod.xml | 99 -------- res/layout/preference_spellchecker.xml | 66 ++---- ...xml => preference_spellchecker_widget.xml} | 11 +- res/xml/language_settings.xml | 6 +- res/xml/spellchecker_prefs.xml | 10 +- .../CheckBoxAndSettingsPreference.java | 132 ----------- .../InputMethodAndLanguageSettings.java | 35 ++- .../inputmethod/InputMethodPreference.java | 6 +- .../SingleSpellCheckerPreference.java | 214 ------------------ .../inputmethod/SpellCheckerPreference.java | 151 ++++++++++++ .../inputmethod/SpellCheckersPreference.java | 54 ----- .../inputmethod/SpellCheckersSettings.java | 197 +++++++++++----- 12 files changed, 363 insertions(+), 618 deletions(-) delete mode 100644 res/layout/preference_inputmethod.xml rename res/layout/{preference_inputmethod_widget.xml => preference_spellchecker_widget.xml} (78%) delete mode 100644 src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java delete mode 100644 src/com/android/settings/inputmethod/SingleSpellCheckerPreference.java create mode 100644 src/com/android/settings/inputmethod/SpellCheckerPreference.java delete mode 100644 src/com/android/settings/inputmethod/SpellCheckersPreference.java diff --git a/res/layout/preference_inputmethod.xml b/res/layout/preference_inputmethod.xml deleted file mode 100644 index 9e3d5e35a7a..00000000000 --- a/res/layout/preference_inputmethod.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/layout/preference_spellchecker.xml b/res/layout/preference_spellchecker.xml index dd35cb3673f..640897699a5 100644 --- a/res/layout/preference_spellchecker.xml +++ b/res/layout/preference_spellchecker.xml @@ -13,9 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. --> + - + android:layout_height="match_parent" + android:gravity="center_vertical" + android:orientation="vertical" /> + android:fadingEdge="horizontal"/> - - - - - - - - + android:background="?android:attr/selectableItemBackground" /> - \ No newline at end of file + diff --git a/res/layout/preference_inputmethod_widget.xml b/res/layout/preference_spellchecker_widget.xml similarity index 78% rename from res/layout/preference_inputmethod_widget.xml rename to res/layout/preference_spellchecker_widget.xml index ee573add122..e4971ec9be6 100644 --- a/res/layout/preference_inputmethod_widget.xml +++ b/res/layout/preference_spellchecker_widget.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + android:clickable="false" + android:focusable="false" /> \ No newline at end of file diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml index 35926a0a405..b493a0ff86b 100644 --- a/res/xml/language_settings.xml +++ b/res/xml/language_settings.xml @@ -25,10 +25,14 @@ android:fragment="com.android.settings.LocalePicker" /> - + + diff --git a/res/xml/spellchecker_prefs.xml b/res/xml/spellchecker_prefs.xml index 1de04937614..666b0a9b0c1 100644 --- a/res/xml/spellchecker_prefs.xml +++ b/res/xml/spellchecker_prefs.xml @@ -14,7 +14,11 @@ limitations under the License. --> - - + + diff --git a/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java b/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java deleted file mode 100644 index c6208ed1cae..00000000000 --- a/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.inputmethod; - -import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.Utils; - -import android.content.Context; -import android.content.Intent; -import android.preference.CheckBoxPreference; -import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; -import android.widget.TextView; - -// TODO: Make this non-persistent. -class CheckBoxAndSettingsPreference extends CheckBoxPreference { - - private SettingsPreferenceFragment mFragment; - private TextView mTitleText; - private TextView mSummaryText; - private ImageView mSettingsButton; - private Intent mSettingsIntent; - - public CheckBoxAndSettingsPreference(Context context) { - this(context, null); - } - - public CheckBoxAndSettingsPreference(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public CheckBoxAndSettingsPreference(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - public CheckBoxAndSettingsPreference(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - - setLayoutResource(R.layout.preference_inputmethod); - setWidgetLayoutResource(R.layout.preference_inputmethod_widget); - } - - @Override - protected void onBindView(View view) { - super.onBindView(view); - View textLayout = view.findViewById(R.id.inputmethod_pref); - textLayout.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View arg0) { - onCheckBoxClicked(); - } - }); - - mSettingsButton = (ImageView) view.findViewById(R.id.inputmethod_settings); - mTitleText = (TextView)view.findViewById(android.R.id.title); - mSummaryText = (TextView)view.findViewById(android.R.id.summary); - mSettingsButton.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View clickedView) { - onSettingsButtonClicked(); - } - }); - enableSettingsButton(); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - enableSettingsButton(); - } - - public void setFragmentIntent(SettingsPreferenceFragment fragment, Intent intent) { - mFragment = fragment; - mSettingsIntent = intent; - } - - protected void onCheckBoxClicked() { - if (isChecked()) { - setChecked(false); - } else { - setChecked(true); - } - } - - protected void onSettingsButtonClicked() { - if (mFragment != null && mSettingsIntent != null) { - mFragment.startActivity(mSettingsIntent); - } - } - - private void enableSettingsButton() { - if (mSettingsButton != null) { - if (mSettingsIntent == null) { - mSettingsButton.setVisibility(View.GONE); - } else { - final boolean checked = isChecked(); - mSettingsButton.setEnabled(checked); - mSettingsButton.setClickable(checked); - mSettingsButton.setFocusable(checked); - if (!checked) { - mSettingsButton.setAlpha(Utils.DISABLED_ALPHA); - } - } - } - if (mTitleText != null) { - mTitleText.setEnabled(true); - } - if (mSummaryText != null) { - mSummaryText.setEnabled(true); - } - } -} diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 073daa67fc2..4166dbb68e7 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -48,10 +48,11 @@ import android.view.InputDevice; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; +import android.view.textservice.SpellCheckerInfo; +import android.view.textservice.TextServicesManager; import com.android.settings.R; import com.android.settings.Settings.KeyboardLayoutPickerActivity; -import com.android.settings.Settings.SpellCheckersSettingsActivity; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.SubSettings; @@ -72,7 +73,8 @@ import java.util.TreeSet; public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener, KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener, Indexable, - InputMethodPreference.onSavePreferenceListener { + InputMethodPreference.OnSavePreferenceListener { + private static final String KEY_SPELL_CHECKERS = "spellcheckers_settings"; private static final String KEY_PHONE_LANGUAGE = "phone_language"; private static final String KEY_CHOOSE_INPUT_METHODS = "choose_input_methods"; private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method"; @@ -171,12 +173,17 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment updateInputDevices(); // Spell Checker - final SpellCheckersPreference scp = ((SpellCheckersPreference)findPreference( - "spellcheckers_settings")); - if (scp != null) { + final Preference spellChecker = findPreference(KEY_SPELL_CHECKERS); + if (spellChecker != null) { + // Note: KEY_SPELL_CHECKERS preference is marked as persistent="false" in XML. + InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(spellChecker); final Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setClass(activity, SpellCheckersSettingsActivity.class); - scp.setFragmentIntent(this, intent); + intent.setClass(activity, SubSettings.class); + intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, + SpellCheckersSettings.class.getName()); + intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, + R.string.spellcheckers_settings_title); + spellChecker.setIntent(intent); } mHandler = new Handler(); @@ -239,6 +246,18 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment mSettingsObserver.resume(); mIm.registerInputDeviceListener(this, null); + final Preference spellChecker = findPreference(KEY_SPELL_CHECKERS); + if (spellChecker != null) { + final TextServicesManager tsm = (TextServicesManager) getSystemService( + Context.TEXT_SERVICES_MANAGER_SERVICE); + if (tsm.isSpellCheckerEnabled()) { + final SpellCheckerInfo sci = tsm.getCurrentSpellChecker(); + spellChecker.setSummary(sci.loadLabel(getPackageManager())); + } else { + spellChecker.setSummary(R.string.switch_off_text); + } + } + if (!mShowsOnlyFullImeAndKeyboardList) { if (mLanguagePref != null) { String localeName = getLocaleName(getResources()); @@ -641,7 +660,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment // Spell checker. SearchIndexableRaw indexable = new SearchIndexableRaw(context); - indexable.key = "spellcheckers_settings"; + indexable.key = KEY_SPELL_CHECKERS; indexable.title = context.getString(R.string.spellcheckers_settings_title); indexable.screenTitle = screenTitle; indexables.add(indexable); diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java index 140487571b5..084da193359 100755 --- a/src/com/android/settings/inputmethod/InputMethodPreference.java +++ b/src/com/android/settings/inputmethod/InputMethodPreference.java @@ -51,7 +51,7 @@ class InputMethodPreference extends SwitchPreference implements OnPreferenceClic private static final String TAG = InputMethodPreference.class.getSimpleName(); private static final String EMPTY_TEXT = ""; - interface onSavePreferenceListener { + interface OnSavePreferenceListener { /** * Called when this preference needs to be saved its state. * @@ -66,7 +66,7 @@ class InputMethodPreference extends SwitchPreference implements OnPreferenceClic private final InputMethodInfo mImi; private final boolean mHasPriorityInSorting; - private final onSavePreferenceListener mOnSaveListener; + private final OnSavePreferenceListener mOnSaveListener; private final InputMethodSettingValuesWrapper mInputMethodSettingValues; private AlertDialog mDialog = null; @@ -82,7 +82,7 @@ class InputMethodPreference extends SwitchPreference implements OnPreferenceClic * to save the state to shared preference. */ InputMethodPreference(final Context context, final InputMethodInfo imi, - final boolean isImeEnabler, final onSavePreferenceListener onSaveListener) { + final boolean isImeEnabler, final OnSavePreferenceListener onSaveListener) { super(context); setPersistent(false); mImi = imi; diff --git a/src/com/android/settings/inputmethod/SingleSpellCheckerPreference.java b/src/com/android/settings/inputmethod/SingleSpellCheckerPreference.java deleted file mode 100644 index 2dc90eca388..00000000000 --- a/src/com/android/settings/inputmethod/SingleSpellCheckerPreference.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.inputmethod; - -import com.android.settings.R; -import com.android.settings.Utils; - -import android.app.AlertDialog; -import android.content.ActivityNotFoundException; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.preference.Preference; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.textservice.SpellCheckerInfo; -import android.view.textservice.SpellCheckerSubtype; -import android.view.textservice.TextServicesManager; -import android.widget.ImageView; -import android.widget.RadioButton; -import android.widget.Toast; - -// TODO: Make this non-persistent. -class SingleSpellCheckerPreference extends Preference { - private static final String TAG = SingleSpellCheckerPreference.class.getSimpleName(); - private static final boolean DBG = false; - - private final SpellCheckerInfo mSpellCheckerInfo; - - private final SpellCheckersSettings mFragment; - private final Resources mRes; - private final TextServicesManager mTsm; - private AlertDialog mDialog = null; - private View mPrefAll; - private RadioButton mRadioButton; - private View mPrefLeftButton; - private View mSettingsButton; - private ImageView mSubtypeButton; - private Intent mSettingsIntent; - private boolean mSelected; - - public SingleSpellCheckerPreference(SpellCheckersSettings fragment, SpellCheckerInfo sci, - TextServicesManager tsm) { - super(fragment.getActivity(), null, 0); - mFragment = fragment; - mRes = fragment.getActivity().getResources(); - mTsm = tsm; - setLayoutResource(R.layout.preference_spellchecker); - mSpellCheckerInfo = sci; - mSelected = false; - final String settingsActivity = mSpellCheckerInfo.getSettingsActivity(); - if (!TextUtils.isEmpty(settingsActivity)) { - mSettingsIntent = new Intent(Intent.ACTION_MAIN); - mSettingsIntent.setClassName(mSpellCheckerInfo.getPackageName(), settingsActivity); - } else { - mSettingsIntent = null; - } - } - - @Override - protected void onBindView(View view) { - super.onBindView(view); - mPrefAll = view.findViewById(R.id.pref_all); - mRadioButton = (RadioButton)view.findViewById(R.id.pref_radio); - mPrefLeftButton = view.findViewById(R.id.pref_left_button); - mPrefLeftButton.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View arg0) { - onLeftButtonClicked(arg0); - } - }); - mSubtypeButton = (ImageView)view.findViewById(R.id.pref_right_button2); - mSubtypeButton.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View arg0) { - onSubtypeButtonClicked(arg0); - } - }); - mSettingsButton = view.findViewById(R.id.pref_right_button1); - mSettingsButton.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View arg0) { - onSettingsButtonClicked(arg0); - } - }); - updateSelectedState(mSelected); - } - - private void onLeftButtonClicked(View arg0) { - mFragment.onPreferenceClick(this); - } - - public SpellCheckerInfo getSpellCheckerInfo() { - return mSpellCheckerInfo; - } - - private void updateSelectedState(boolean selected) { - if (mPrefAll != null) { - mRadioButton.setChecked(selected); - enableButtons(selected); - } - } - - public void setSelected(boolean selected) { - mSelected = selected; - updateSelectedState(selected); - } - - private void onSubtypeButtonClicked(View arg0) { - if (mDialog != null && mDialog.isShowing()) { - mDialog.dismiss(); - } - final AlertDialog.Builder builder = new AlertDialog.Builder(mFragment.getActivity()); - builder.setTitle(R.string.phone_language); - final int size = mSpellCheckerInfo.getSubtypeCount(); - final CharSequence[] items = new CharSequence[size + 1]; - items[0] = mRes.getString(R.string.use_system_language_to_select_input_method_subtypes); - for (int i = 0; i < size; ++i) { - final SpellCheckerSubtype subtype = mSpellCheckerInfo.getSubtypeAt(i); - final CharSequence label = subtype.getDisplayName( - mFragment.getActivity(), mSpellCheckerInfo.getPackageName(), - mSpellCheckerInfo.getServiceInfo().applicationInfo); - items[i + 1] = label; - } - // default: "Use system language" - int checkedItem = 0; - // Allow no implicitly selected subtypes - final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(false); - if (currentScs != null) { - for (int i = 0; i < size; ++i) { - if (mSpellCheckerInfo.getSubtypeAt(i).equals(currentScs)) { - checkedItem = i + 1; - break; - } - } - } - builder.setSingleChoiceItems(items, checkedItem, new AlertDialog.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == 0) { - mTsm.setSpellCheckerSubtype(null); - } else { - mTsm.setSpellCheckerSubtype(mSpellCheckerInfo.getSubtypeAt(which - 1)); - } - if (DBG) { - final SpellCheckerSubtype subtype = mTsm.getCurrentSpellCheckerSubtype(true); - Log.d(TAG, "Current spell check locale is " - + subtype == null ? "null" : subtype.getLocale()); - } - dialog.dismiss(); - } - }); - mDialog = builder.create(); - mDialog.show(); - } - - private void onSettingsButtonClicked(View arg0) { - if (mFragment != null && mSettingsIntent != null) { - try { - mFragment.startActivity(mSettingsIntent); - } catch (ActivityNotFoundException e) { - final String msg = mFragment.getString(R.string.failed_to_open_app_settings_toast, - mSpellCheckerInfo.loadLabel(mFragment.getActivity().getPackageManager())); - Toast.makeText(mFragment.getActivity(), msg, Toast.LENGTH_LONG).show(); - } - } - } - - private void enableButtons(boolean enabled) { - if (mSettingsButton != null) { - if (mSettingsIntent == null) { - mSettingsButton.setVisibility(View.GONE); - } else { - mSettingsButton.setEnabled(enabled); - mSettingsButton.setClickable(enabled); - mSettingsButton.setFocusable(enabled); - if (!enabled) { - mSettingsButton.setAlpha(Utils.DISABLED_ALPHA); - } - } - } - if (mSubtypeButton != null) { - if (mSpellCheckerInfo.getSubtypeCount() <= 0) { - mSubtypeButton.setVisibility(View.GONE); - } else { - mSubtypeButton.setEnabled(enabled); - mSubtypeButton.setClickable(enabled); - mSubtypeButton.setFocusable(enabled); - if (!enabled) { - mSubtypeButton.setAlpha(Utils.DISABLED_ALPHA); - } - } - } - } -} diff --git a/src/com/android/settings/inputmethod/SpellCheckerPreference.java b/src/com/android/settings/inputmethod/SpellCheckerPreference.java new file mode 100644 index 00000000000..37878032d60 --- /dev/null +++ b/src/com/android/settings/inputmethod/SpellCheckerPreference.java @@ -0,0 +1,151 @@ +/* + * 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.settings.inputmethod; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.preference.Preference; +import android.text.TextUtils; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.textservice.SpellCheckerInfo; +import android.widget.RadioButton; +import android.widget.Toast; + +import com.android.settings.R; +import com.android.settings.Utils; + +/** + * Spell checker service preference. + * + * This preference represents a spell checker service. It is used for two purposes. 1) A radio + * button on the left side is used to choose the current spell checker service. 2) A settings + * icon on the right side is used to invoke the setting activity of the spell checker service. + */ +class SpellCheckerPreference extends Preference implements OnClickListener { + interface OnRadioButtonPreferenceListener { + /** + * Called when this preference needs to be saved its state. + * + * Note that this preference is non-persistent and needs explicitly to be saved its state. + * Because changing one IME state may change other IMEs' state, this is a place to update + * other IMEs' state as well. + * + * @param pref This preference. + */ + public void onRadioButtonClicked(SpellCheckerPreference pref); + } + + private final SpellCheckerInfo mSci; + private final OnRadioButtonPreferenceListener mOnRadioButtonListener; + + private RadioButton mRadioButton; + private View mPrefLeftButton; + private View mSettingsButton; + private boolean mSelected; + + public SpellCheckerPreference(final Context context, final SpellCheckerInfo sci, + final OnRadioButtonPreferenceListener onRadioButtonListener) { + super(context, null, 0); + setPersistent(false); + setLayoutResource(R.layout.preference_spellchecker); + setWidgetLayoutResource(R.layout.preference_spellchecker_widget); + mSci = sci; + mOnRadioButtonListener = onRadioButtonListener; + setKey(sci.getId()); + setTitle(sci.loadLabel(context.getPackageManager())); + final String settingsActivity = mSci.getSettingsActivity(); + if (TextUtils.isEmpty(settingsActivity)) { + setIntent(null); + } else { + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClassName(mSci.getPackageName(), settingsActivity); + setIntent(intent); + } + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + mRadioButton = (RadioButton)view.findViewById(R.id.pref_radio); + mPrefLeftButton = view.findViewById(R.id.pref_left_button); + mPrefLeftButton.setOnClickListener(this); + mSettingsButton = view.findViewById(R.id.pref_right_button); + mSettingsButton.setOnClickListener(this); + updateSelectedState(mSelected); + } + + @Override + public void onClick(final View v) { + if (v == mPrefLeftButton) { + mOnRadioButtonListener.onRadioButtonClicked(this); + return; + } + if (v == mSettingsButton) { + onSettingsButtonClicked(); + return; + } + } + + private void onSettingsButtonClicked() { + final Context context = getContext(); + try { + final Intent intent = getIntent(); + if (intent != null) { + // Invoke a settings activity of an spell checker. + context.startActivity(intent); + } + } catch (final ActivityNotFoundException e) { + final String message = context.getString(R.string.failed_to_open_app_settings_toast, + mSci.loadLabel(context.getPackageManager())); + Toast.makeText(context, message, Toast.LENGTH_LONG).show(); + } + } + + public SpellCheckerInfo getSpellCheckerInfo() { + return mSci; + } + + public void setSelected(final boolean selected) { + mSelected = selected; + updateSelectedState(selected); + } + + private void updateSelectedState(final boolean selected) { + if (mRadioButton != null) { + mRadioButton.setChecked(selected); + enableSettingsButton(isEnabled() && selected); + } + } + + private void enableSettingsButton(final boolean enabled) { + if (mSettingsButton == null) { + return; + } + if (getIntent() == null) { + mSettingsButton.setVisibility(View.GONE); + } else { + mSettingsButton.setEnabled(enabled); + mSettingsButton.setClickable(enabled); + mSettingsButton.setFocusable(enabled); + if (!enabled) { + mSettingsButton.setAlpha(Utils.DISABLED_ALPHA); + } + } + } +} diff --git a/src/com/android/settings/inputmethod/SpellCheckersPreference.java b/src/com/android/settings/inputmethod/SpellCheckersPreference.java deleted file mode 100644 index 1482b6c9c2f..00000000000 --- a/src/com/android/settings/inputmethod/SpellCheckersPreference.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.inputmethod; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.textservice.TextServicesManager; - -// TODO: Make this non-persistent. -class SpellCheckersPreference extends CheckBoxAndSettingsPreference { - private TextServicesManager mTsm; - - public SpellCheckersPreference(Context context) { - this(context, null); - } - - public SpellCheckersPreference(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public SpellCheckersPreference(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - public SpellCheckersPreference(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - - mTsm = (TextServicesManager) context.getSystemService( - Context.TEXT_SERVICES_MANAGER_SERVICE); - setChecked(mTsm.isSpellCheckerEnabled()); - } - - @Override - protected void onCheckBoxClicked() { - super.onCheckBoxClicked(); - final boolean checked = isChecked(); - mTsm.setSpellCheckerEnabled(checked); - } -} diff --git a/src/com/android/settings/inputmethod/SpellCheckersSettings.java b/src/com/android/settings/inputmethod/SpellCheckersSettings.java index 40d861953e6..5a8ccea130a 100644 --- a/src/com/android/settings/inputmethod/SpellCheckersSettings.java +++ b/src/com/android/settings/inputmethod/SpellCheckersSettings.java @@ -20,104 +20,201 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; import android.util.Log; import android.view.textservice.SpellCheckerInfo; +import android.view.textservice.SpellCheckerSubtype; import android.view.textservice.TextServicesManager; +import android.widget.Switch; import com.android.settings.R; +import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; - -import java.util.ArrayList; +import com.android.settings.inputmethod.SpellCheckerPreference.OnRadioButtonPreferenceListener; +import com.android.settings.widget.SwitchBar; +import com.android.settings.widget.SwitchBar.OnSwitchChangeListener; public class SpellCheckersSettings extends SettingsPreferenceFragment - implements Preference.OnPreferenceClickListener { + implements OnSwitchChangeListener, OnPreferenceClickListener, + OnRadioButtonPreferenceListener { private static final String TAG = SpellCheckersSettings.class.getSimpleName(); private static final boolean DBG = false; + private static final String KEY_SPELL_CHECKER_LANGUAGE = "spellchecker_language"; + private static final int ITEM_ID_USE_SYSTEM_LANGUAGE = 0; + + private SwitchBar mSwitchBar; + private Preference mSpellCheckerLanaguagePref; private AlertDialog mDialog = null; private SpellCheckerInfo mCurrentSci; private SpellCheckerInfo[] mEnabledScis; private TextServicesManager mTsm; - private final ArrayList mSpellCheckers = new ArrayList<>(); @Override public void onCreate(final Bundle icicle) { super.onCreate(icicle); - mTsm = (TextServicesManager) getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE); + addPreferencesFromResource(R.xml.spellchecker_prefs); - updateScreen(); + mSpellCheckerLanaguagePref = findPreference(KEY_SPELL_CHECKER_LANGUAGE); + mSpellCheckerLanaguagePref.setOnPreferenceClickListener(this); + + mTsm = (TextServicesManager) getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE); + mCurrentSci = mTsm.getCurrentSpellChecker(); + mEnabledScis = mTsm.getEnabledSpellCheckers(); + populatePreferenceScreen(); } - // Override the behavior of {@link PreferenceFragment}. - @Override - public boolean onPreferenceTreeClick(final PreferenceScreen screen, - final Preference preference) { - return false; + private void populatePreferenceScreen() { + final PreferenceScreen screen = getPreferenceScreen(); + final Context context = getActivity(); + final int count = (mEnabledScis == null) ? 0 : mEnabledScis.length; + for (int index = 0; index < count; ++index) { + final SpellCheckerInfo sci = mEnabledScis[index]; + final SpellCheckerPreference pref = new SpellCheckerPreference(context, sci, this); + screen.addPreference(pref); + InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref); + } } @Override public void onResume() { super.onResume(); - updateScreen(); + mSwitchBar = ((SettingsActivity)getActivity()).getSwitchBar(); + mSwitchBar.show(); + mSwitchBar.addOnSwitchChangeListener(this); + updatePreferenceScreen(); } - private void updateScreen() { - getPreferenceScreen().removeAll(); - updateEnabledSpellCheckers(); + @Override + public void onPause() { + super.onPause(); + mSwitchBar.removeOnSwitchChangeListener(this); } - private void updateEnabledSpellCheckers() { + @Override + public void onSwitchChanged(final Switch switchView, final boolean isChecked) { + mTsm.setSpellCheckerEnabled(isChecked); + updatePreferenceScreen(); + } + + private void updatePreferenceScreen() { mCurrentSci = mTsm.getCurrentSpellChecker(); - mEnabledScis = mTsm.getEnabledSpellCheckers(); - if (mCurrentSci == null || mEnabledScis == null) { - return; + final boolean isSpellCheckerEnabled = mTsm.isSpellCheckerEnabled(); + mSwitchBar.setChecked(isSpellCheckerEnabled); + + final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype( + false /* allowImplicitlySelectedSubtype */); + mSpellCheckerLanaguagePref.setSummary(getSpellCheckerSubtypeLabel(mCurrentSci, currentScs)); + + final PreferenceScreen screen = getPreferenceScreen(); + final int count = screen.getPreferenceCount(); + for (int index = 0; index < count; index++) { + final Preference preference = screen.getPreference(index); + preference.setEnabled(isSpellCheckerEnabled); + if (preference instanceof SpellCheckerPreference) { + final SpellCheckerPreference pref = (SpellCheckerPreference)preference; + final SpellCheckerInfo sci = pref.getSpellCheckerInfo(); + pref.setSelected(mCurrentSci != null && mCurrentSci.getId().equals(sci.getId())); + } } - final PackageManager pm = getPackageManager(); - mSpellCheckers.clear(); - for (int i = 0; i < mEnabledScis.length; ++i) { - final SpellCheckerInfo sci = mEnabledScis[i]; - final SingleSpellCheckerPreference scPref = new SingleSpellCheckerPreference( - this, sci, mTsm); - mSpellCheckers.add(scPref); - scPref.setTitle(sci.loadLabel(pm)); - scPref.setSelected(mCurrentSci != null && mCurrentSci.getId().equals(sci.getId())); - getPreferenceScreen().addPreference(scPref); + } + + private CharSequence getSpellCheckerSubtypeLabel(final SpellCheckerInfo sci, + final SpellCheckerSubtype subtype) { + if (sci == null) { + return null; } + if (subtype == null) { + return getString(R.string.use_system_language_to_select_input_method_subtypes); + } + return subtype.getDisplayName( + getActivity(), sci.getPackageName(), sci.getServiceInfo().applicationInfo); } @Override public boolean onPreferenceClick(final Preference pref) { - for (final SingleSpellCheckerPreference scp : mSpellCheckers) { - if (pref.equals(scp)) { - if (isSystemApp(scp.getSpellCheckerInfo())) { - changeCurrentSpellChecker(scp); - } else { - showSecurityWarnDialog(scp); - } - return true; - } + if (pref == mSpellCheckerLanaguagePref) { + showChooseLanguageDialog(); + return true; } - return true; + return false; } - private void showSecurityWarnDialog(final SingleSpellCheckerPreference scp) { + @Override + public void onRadioButtonClicked(final SpellCheckerPreference pref) { + final SpellCheckerInfo sci = pref.getSpellCheckerInfo(); + final boolean isSystemApp = + (sci.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + if (isSystemApp) { + changeCurrentSpellChecker(sci); + } else { + showSecurityWarnDialog(pref); + } + } + + private static int convertSubtypeIndexToDialogItemId(final int index) { return index + 1; } + private static int convertDialogItemIdToSubtypeIndex(final int item) { return item - 1; } + + private void showChooseLanguageDialog() { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } + final SpellCheckerInfo currentSci = mTsm.getCurrentSpellChecker(); + final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype( + false /* allowImplicitlySelectedSubtype */); + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.phone_language); + final int subtypeCount = currentSci.getSubtypeCount(); + final CharSequence[] items = new CharSequence[subtypeCount + 1 /* default */ ]; + items[ITEM_ID_USE_SYSTEM_LANGUAGE] = getSpellCheckerSubtypeLabel(currentSci, null); + int checkedItemId = ITEM_ID_USE_SYSTEM_LANGUAGE; + for (int index = 0; index < subtypeCount; ++index) { + final SpellCheckerSubtype subtype = currentSci.getSubtypeAt(index); + final int itemId = convertSubtypeIndexToDialogItemId(index); + items[itemId] = getSpellCheckerSubtypeLabel(currentSci, subtype); + if (subtype.equals(currentScs)) { + checkedItemId = itemId; + } + } + builder.setSingleChoiceItems(items, checkedItemId, new AlertDialog.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int item) { + if (item == ITEM_ID_USE_SYSTEM_LANGUAGE) { + mTsm.setSpellCheckerSubtype(null); + } else { + final int index = convertDialogItemIdToSubtypeIndex(item); + mTsm.setSpellCheckerSubtype(currentSci.getSubtypeAt(index)); + } + if (DBG) { + final SpellCheckerSubtype subtype = mTsm.getCurrentSpellCheckerSubtype( + true /* allowImplicitlySelectedSubtype */); + Log.d(TAG, "Current spell check locale is " + + subtype == null ? "null" : subtype.getLocale()); + } + dialog.dismiss(); + updatePreferenceScreen(); + } + }); + mDialog = builder.create(); + mDialog.show(); + } + + private void showSecurityWarnDialog(final SpellCheckerPreference pref) { + if (mDialog != null && mDialog.isShowing()) { + mDialog.dismiss(); + } + final SpellCheckerInfo sci = pref.getSpellCheckerInfo(); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(android.R.string.dialog_alert_title); - final PackageManager pm = getPackageManager(); - builder.setMessage(getString(R.string.spellchecker_security_warning, - scp.getSpellCheckerInfo().getServiceInfo().applicationInfo.loadLabel(pm))); + builder.setMessage(getString(R.string.spellchecker_security_warning, pref.getTitle())); builder.setCancelable(true); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int which) { - changeCurrentSpellChecker(scp); + changeCurrentSpellChecker(sci); } }); builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @@ -129,15 +226,11 @@ public class SpellCheckersSettings extends SettingsPreferenceFragment mDialog.show(); } - private void changeCurrentSpellChecker(final SingleSpellCheckerPreference scp) { - mTsm.setCurrentSpellChecker(scp.getSpellCheckerInfo()); + private void changeCurrentSpellChecker(final SpellCheckerInfo sci) { + mTsm.setCurrentSpellChecker(sci); if (DBG) { Log.d(TAG, "Current spell check is " + mTsm.getCurrentSpellChecker().getId()); } - updateScreen(); - } - - private static boolean isSystemApp(final SpellCheckerInfo sci) { - return (sci.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + updatePreferenceScreen(); } }