Skip to content

Commit 404c8e5

Browse files
Gilles DebunneAndroid (Google) Code Review
authored andcommitted
Merge "Bug 5278473 & 5278471: delete option in suggestion popup menu"
2 parents f4314df + a6c673b commit 404c8e5

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
@@ -9613,6 +9613,8 @@ public boolean isShowing() {
96139613

96149614
private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
96159615
private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
9616+
private static final int ADD_TO_DICTIONARY = -1;
9617+
private static final int DELETE_TEXT = -2;
96169618
private SuggestionInfo[] mSuggestionInfos;
96179619
private int mNumberOfSuggestions;
96189620
private boolean mCursorWasVisibleBeforeSuggestions;
@@ -9664,9 +9666,9 @@ protected void initContentView() {
96649666
listView.setOnItemClickListener(this);
96659667
mContentView = listView;
96669668

9667-
// Inflate the suggestion items once and for all. +1 for add to dictionary
9668-
mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS + 1];
9669-
for (int i = 0; i < MAX_NUMBER_SUGGESTIONS + 1; i++) {
9669+
// Inflate the suggestion items once and for all. + 2 for add to dictionary and delete
9670+
mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS + 2];
9671+
for (int i = 0; i < mSuggestionInfos.length; i++) {
96709672
mSuggestionInfos[i] = new SuggestionInfo();
96719673
}
96729674
}
@@ -9717,7 +9719,19 @@ public View getView(int position, View convertView, ViewGroup parent) {
97179719
false);
97189720
}
97199721

9720-
textView.setText(mSuggestionInfos[position].text);
9722+
final SuggestionInfo suggestionInfo = mSuggestionInfos[position];
9723+
textView.setText(suggestionInfo.text);
9724+
9725+
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
9726+
textView.setCompoundDrawablesWithIntrinsicBounds(
9727+
com.android.internal.R.drawable.ic_suggestions_add, 0, 0, 0);
9728+
} else if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
9729+
textView.setCompoundDrawablesWithIntrinsicBounds(
9730+
com.android.internal.R.drawable.ic_suggestions_delete, 0, 0, 0);
9731+
} else {
9732+
textView.setCompoundDrawables(null, null, null, null);
9733+
}
9734+
97219735
return textView;
97229736
}
97239737
}
@@ -9768,11 +9782,10 @@ private SuggestionSpan[] getSuggestionSpans() {
97689782
public void show() {
97699783
if (!(mText instanceof Editable)) return;
97709784

9771-
if (updateSuggestions()) {
9772-
mCursorWasVisibleBeforeSuggestions = mCursorVisible;
9773-
setCursorVisible(false);
9774-
super.show();
9775-
}
9785+
updateSuggestions();
9786+
mCursorWasVisibleBeforeSuggestions = mCursorVisible;
9787+
setCursorVisible(false);
9788+
super.show();
97769789
}
97779790

97789791
@Override
@@ -9828,7 +9841,7 @@ public void hide() {
98289841
super.hide();
98299842
}
98309843

9831-
private boolean updateSuggestions() {
9844+
private void updateSuggestions() {
98329845
Spannable spannable = (Spannable) TextView.this.mText;
98339846
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
98349847

@@ -9877,21 +9890,28 @@ private boolean updateSuggestions() {
98779890
highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
98789891
}
98799892

9893+
// Add to dictionary item is there a span with the misspelled flag
98809894
if (misspelledSpan != null) {
98819895
final int misspelledStart = spannable.getSpanStart(misspelledSpan);
98829896
final int misspelledEnd = spannable.getSpanEnd(misspelledSpan);
98839897
if (misspelledStart >= 0 && misspelledEnd > misspelledStart) {
98849898
SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
98859899
suggestionInfo.suggestionSpan = misspelledSpan;
9886-
suggestionInfo.suggestionIndex = -1;
9900+
suggestionInfo.suggestionIndex = ADD_TO_DICTIONARY;
98879901
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
98889902
getContext().getString(com.android.internal.R.string.addToDictionary));
98899903

98909904
mNumberOfSuggestions++;
98919905
}
98929906
}
98939907

9894-
if (mNumberOfSuggestions == 0) return false;
9908+
// Delete item
9909+
SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
9910+
suggestionInfo.suggestionSpan = null;
9911+
suggestionInfo.suggestionIndex = DELETE_TEXT;
9912+
suggestionInfo.text.replace(0, suggestionInfo.text.length(),
9913+
getContext().getString(com.android.internal.R.string.deleteText));
9914+
mNumberOfSuggestions++;
98959915

98969916
if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
98979917
if (underlineColor == 0) {
@@ -9907,8 +9927,6 @@ private boolean updateSuggestions() {
99079927
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
99089928

99099929
mSuggestionsAdapter.notifyDataSetChanged();
9910-
9911-
return true;
99129930
}
99139931

99149932
private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
@@ -9933,77 +9951,94 @@ private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionSt
99339951

99349952
@Override
99359953
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
9936-
hide();
9937-
9938-
if (view instanceof TextView) {
9939-
TextView textView = (TextView) view;
9940-
Editable editable = (Editable) mText;
9941-
9942-
SuggestionInfo suggestionInfo = mSuggestionInfos[position];
9943-
final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
9944-
final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
9945-
if (spanStart < 0 || spanEnd < 0) return; // Span has been removed
9946-
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
9947-
9948-
if (suggestionInfo.suggestionIndex < 0) {
9949-
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
9950-
intent.putExtra("word", originalText);
9951-
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
9952-
getContext().startActivity(intent);
9953-
suggestionInfo.removeMisspelledFlag();
9954-
} else {
9955-
// SuggestionSpans are removed by replace: save them before
9956-
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
9957-
SuggestionSpan.class);
9958-
final int length = suggestionSpans.length;
9959-
int[] suggestionSpansStarts = new int[length];
9960-
int[] suggestionSpansEnds = new int[length];
9961-
int[] suggestionSpansFlags = new int[length];
9962-
for (int i = 0; i < length; i++) {
9963-
final SuggestionSpan suggestionSpan = suggestionSpans[i];
9964-
suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
9965-
suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
9966-
suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
9967-
}
9954+
TextView textView = (TextView) view;
9955+
Editable editable = (Editable) mText;
99689956

9969-
final int suggestionStart = suggestionInfo.suggestionStart;
9970-
final int suggestionEnd = suggestionInfo.suggestionEnd;
9971-
final String suggestion = textView.getText().subSequence(
9972-
suggestionStart, suggestionEnd).toString();
9973-
editable.replace(spanStart, spanEnd, suggestion);
9957+
SuggestionInfo suggestionInfo = mSuggestionInfos[position];
99749958

9975-
suggestionInfo.removeMisspelledFlag();
9959+
if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
9960+
final int spanUnionStart = editable.getSpanStart(mSuggestionRangeSpan);
9961+
int spanUnionEnd = editable.getSpanEnd(mSuggestionRangeSpan);
9962+
// Do not leave two adjacent spaces after deletion, or one at beginning of text
9963+
if (spanUnionEnd < editable.length() &&
9964+
Character.isSpaceChar(editable.charAt(spanUnionEnd)) &&
9965+
(spanUnionStart == 0 ||
9966+
Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
9967+
spanUnionEnd = spanUnionEnd + 1;
9968+
}
9969+
editable.replace(spanUnionStart, spanUnionEnd, "");
9970+
hide();
9971+
return;
9972+
}
99769973

9977-
// Notify source IME of the suggestion pick. Do this before swaping texts.
9978-
if (!TextUtils.isEmpty(
9979-
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
9980-
InputMethodManager imm = InputMethodManager.peekInstance();
9981-
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
9982-
suggestionInfo.suggestionIndex);
9983-
}
9974+
final int spanStart = editable.getSpanStart(suggestionInfo.suggestionSpan);
9975+
final int spanEnd = editable.getSpanEnd(suggestionInfo.suggestionSpan);
9976+
if (spanStart < 0 || spanEnd < 0) {
9977+
// Span has been removed
9978+
hide();
9979+
return;
9980+
}
9981+
final String originalText = mText.subSequence(spanStart, spanEnd).toString();
99849982

9985-
// Swap text content between actual text and Suggestion span
9986-
String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
9987-
suggestions[suggestionInfo.suggestionIndex] = originalText;
9988-
9989-
// Restore previous SuggestionSpans
9990-
final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
9991-
for (int i = 0; i < length; i++) {
9992-
// Only spans that include the modified region make sense after replacement
9993-
// Spans partially included in the replaced region are removed, there is no
9994-
// way to assign them a valid range after replacement
9995-
if (suggestionSpansStarts[i] <= spanStart &&
9996-
suggestionSpansEnds[i] >= spanEnd) {
9997-
editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
9998-
suggestionSpansEnds[i] + lengthDifference,
9999-
suggestionSpansFlags[i]);
10000-
}
9983+
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
9984+
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
9985+
intent.putExtra("word", originalText);
9986+
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
9987+
getContext().startActivity(intent);
9988+
suggestionInfo.removeMisspelledFlag();
9989+
} else {
9990+
// SuggestionSpans are removed by replace: save them before
9991+
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
9992+
SuggestionSpan.class);
9993+
final int length = suggestionSpans.length;
9994+
int[] suggestionSpansStarts = new int[length];
9995+
int[] suggestionSpansEnds = new int[length];
9996+
int[] suggestionSpansFlags = new int[length];
9997+
for (int i = 0; i < length; i++) {
9998+
final SuggestionSpan suggestionSpan = suggestionSpans[i];
9999+
suggestionSpansStarts[i] = editable.getSpanStart(suggestionSpan);
10000+
suggestionSpansEnds[i] = editable.getSpanEnd(suggestionSpan);
10001+
suggestionSpansFlags[i] = editable.getSpanFlags(suggestionSpan);
10002+
}
10003+
10004+
final int suggestionStart = suggestionInfo.suggestionStart;
10005+
final int suggestionEnd = suggestionInfo.suggestionEnd;
10006+
final String suggestion = textView.getText().subSequence(
10007+
suggestionStart, suggestionEnd).toString();
10008+
editable.replace(spanStart, spanEnd, suggestion);
10009+
10010+
suggestionInfo.removeMisspelledFlag();
10011+
10012+
// Notify source IME of the suggestion pick. Do this before swaping texts.
10013+
if (!TextUtils.isEmpty(
10014+
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
10015+
InputMethodManager imm = InputMethodManager.peekInstance();
10016+
imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
10017+
suggestionInfo.suggestionIndex);
10018+
}
10019+
10020+
// Swap text content between actual text and Suggestion span
10021+
String[] suggestions = suggestionInfo.suggestionSpan.getSuggestions();
10022+
suggestions[suggestionInfo.suggestionIndex] = originalText;
10023+
10024+
// Restore previous SuggestionSpans
10025+
final int lengthDifference = suggestion.length() - (spanEnd - spanStart);
10026+
for (int i = 0; i < length; i++) {
10027+
// Only spans that include the modified region make sense after replacement
10028+
// Spans partially included in the replaced region are removed, there is no
10029+
// way to assign them a valid range after replacement
10030+
if (suggestionSpansStarts[i] <= spanStart &&
10031+
suggestionSpansEnds[i] >= spanEnd) {
10032+
editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
10033+
suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
1000110034
}
10002-
10003-
// Move cursor at the end of the replacement word
10004-
Selection.setSelection(editable, spanEnd + lengthDifference);
1000510035
}
10036+
10037+
// Move cursor at the end of the replacement word
10038+
Selection.setSelection(editable, spanEnd + lengthDifference);
1000610039
}
10040+
10041+
hide();
1000710042
}
1000810043
}
1000910044

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)