Home | History | Annotate | Download | only in inputmethod
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.inputmethod;
     18 
     19 import android.app.AlertDialog;
     20 import android.content.Context;
     21 import android.content.DialogInterface;
     22 import android.content.pm.ApplicationInfo;
     23 import android.os.Bundle;
     24 import android.preference.Preference;
     25 import android.preference.Preference.OnPreferenceClickListener;
     26 import android.preference.PreferenceScreen;
     27 import android.util.Log;
     28 import android.view.textservice.SpellCheckerInfo;
     29 import android.view.textservice.SpellCheckerSubtype;
     30 import android.view.textservice.TextServicesManager;
     31 import android.widget.Switch;
     32 
     33 import com.android.internal.logging.MetricsLogger;
     34 import com.android.settings.R;
     35 import com.android.settings.SettingsActivity;
     36 import com.android.settings.SettingsPreferenceFragment;
     37 import com.android.settings.inputmethod.SpellCheckerPreference.OnRadioButtonPreferenceListener;
     38 import com.android.settings.widget.SwitchBar;
     39 import com.android.settings.widget.SwitchBar.OnSwitchChangeListener;
     40 
     41 public class SpellCheckersSettings extends SettingsPreferenceFragment
     42         implements OnSwitchChangeListener, OnPreferenceClickListener,
     43         OnRadioButtonPreferenceListener {
     44     private static final String TAG = SpellCheckersSettings.class.getSimpleName();
     45     private static final boolean DBG = false;
     46 
     47     private static final String KEY_SPELL_CHECKER_LANGUAGE = "spellchecker_language";
     48     private static final int ITEM_ID_USE_SYSTEM_LANGUAGE = 0;
     49 
     50     private SwitchBar mSwitchBar;
     51     private Preference mSpellCheckerLanaguagePref;
     52     private AlertDialog mDialog = null;
     53     private SpellCheckerInfo mCurrentSci;
     54     private SpellCheckerInfo[] mEnabledScis;
     55     private TextServicesManager mTsm;
     56 
     57     @Override
     58     protected int getMetricsCategory() {
     59         return MetricsLogger.INPUTMETHOD_SPELL_CHECKERS;
     60     }
     61 
     62     @Override
     63     public void onCreate(final Bundle icicle) {
     64         super.onCreate(icicle);
     65 
     66         addPreferencesFromResource(R.xml.spellchecker_prefs);
     67         mSpellCheckerLanaguagePref = findPreference(KEY_SPELL_CHECKER_LANGUAGE);
     68         mSpellCheckerLanaguagePref.setOnPreferenceClickListener(this);
     69 
     70         mTsm = (TextServicesManager) getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
     71         mCurrentSci = mTsm.getCurrentSpellChecker();
     72         mEnabledScis = mTsm.getEnabledSpellCheckers();
     73         populatePreferenceScreen();
     74     }
     75 
     76     private void populatePreferenceScreen() {
     77         final PreferenceScreen screen = getPreferenceScreen();
     78         final Context context = getActivity();
     79         final int count = (mEnabledScis == null) ? 0 : mEnabledScis.length;
     80         for (int index = 0; index < count; ++index) {
     81             final SpellCheckerInfo sci = mEnabledScis[index];
     82             final SpellCheckerPreference pref = new SpellCheckerPreference(context, sci, this);
     83             screen.addPreference(pref);
     84             InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref);
     85         }
     86     }
     87 
     88     @Override
     89     public void onResume() {
     90         super.onResume();
     91         mSwitchBar = ((SettingsActivity)getActivity()).getSwitchBar();
     92         mSwitchBar.show();
     93         mSwitchBar.addOnSwitchChangeListener(this);
     94         updatePreferenceScreen();
     95     }
     96 
     97     @Override
     98     public void onPause() {
     99         super.onPause();
    100         mSwitchBar.removeOnSwitchChangeListener(this);
    101     }
    102 
    103     @Override
    104     public void onSwitchChanged(final Switch switchView, final boolean isChecked) {
    105         mTsm.setSpellCheckerEnabled(isChecked);
    106         updatePreferenceScreen();
    107     }
    108 
    109     private void updatePreferenceScreen() {
    110         mCurrentSci = mTsm.getCurrentSpellChecker();
    111         final boolean isSpellCheckerEnabled = mTsm.isSpellCheckerEnabled();
    112         mSwitchBar.setChecked(isSpellCheckerEnabled);
    113 
    114         final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(
    115                 false /* allowImplicitlySelectedSubtype */);
    116         mSpellCheckerLanaguagePref.setSummary(getSpellCheckerSubtypeLabel(mCurrentSci, currentScs));
    117 
    118         final PreferenceScreen screen = getPreferenceScreen();
    119         final int count = screen.getPreferenceCount();
    120         for (int index = 0; index < count; index++) {
    121             final Preference preference = screen.getPreference(index);
    122             preference.setEnabled(isSpellCheckerEnabled);
    123             if (preference instanceof SpellCheckerPreference) {
    124                 final SpellCheckerPreference pref = (SpellCheckerPreference)preference;
    125                 final SpellCheckerInfo sci = pref.getSpellCheckerInfo();
    126                 pref.setSelected(mCurrentSci != null && mCurrentSci.getId().equals(sci.getId()));
    127             }
    128         }
    129     }
    130 
    131     private CharSequence getSpellCheckerSubtypeLabel(final SpellCheckerInfo sci,
    132             final SpellCheckerSubtype subtype) {
    133         if (sci == null) {
    134             return null;
    135         }
    136         if (subtype == null) {
    137             return getString(R.string.use_system_language_to_select_input_method_subtypes);
    138         }
    139         return subtype.getDisplayName(
    140                 getActivity(), sci.getPackageName(), sci.getServiceInfo().applicationInfo);
    141     }
    142 
    143     @Override
    144     public boolean onPreferenceClick(final Preference pref) {
    145         if (pref == mSpellCheckerLanaguagePref) {
    146             showChooseLanguageDialog();
    147             return true;
    148         }
    149         return false;
    150     }
    151 
    152     @Override
    153     public void onRadioButtonClicked(final SpellCheckerPreference pref) {
    154         final SpellCheckerInfo sci = pref.getSpellCheckerInfo();
    155         final boolean isSystemApp =
    156                 (sci.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
    157         if (isSystemApp) {
    158             changeCurrentSpellChecker(sci);
    159         } else {
    160             showSecurityWarnDialog(pref);
    161         }
    162     }
    163 
    164     private static int convertSubtypeIndexToDialogItemId(final int index) { return index + 1; }
    165     private static int convertDialogItemIdToSubtypeIndex(final int item) { return item - 1; }
    166 
    167     private void showChooseLanguageDialog() {
    168         if (mDialog != null && mDialog.isShowing()) {
    169             mDialog.dismiss();
    170         }
    171         final SpellCheckerInfo currentSci = mTsm.getCurrentSpellChecker();
    172         final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(
    173                 false /* allowImplicitlySelectedSubtype */);
    174         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    175         builder.setTitle(R.string.phone_language);
    176         final int subtypeCount = currentSci.getSubtypeCount();
    177         final CharSequence[] items = new CharSequence[subtypeCount + 1 /* default */ ];
    178         items[ITEM_ID_USE_SYSTEM_LANGUAGE] = getSpellCheckerSubtypeLabel(currentSci, null);
    179         int checkedItemId = ITEM_ID_USE_SYSTEM_LANGUAGE;
    180         for (int index = 0; index < subtypeCount; ++index) {
    181             final SpellCheckerSubtype subtype = currentSci.getSubtypeAt(index);
    182             final int itemId = convertSubtypeIndexToDialogItemId(index);
    183             items[itemId] = getSpellCheckerSubtypeLabel(currentSci, subtype);
    184             if (subtype.equals(currentScs)) {
    185                 checkedItemId = itemId;
    186             }
    187         }
    188         builder.setSingleChoiceItems(items, checkedItemId, new AlertDialog.OnClickListener() {
    189             @Override
    190             public void onClick(final DialogInterface dialog, final int item) {
    191                 if (item == ITEM_ID_USE_SYSTEM_LANGUAGE) {
    192                     mTsm.setSpellCheckerSubtype(null);
    193                 } else {
    194                     final int index = convertDialogItemIdToSubtypeIndex(item);
    195                     mTsm.setSpellCheckerSubtype(currentSci.getSubtypeAt(index));
    196                 }
    197                 if (DBG) {
    198                     final SpellCheckerSubtype subtype = mTsm.getCurrentSpellCheckerSubtype(
    199                             true /* allowImplicitlySelectedSubtype */);
    200                     Log.d(TAG, "Current spell check locale is "
    201                             + subtype == null ? "null" : subtype.getLocale());
    202                 }
    203                 dialog.dismiss();
    204                 updatePreferenceScreen();
    205             }
    206         });
    207         mDialog = builder.create();
    208         mDialog.show();
    209     }
    210 
    211     private void showSecurityWarnDialog(final SpellCheckerPreference pref) {
    212         if (mDialog != null && mDialog.isShowing()) {
    213             mDialog.dismiss();
    214         }
    215         final SpellCheckerInfo sci = pref.getSpellCheckerInfo();
    216         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    217         builder.setTitle(android.R.string.dialog_alert_title);
    218         builder.setMessage(getString(R.string.spellchecker_security_warning, pref.getTitle()));
    219         builder.setCancelable(true);
    220         builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    221             @Override
    222             public void onClick(final DialogInterface dialog, final int which) {
    223                 changeCurrentSpellChecker(sci);
    224             }
    225         });
    226         builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
    227             @Override
    228             public void onClick(final DialogInterface dialog, final int which) {
    229             }
    230         });
    231         mDialog = builder.create();
    232         mDialog.show();
    233     }
    234 
    235     private void changeCurrentSpellChecker(final SpellCheckerInfo sci) {
    236         mTsm.setCurrentSpellChecker(sci);
    237         if (DBG) {
    238             Log.d(TAG, "Current spell check is " + mTsm.getCurrentSpellChecker().getId());
    239         }
    240         updatePreferenceScreen();
    241     }
    242 }
    243