Skip to content

Commit a6c673b

Browse files
author
Gilles Debunne
committed
Bug 5278473 & 5278471: delete option in suggestion popup menu
Also added + and x icons on that line. Change-Id: I508ae48f83eb7a831f24bb4f81933d9e698abde6
1 parent 4c08848 commit a6c673b

File tree

8 files changed

+114
-78
lines changed

8 files changed

+114
-78
lines changed

core/java/android/widget/TextView.java

Lines changed: 113 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -9596,6 +9596,8 @@ public boolean isShowing() {
95969596

95979597
private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
95989598
private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
9599+
private static final int ADD_TO_DICTIONARY = -1;
9600+
private static final int DELETE_TEXT = -2;
95999601
private SuggestionInfo[] mSuggestionInfos;
96009602
private int mNumberOfSuggestions;
96019603
private boolean mCursorWasVisibleBeforeSuggestions;
@@ -9647,9 +9649,9 @@ protected void initContentView() {
96479649
listView.setOnItemClickListener(this);
96489650
mContentView = listView;
96499651

9650-
// Inflate the suggestion items once and for all. +1 for add to dictionary
9651-
mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS + 1];
9652-
for (int i = 0; i < MAX_NUMBER_SUGGESTIONS + 1; i++) {
9652+
// Inflate the suggestion items once and for all. + 2 for add to dictionary and delete
9653+
mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS + 2];
9654+
for (int i = 0; i < mSuggestionInfos.length; i++) {
96539655
mSuggestionInfos[i] = new SuggestionInfo();
96549656
}
96559657
}
@@ -9700,7 +9702,19 @@ public View getView(int position, View convertView, ViewGroup parent) {
97009702
false);
97019703
}
97029704

9703-
textView.setText(mSuggestionInfos[position].text);
9705+
final SuggestionInfo suggestionInfo = mSuggestionInfos[position];
9706+
textView.setText(suggestionInfo.text);
9707+
9708+
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
9709+
textView.setCompoundDrawablesWithIntrinsicBounds(
9710+
com.android.internal.R.drawable.ic_suggestions_add, 0, 0, 0);
9711+
} else if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
9712+
textView.setCompoundDrawablesWithIntrinsicBounds(
9713+
com.android.internal.R.drawable.ic_suggestions_delete, 0, 0, 0);
9714+
} else {
9715+
textView.setCompoundDrawables(null, null, null, null);
9716+
}
9717+
97049718
return textView;
97059719
}
97069720
}
@@ -9751,11 +9765,10 @@ private SuggestionSpan[] getSuggestionSpans() {
97519765
public void show() {
97529766
if (!(mText instanceof Editable)) return;
97539767

9754-
if (updateSuggestions()) {
9755-
mCursorWasVisibleBeforeSuggestions = mCursorVisible;
9756-
setCursorVisible(false);
9757-
super.show();
9758-
}
9768+
updateSuggestions();
9769+
mCursorWasVisibleBeforeSuggestions = mCursorVisible;
9770+
setCursorVisible(false);
9771+
super.show();
97599772
}
97609773

97619774
@Override
@@ -9810,7 +9823,7 @@ public void hide() {
98109823
super.hide();
98119824
}
98129825

9813-
private boolean updateSuggestions() {
9826+
private void updateSuggestions() {
98149827
Spannable spannable = (Spannable) TextView.this.mText;
98159828
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
98169829

@@ -9859,21 +9872,28 @@ private boolean updateSuggestions() {
98599872
highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
98609873
}
98619874

9875+
// Add to dictionary item is there a span with the misspelled flag
98629876
if (misspelledSpan != null) {
98639877
final int misspelledStart = spannable.getSpanStart(misspelledSpan);
98649878
final int misspelledEnd = spannable.getSpanEnd(misspelledSpan);
98659879
if (misspelledStart >= 0 && misspelledEnd > misspelledStart) {
98669880
SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
98679881
suggestionInfo.suggestionSpan = misspelledSpan;
9868-
suggestionInfo.suggestionIndex = -1;
9882+
suggestionInfo.suggestionIndex = ADD_TO_DICTIONARY;
98699883
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
98709884
getContext().getString(com.android.internal.R.string.addToDictionary));
98719885

98729886
mNumberOfSuggestions++;
98739887
}
98749888
}
98759889

9876-
if (mNumberOfSuggestions == 0) return false;
9890+
// Delete item
9891+
SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
9892+
suggestionInfo.suggestionSpan = null;
9893+
suggestionInfo.suggestionIndex = DELETE_TEXT;
9894+
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
9895+
getContext().getString(com.android.internal.R.string.deleteText));
9896+
mNumberOfSuggestions++;
98779897

98789898
if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
98799899
if (underlineColor == 0) {
@@ -9889,8 +9909,6 @@ private boolean updateSuggestions() {
98899909
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
98909910

98919911
mSuggestionsAdapter.notifyDataSetChanged();
9892-
9893-
return true;
98949912
}
98959913

98969914
private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
@@ -9915,77 +9933,94 @@ private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionSt
99159933

99169934
@Override
99179935
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
9918-
hide();
9919-
9920-
if (view instanceof TextView) {
9921-
TextView textView = (TextView) view;
9922-
Editable editable = (Editable) mText;
9923-
9924-
SuggestionInfo suggestionInfo = mSuggestionInfos[position];
9925-
final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
9926-
final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
9927-
if (spanStart < 0 || spanEnd < 0) return; // Span has been removed
9928-
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
9929-
9930-
if (suggestionInfo.suggestionIndex < 0) {
9931-
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
9932-
intent.putExtra("word", originalText);
9933-
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
9934-
getContext().startActivity(intent);
9935-
suggestionInfo.removeMisspelledFlag();
9936-
} else {
9937-
// SuggestionSpans are removed by replace: save them before
9938-
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
9939-
SuggestionSpan.class);
9940-
final int length = suggestionSpans.length;
9941-
int[] suggestionSpansStarts = new int[length];
9942-
int[] suggestionSpansEnds = new int[length];
9943-
int[] suggestionSpansFlags = new int[length];
9944-
for (int i = 0; i < length; i++) {
9945-
final SuggestionSpan suggestionSpan = suggestionSpans[i];
9946-
suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
9947-
suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
9948-
suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
9949-
}
9936+
TextView textView = (TextView) view;
9937+
Editable editable = (Editable) mText;
99509938

9951-
final int suggestionStart = suggestionInfo.suggestionStart;
9952-
final int suggestionEnd = suggestionInfo.suggestionEnd;
9953-
final String suggestion = textView.getText().subSequence(
9954-
suggestionStart, suggestionEnd).toString();
9955-
editable.replace(spanStart, spanEnd, suggestion);
9939+
SuggestionInfo suggestionInfo = mSuggestionInfos[position];
99569940

9957-
suggestionInfo.removeMisspelledFlag();
9941+
if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
9942+
final int spanUnionStart = editable.getSpanStart(mSuggestionRangeSpan);
9943+
int spanUnionEnd = editable.getSpanEnd(mSuggestionRangeSpan);
9944+
// Do not leave two adjacent spaces after deletion, or one at beginning of text
9945+
if (spanUnionEnd < editable.length() &&
9946+
Character.isSpaceChar(editable.charAt(spanUnionEnd)) &&
9947+
(spanUnionStart == 0 ||
9948+
Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
9949+
spanUnionEnd = spanUnionEnd + 1;
9950+
}
9951+
editable.replace(spanUnionStart, spanUnionEnd, "");
9952+
hide();
9953+
return;
9954+
}
99589955

9959-
// Notify source IME of the suggestion pick. Do this before swaping texts.
9960-
if (!TextUtils.isEmpty(
9961-
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
9962-
InputMethodManager imm = InputMethodManager.peekInstance();
9963-
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
9964-
suggestionInfo.suggestionIndex);
9965-
}
9956+
final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
9957+
final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
9958+
if (spanStart < 0 || spanEnd < 0) {
9959+
// Span has been removed
9960+
hide();
9961+
return;
9962+
}
9963+
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
99669964

9967-
// Swap text content between actual text and Suggestion span
9968-
String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
9969-
suggestions[suggestionInfo.suggestionIndex] = originalText;
9970-
9971-
// Restore previous SuggestionSpans
9972-
final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
9973-
for (int i = 0; i < length; i++) {
9974-
// Only spans that include the modified region make sense after replacement
9975-
// Spans partially included in the replaced region are removed, there is no
9976-
// way to assign them a valid range after replacement
9977-
if (suggestionSpansStarts[i] <= spanStart &&
9978-
suggestionSpansEnds[i] >= spanEnd) {
9979-
editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
9980-
suggestionSpansEnds[i] + lengthDifference,
9981-
suggestionSpansFlags[i]);
9982-
}
9965+
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
9966+
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
9967+
intent.putExtra("word", originalText);
9968+
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
9969+
getContext().startActivity(intent);
9970+
suggestionInfo.removeMisspelledFlag();
9971+
} else {
9972+
// SuggestionSpans are removed by replace: save them before
9973+
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
9974+
SuggestionSpan.class);
9975+
final int length = suggestionSpans.length;
9976+
int[] suggestionSpansStarts = new int[length];
9977+
int[] suggestionSpansEnds = new int[length];
9978+
int[] suggestionSpansFlags = new int[length];
9979+
for (int i = 0; i < length; i++) {
9980+
final SuggestionSpan suggestionSpan = suggestionSpans[i];
9981+
suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
9982+
suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
9983+
suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
9984+
}
9985+
9986+
final int suggestionStart = suggestionInfo.suggestionStart;
9987+
final int suggestionEnd = suggestionInfo.suggestionEnd;
9988+
final String suggestion = textView.getText().subSequence(
9989+
suggestionStart, suggestionEnd).toString();
9990+
editable.replace(spanStart, spanEnd, suggestion);
9991+
9992+
suggestionInfo.removeMisspelledFlag();
9993+
9994+
// Notify source IME of the suggestion pick. Do this before swaping texts.
9995+
if (!TextUtils.isEmpty(
9996+
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
9997+
InputMethodManager imm = InputMethodManager.peekInstance();
9998+
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
9999+
suggestionInfo.suggestionIndex);
10000+
}
10001+
10002+
// Swap text content between actual text and Suggestion span
10003+
String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
10004+
suggestions[suggestionInfo.suggestionIndex] = originalText;
10005+
10006+
// Restore previous SuggestionSpans
10007+
final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
10008+
for (int i = 0; i < length; i++) {
10009+
// Only spans that include the modified region make sense after replacement
10010+
// Spans partially included in the replaced region are removed, there is no
10011+
// way to assign them a valid range after replacement
10012+
if (suggestionSpansStarts[i] <= spanStart &&
10013+
suggestionSpansEnds[i] >= spanEnd) {
10014+
editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
10015+
suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
998310016
}
9984-
9985-
// Move cursor at the end of the replacement word
9986-
Selection.setSelection(editable, spanEnd + lengthDifference);
998710017
}
10018+
10019+
// Move cursor at the end of the replacement word
10020+
Selection.setSelection(editable, spanEnd + lengthDifference);
998810021
}
10022+
10023+
hide();
998910024
}
999010025
}
999110026

381 Bytes
Loading
478 Bytes
Loading
353 Bytes
Loading
401 Bytes
Loading
401 Bytes
Loading
627 Bytes
Loading

core/res/res/layout/text_edit_suggestion_item.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
android:paddingBottom="8dip"
2424
android:layout_gravity="left|center_vertical"
2525
android:singleLine="true"
26+
android:drawablePadding="8dip"
2627
android:ellipsize="marquee"
2728
android:textAppearance="?android:attr/textAppearanceMedium"
2829
android:textColor="@android:color/dim_foreground_light" />

0 commit comments

Comments
 (0)