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