Reorganize spell checkers settings

Bug: 15976603
Bug: 16115751
Change-Id: I3b23d7f01d8d39da27215a5263b12304ac64db0f
This commit is contained in:
Tadashi G. Takaoka
2014-07-10 15:37:28 +09:00
parent 1aa40913df
commit cd6fdead7c
12 changed files with 363 additions and 618 deletions

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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<SingleSpellCheckerPreference> 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();
}
}