1 /** 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 17 package com.android.inputmethod.latin; 18 19 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE; 20 21 import android.app.AlertDialog; 22 import android.app.Dialog; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.content.SharedPreferences; 27 import android.content.res.Resources; 28 import android.os.Bundle; 29 import android.os.Parcel; 30 import android.os.Parcelable; 31 import android.preference.DialogPreference; 32 import android.preference.Preference; 33 import android.preference.PreferenceFragment; 34 import android.preference.PreferenceGroup; 35 import android.util.Pair; 36 import android.view.Menu; 37 import android.view.MenuInflater; 38 import android.view.MenuItem; 39 import android.view.View; 40 import android.view.inputmethod.InputMethodInfo; 41 import android.view.inputmethod.InputMethodSubtype; 42 import android.widget.ArrayAdapter; 43 import android.widget.Spinner; 44 import android.widget.SpinnerAdapter; 45 import android.widget.Toast; 46 47 import com.android.inputmethod.compat.CompatUtils; 48 49 import java.util.ArrayList; 50 import java.util.TreeSet; 51 52 public class AdditionalSubtypeSettings extends PreferenceFragment { 53 private SharedPreferences mPrefs; 54 private SubtypeLocaleAdapter mSubtypeLocaleAdapter; 55 private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter; 56 57 private boolean mIsAddingNewSubtype; 58 private AlertDialog mSubtypeEnablerNotificationDialog; 59 private String mSubtypePreferenceKeyForSubtypeEnabler; 60 61 private static final int MENU_ADD_SUBTYPE = Menu.FIRST; 62 private static final String KEY_IS_ADDING_NEW_SUBTYPE = "is_adding_new_subtype"; 63 private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN = 64 "is_subtype_enabler_notification_dialog_open"; 65 private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler"; 66 static class SubtypeLocaleItem extends Pair<String, String> 67 implements Comparable<SubtypeLocaleItem> { SubtypeLocaleItem(String localeString, String displayName)68 public SubtypeLocaleItem(String localeString, String displayName) { 69 super(localeString, displayName); 70 } 71 SubtypeLocaleItem(String localeString)72 public SubtypeLocaleItem(String localeString) { 73 this(localeString, SubtypeLocale.getSubtypeLocaleDisplayName(localeString)); 74 } 75 76 @Override toString()77 public String toString() { 78 return second; 79 } 80 81 @Override compareTo(SubtypeLocaleItem o)82 public int compareTo(SubtypeLocaleItem o) { 83 return first.compareTo(o.first); 84 } 85 } 86 87 static class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> { SubtypeLocaleAdapter(Context context)88 public SubtypeLocaleAdapter(Context context) { 89 super(context, android.R.layout.simple_spinner_item); 90 setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 91 92 final TreeSet<SubtypeLocaleItem> items = new TreeSet<SubtypeLocaleItem>(); 93 final InputMethodInfo imi = ImfUtils.getInputMethodInfoOfThisIme(context); 94 final int count = imi.getSubtypeCount(); 95 for (int i = 0; i < count; i++) { 96 final InputMethodSubtype subtype = imi.getSubtypeAt(i); 97 if (subtype.containsExtraValueKey(ASCII_CAPABLE)) { 98 items.add(createItem(context, subtype.getLocale())); 99 } 100 } 101 // TODO: Should filter out already existing combinations of locale and layout. 102 addAll(items); 103 } 104 createItem(Context context, String localeString)105 public static SubtypeLocaleItem createItem(Context context, String localeString) { 106 if (localeString.equals(SubtypeLocale.NO_LANGUAGE)) { 107 final String displayName = context.getString(R.string.subtype_no_language); 108 return new SubtypeLocaleItem(localeString, displayName); 109 } else { 110 return new SubtypeLocaleItem(localeString); 111 } 112 } 113 } 114 115 static class KeyboardLayoutSetItem extends Pair<String, String> { KeyboardLayoutSetItem(InputMethodSubtype subtype)116 public KeyboardLayoutSetItem(InputMethodSubtype subtype) { 117 super(SubtypeLocale.getKeyboardLayoutSetName(subtype), 118 SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype)); 119 } 120 121 @Override toString()122 public String toString() { 123 return second; 124 } 125 } 126 127 static class KeyboardLayoutSetAdapter extends ArrayAdapter<KeyboardLayoutSetItem> { KeyboardLayoutSetAdapter(Context context)128 public KeyboardLayoutSetAdapter(Context context) { 129 super(context, android.R.layout.simple_spinner_item); 130 setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 131 132 // TODO: Should filter out already existing combinations of locale and layout. 133 for (final String layout : SubtypeLocale.getPredefinedKeyboardLayoutSet()) { 134 // This is a dummy subtype with NO_LANGUAGE, only for display. 135 final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype( 136 SubtypeLocale.NO_LANGUAGE, layout, null); 137 add(new KeyboardLayoutSetItem(subtype)); 138 } 139 } 140 } 141 142 private interface SubtypeDialogProxy { onRemovePressed(SubtypePreference subtypePref)143 public void onRemovePressed(SubtypePreference subtypePref); onSavePressed(SubtypePreference subtypePref)144 public void onSavePressed(SubtypePreference subtypePref); onAddPressed(SubtypePreference subtypePref)145 public void onAddPressed(SubtypePreference subtypePref); getSubtypeLocaleAdapter()146 public SubtypeLocaleAdapter getSubtypeLocaleAdapter(); getKeyboardLayoutSetAdapter()147 public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter(); 148 } 149 150 static class SubtypePreference extends DialogPreference 151 implements DialogInterface.OnCancelListener { 152 private static final String KEY_PREFIX = "subtype_pref_"; 153 private static final String KEY_NEW_SUBTYPE = KEY_PREFIX + "new"; 154 155 private InputMethodSubtype mSubtype; 156 private InputMethodSubtype mPreviousSubtype; 157 158 private final SubtypeDialogProxy mProxy; 159 private Spinner mSubtypeLocaleSpinner; 160 private Spinner mKeyboardLayoutSetSpinner; 161 newIncompleteSubtypePreference( Context context, SubtypeDialogProxy proxy)162 public static SubtypePreference newIncompleteSubtypePreference( 163 Context context, SubtypeDialogProxy proxy) { 164 return new SubtypePreference(context, null, proxy); 165 } 166 SubtypePreference(Context context, InputMethodSubtype subtype, SubtypeDialogProxy proxy)167 public SubtypePreference(Context context, InputMethodSubtype subtype, 168 SubtypeDialogProxy proxy) { 169 super(context, null); 170 setDialogLayoutResource(R.layout.additional_subtype_dialog); 171 setPersistent(false); 172 mProxy = proxy; 173 setSubtype(subtype); 174 } 175 show()176 public void show() { 177 showDialog(null); 178 } 179 isIncomplete()180 public final boolean isIncomplete() { 181 return mSubtype == null; 182 } 183 getSubtype()184 public InputMethodSubtype getSubtype() { 185 return mSubtype; 186 } 187 setSubtype(InputMethodSubtype subtype)188 public void setSubtype(InputMethodSubtype subtype) { 189 mPreviousSubtype = mSubtype; 190 mSubtype = subtype; 191 if (isIncomplete()) { 192 setTitle(null); 193 setDialogTitle(R.string.add_style); 194 setKey(KEY_NEW_SUBTYPE); 195 } else { 196 final String displayName = SubtypeLocale.getSubtypeDisplayName( 197 subtype, getContext().getResources()); 198 setTitle(displayName); 199 setDialogTitle(displayName); 200 setKey(KEY_PREFIX + subtype.getLocale() + "_" 201 + SubtypeLocale.getKeyboardLayoutSetName(subtype)); 202 } 203 } 204 revert()205 public void revert() { 206 setSubtype(mPreviousSubtype); 207 } 208 hasBeenModified()209 public boolean hasBeenModified() { 210 return mSubtype != null && !mSubtype.equals(mPreviousSubtype); 211 } 212 213 @Override onCreateDialogView()214 protected View onCreateDialogView() { 215 final View v = super.onCreateDialogView(); 216 mSubtypeLocaleSpinner = (Spinner) v.findViewById(R.id.subtype_locale_spinner); 217 mSubtypeLocaleSpinner.setAdapter(mProxy.getSubtypeLocaleAdapter()); 218 mKeyboardLayoutSetSpinner = (Spinner) v.findViewById(R.id.keyboard_layout_set_spinner); 219 mKeyboardLayoutSetSpinner.setAdapter(mProxy.getKeyboardLayoutSetAdapter()); 220 return v; 221 } 222 223 @Override onPrepareDialogBuilder(AlertDialog.Builder builder)224 protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { 225 final Context context = builder.getContext(); 226 builder.setCancelable(true).setOnCancelListener(this); 227 if (isIncomplete()) { 228 builder.setPositiveButton(R.string.add, this) 229 .setNegativeButton(android.R.string.cancel, this); 230 } else { 231 builder.setPositiveButton(R.string.save, this) 232 .setNeutralButton(android.R.string.cancel, this) 233 .setNegativeButton(R.string.remove, this); 234 final SubtypeLocaleItem localeItem = SubtypeLocaleAdapter.createItem( 235 context, mSubtype.getLocale()); 236 final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(mSubtype); 237 setSpinnerPosition(mSubtypeLocaleSpinner, localeItem); 238 setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem); 239 } 240 } 241 setSpinnerPosition(Spinner spinner, Object itemToSelect)242 private static void setSpinnerPosition(Spinner spinner, Object itemToSelect) { 243 final SpinnerAdapter adapter = spinner.getAdapter(); 244 final int count = adapter.getCount(); 245 for (int i = 0; i < count; i++) { 246 final Object item = spinner.getItemAtPosition(i); 247 if (item.equals(itemToSelect)) { 248 spinner.setSelection(i); 249 return; 250 } 251 } 252 } 253 254 @Override onCancel(DialogInterface dialog)255 public void onCancel(DialogInterface dialog) { 256 if (isIncomplete()) { 257 mProxy.onRemovePressed(this); 258 } 259 } 260 261 @Override onClick(DialogInterface dialog, int which)262 public void onClick(DialogInterface dialog, int which) { 263 super.onClick(dialog, which); 264 switch (which) { 265 case DialogInterface.BUTTON_POSITIVE: 266 final boolean isEditing = !isIncomplete(); 267 final SubtypeLocaleItem locale = 268 (SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem(); 269 final KeyboardLayoutSetItem layout = 270 (KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem(); 271 final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype( 272 locale.first, layout.first, ASCII_CAPABLE); 273 setSubtype(subtype); 274 notifyChanged(); 275 if (isEditing) { 276 mProxy.onSavePressed(this); 277 } else { 278 mProxy.onAddPressed(this); 279 } 280 break; 281 case DialogInterface.BUTTON_NEUTRAL: 282 // Nothing to do 283 break; 284 case DialogInterface.BUTTON_NEGATIVE: 285 mProxy.onRemovePressed(this); 286 break; 287 } 288 } 289 getSpinnerPosition(Spinner spinner)290 private static int getSpinnerPosition(Spinner spinner) { 291 if (spinner == null) return -1; 292 return spinner.getSelectedItemPosition(); 293 } 294 setSpinnerPosition(Spinner spinner, int position)295 private static void setSpinnerPosition(Spinner spinner, int position) { 296 if (spinner == null || position < 0) return; 297 spinner.setSelection(position); 298 } 299 300 @Override onSaveInstanceState()301 protected Parcelable onSaveInstanceState() { 302 final Parcelable superState = super.onSaveInstanceState(); 303 final Dialog dialog = getDialog(); 304 if (dialog == null || !dialog.isShowing()) { 305 return superState; 306 } 307 308 final SavedState myState = new SavedState(superState); 309 myState.mSubtype = mSubtype; 310 myState.mSubtypeLocaleSelectedPos = getSpinnerPosition(mSubtypeLocaleSpinner); 311 myState.mKeyboardLayoutSetSelectedPos = getSpinnerPosition(mKeyboardLayoutSetSpinner); 312 return myState; 313 } 314 315 @Override onRestoreInstanceState(Parcelable state)316 protected void onRestoreInstanceState(Parcelable state) { 317 if (!(state instanceof SavedState)) { 318 super.onRestoreInstanceState(state); 319 return; 320 } 321 322 final SavedState myState = (SavedState) state; 323 super.onRestoreInstanceState(myState.getSuperState()); 324 setSpinnerPosition(mSubtypeLocaleSpinner, myState.mSubtypeLocaleSelectedPos); 325 setSpinnerPosition(mKeyboardLayoutSetSpinner, myState.mKeyboardLayoutSetSelectedPos); 326 setSubtype(myState.mSubtype); 327 } 328 329 static class SavedState extends Preference.BaseSavedState { 330 InputMethodSubtype mSubtype; 331 int mSubtypeLocaleSelectedPos; 332 int mKeyboardLayoutSetSelectedPos; 333 SavedState(Parcelable superState)334 public SavedState(Parcelable superState) { 335 super(superState); 336 } 337 338 @Override writeToParcel(Parcel dest, int flags)339 public void writeToParcel(Parcel dest, int flags) { 340 super.writeToParcel(dest, flags); 341 dest.writeInt(mSubtypeLocaleSelectedPos); 342 dest.writeInt(mKeyboardLayoutSetSelectedPos); 343 dest.writeParcelable(mSubtype, 0); 344 } 345 SavedState(Parcel source)346 public SavedState(Parcel source) { 347 super(source); 348 mSubtypeLocaleSelectedPos = source.readInt(); 349 mKeyboardLayoutSetSelectedPos = source.readInt(); 350 mSubtype = (InputMethodSubtype)source.readParcelable(null); 351 } 352 353 @SuppressWarnings("hiding") 354 public static final Parcelable.Creator<SavedState> CREATOR = 355 new Parcelable.Creator<SavedState>() { 356 @Override 357 public SavedState createFromParcel(Parcel source) { 358 return new SavedState(source); 359 } 360 361 @Override 362 public SavedState[] newArray(int size) { 363 return new SavedState[size]; 364 } 365 }; 366 } 367 } 368 AdditionalSubtypeSettings()369 public AdditionalSubtypeSettings() { 370 // Empty constructor for fragment generation. 371 } 372 373 @Override onCreate(Bundle savedInstanceState)374 public void onCreate(Bundle savedInstanceState) { 375 super.onCreate(savedInstanceState); 376 377 addPreferencesFromResource(R.xml.additional_subtype_settings); 378 setHasOptionsMenu(true); 379 380 mPrefs = getPreferenceManager().getSharedPreferences(); 381 } 382 383 @Override onActivityCreated(Bundle savedInstanceState)384 public void onActivityCreated(Bundle savedInstanceState) { 385 final Context context = getActivity(); 386 mSubtypeLocaleAdapter = new SubtypeLocaleAdapter(context); 387 mKeyboardLayoutSetAdapter = new KeyboardLayoutSetAdapter(context); 388 389 final String prefSubtypes = 390 SettingsValues.getPrefAdditionalSubtypes(mPrefs, getResources()); 391 setPrefSubtypes(prefSubtypes, context); 392 393 mIsAddingNewSubtype = (savedInstanceState != null) 394 && savedInstanceState.containsKey(KEY_IS_ADDING_NEW_SUBTYPE); 395 if (mIsAddingNewSubtype) { 396 getPreferenceScreen().addPreference( 397 SubtypePreference.newIncompleteSubtypePreference(context, mSubtypeProxy)); 398 } 399 400 super.onActivityCreated(savedInstanceState); 401 402 if (savedInstanceState != null && savedInstanceState.containsKey( 403 KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN)) { 404 mSubtypePreferenceKeyForSubtypeEnabler = savedInstanceState.getString( 405 KEY_SUBTYPE_FOR_SUBTYPE_ENABLER); 406 final SubtypePreference subtypePref = (SubtypePreference)findPreference( 407 mSubtypePreferenceKeyForSubtypeEnabler); 408 mSubtypeEnablerNotificationDialog = createDialog(subtypePref); 409 mSubtypeEnablerNotificationDialog.show(); 410 } 411 } 412 413 @Override onSaveInstanceState(Bundle outState)414 public void onSaveInstanceState(Bundle outState) { 415 super.onSaveInstanceState(outState); 416 if (mIsAddingNewSubtype) { 417 outState.putBoolean(KEY_IS_ADDING_NEW_SUBTYPE, true); 418 } 419 if (mSubtypeEnablerNotificationDialog != null 420 && mSubtypeEnablerNotificationDialog.isShowing()) { 421 outState.putBoolean(KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN, true); 422 outState.putString( 423 KEY_SUBTYPE_FOR_SUBTYPE_ENABLER, mSubtypePreferenceKeyForSubtypeEnabler); 424 } 425 } 426 427 private final SubtypeDialogProxy mSubtypeProxy = new SubtypeDialogProxy() { 428 @Override 429 public void onRemovePressed(SubtypePreference subtypePref) { 430 mIsAddingNewSubtype = false; 431 final PreferenceGroup group = getPreferenceScreen(); 432 group.removePreference(subtypePref); 433 ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); 434 } 435 436 @Override 437 public void onSavePressed(SubtypePreference subtypePref) { 438 final InputMethodSubtype subtype = subtypePref.getSubtype(); 439 if (!subtypePref.hasBeenModified()) { 440 return; 441 } 442 if (findDuplicatedSubtype(subtype) == null) { 443 ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); 444 return; 445 } 446 447 // Saved subtype is duplicated. 448 final PreferenceGroup group = getPreferenceScreen(); 449 group.removePreference(subtypePref); 450 subtypePref.revert(); 451 group.addPreference(subtypePref); 452 showSubtypeAlreadyExistsToast(subtype); 453 } 454 455 @Override 456 public void onAddPressed(SubtypePreference subtypePref) { 457 mIsAddingNewSubtype = false; 458 final InputMethodSubtype subtype = subtypePref.getSubtype(); 459 if (findDuplicatedSubtype(subtype) == null) { 460 ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); 461 mSubtypePreferenceKeyForSubtypeEnabler = subtypePref.getKey(); 462 mSubtypeEnablerNotificationDialog = createDialog(subtypePref); 463 mSubtypeEnablerNotificationDialog.show(); 464 return; 465 } 466 467 // Newly added subtype is duplicated. 468 final PreferenceGroup group = getPreferenceScreen(); 469 group.removePreference(subtypePref); 470 showSubtypeAlreadyExistsToast(subtype); 471 } 472 473 @Override 474 public SubtypeLocaleAdapter getSubtypeLocaleAdapter() { 475 return mSubtypeLocaleAdapter; 476 } 477 478 @Override 479 public KeyboardLayoutSetAdapter getKeyboardLayoutSetAdapter() { 480 return mKeyboardLayoutSetAdapter; 481 } 482 }; 483 showSubtypeAlreadyExistsToast(InputMethodSubtype subtype)484 private void showSubtypeAlreadyExistsToast(InputMethodSubtype subtype) { 485 final Context context = getActivity(); 486 final Resources res = context.getResources(); 487 final String message = res.getString(R.string.custom_input_style_already_exists, 488 SubtypeLocale.getSubtypeDisplayName(subtype, res)); 489 Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 490 } 491 findDuplicatedSubtype(InputMethodSubtype subtype)492 private InputMethodSubtype findDuplicatedSubtype(InputMethodSubtype subtype) { 493 final String localeString = subtype.getLocale(); 494 final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype); 495 return ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet( 496 getActivity(), localeString, keyboardLayoutSetName); 497 } 498 createDialog(SubtypePreference subtypePref)499 private AlertDialog createDialog(SubtypePreference subtypePref) { 500 final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 501 builder.setTitle(R.string.custom_input_styles_title) 502 .setMessage(R.string.custom_input_style_note_message) 503 .setNegativeButton(R.string.not_now, null) 504 .setPositiveButton(R.string.enable, new DialogInterface.OnClickListener() { 505 @Override 506 public void onClick(DialogInterface dialog, int which) { 507 final Intent intent = CompatUtils.getInputLanguageSelectionIntent( 508 ImfUtils.getInputMethodIdOfThisIme(getActivity()), 509 Intent.FLAG_ACTIVITY_NEW_TASK 510 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 511 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 512 // TODO: Add newly adding subtype to extra value of the intent as a hint 513 // for the input language selection activity. 514 // intent.putExtra("newlyAddedSubtype", subtypePref.getSubtype()); 515 startActivity(intent); 516 } 517 }); 518 519 return builder.create(); 520 } 521 setPrefSubtypes(String prefSubtypes, Context context)522 private void setPrefSubtypes(String prefSubtypes, Context context) { 523 final PreferenceGroup group = getPreferenceScreen(); 524 group.removeAll(); 525 final InputMethodSubtype[] subtypesArray = 526 AdditionalSubtype.createAdditionalSubtypesArray(prefSubtypes); 527 for (final InputMethodSubtype subtype : subtypesArray) { 528 final SubtypePreference pref = new SubtypePreference( 529 context, subtype, mSubtypeProxy); 530 group.addPreference(pref); 531 } 532 } 533 getSubtypes()534 private InputMethodSubtype[] getSubtypes() { 535 final PreferenceGroup group = getPreferenceScreen(); 536 final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); 537 final int count = group.getPreferenceCount(); 538 for (int i = 0; i < count; i++) { 539 final Preference pref = group.getPreference(i); 540 if (pref instanceof SubtypePreference) { 541 final SubtypePreference subtypePref = (SubtypePreference)pref; 542 // We should not save newly adding subtype to preference because it is incomplete. 543 if (subtypePref.isIncomplete()) continue; 544 subtypes.add(subtypePref.getSubtype()); 545 } 546 } 547 return subtypes.toArray(new InputMethodSubtype[subtypes.size()]); 548 } 549 getPrefSubtypes(InputMethodSubtype[] subtypes)550 private String getPrefSubtypes(InputMethodSubtype[] subtypes) { 551 final StringBuilder sb = new StringBuilder(); 552 for (final InputMethodSubtype subtype : subtypes) { 553 if (sb.length() > 0) { 554 sb.append(AdditionalSubtype.PREF_SUBTYPE_SEPARATOR); 555 } 556 sb.append(AdditionalSubtype.getPrefSubtype(subtype)); 557 } 558 return sb.toString(); 559 } 560 561 @Override onPause()562 public void onPause() { 563 super.onPause(); 564 final String oldSubtypes = SettingsValues.getPrefAdditionalSubtypes(mPrefs, getResources()); 565 final InputMethodSubtype[] subtypes = getSubtypes(); 566 final String prefSubtypes = getPrefSubtypes(subtypes); 567 if (prefSubtypes.equals(oldSubtypes)) { 568 return; 569 } 570 571 final SharedPreferences.Editor editor = mPrefs.edit(); 572 try { 573 editor.putString(Settings.PREF_CUSTOM_INPUT_STYLES, prefSubtypes); 574 } finally { 575 editor.apply(); 576 } 577 ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), subtypes); 578 } 579 580 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)581 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 582 final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style); 583 addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 584 } 585 586 @Override onOptionsItemSelected(MenuItem item)587 public boolean onOptionsItemSelected(MenuItem item) { 588 final int itemId = item.getItemId(); 589 if (itemId == MENU_ADD_SUBTYPE) { 590 final SubtypePreference newSubtype = 591 SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy); 592 getPreferenceScreen().addPreference(newSubtype); 593 newSubtype.show(); 594 mIsAddingNewSubtype = true; 595 return true; 596 } 597 return super.onOptionsItemSelected(item); 598 } 599 } 600