summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Gilles Debunne <debunne@google.com> 2011-08-30 15:53:33 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2011-08-30 15:53:33 -0700
commitb5305007a6eb10457aa97b9791fed62d3542e3c1 (patch)
treef230955eae4f1130251936c764b0fcd7fe629246
parent9c93db60e6d9172e1957e5e31a6c5b82e2494420 (diff)
parente6d368218918f911b1954296dab25bf84147b4c6 (diff)
Merge "Add EditTextShortcutSpan to provide edit short cut in the text view."
-rw-r--r--api/current.txt8
-rw-r--r--core/java/android/text/TextLine.java19
-rw-r--r--core/java/android/text/TextPaint.java51
-rw-r--r--core/java/android/text/TextUtils.java7
-rw-r--r--core/java/android/text/style/EasyEditSpan.java54
-rw-r--r--core/java/android/text/style/SuggestionSpan.java67
-rw-r--r--core/java/android/widget/TextView.java188
-rwxr-xr-xcore/res/res/values/attrs.xml15
-rwxr-xr-xcore/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/styles.xml7
-rw-r--r--core/res/res/values/themes.xml1
11 files changed, 351 insertions, 69 deletions
diff --git a/api/current.txt b/api/current.txt
index 6daf77ebb735..c4256afcbc2d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20689,6 +20689,14 @@ package android.text.style {
field protected final int mVerticalAlignment;
}
+ public class EasyEditSpan implements android.text.ParcelableSpan {
+ ctor public EasyEditSpan();
+ ctor public EasyEditSpan(android.os.Parcel);
+ method public int describeContents();
+ method public int getSpanTypeId();
+ method public void writeToParcel(android.os.Parcel, int);
+ }
+
public class ForegroundColorSpan extends android.text.style.CharacterStyle implements android.text.ParcelableSpan android.text.style.UpdateAppearance {
ctor public ForegroundColorSpan(int);
ctor public ForegroundColorSpan(android.os.Parcel);
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index fcc372e36dfd..68a6b3e7823e 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -723,7 +723,7 @@ class TextLine {
float ret = 0;
int contextLen = contextEnd - contextStart;
- if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor !=0 || runIsRtl))) {
+ if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineCount != 0 || runIsRtl))) {
int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR;
if (mCharsValid) {
ret = wp.getTextRunAdvances(mChars, start, runLen,
@@ -753,21 +753,26 @@ class TextLine {
wp.setColor(previousColor);
}
- if (wp.underlineColor != 0) {
+ if (wp.underlineCount != 0) {
// kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
- float middle = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();
- // kStdUnderline_Thickness = 1/18, defined in SkTextFormatParams.h
- float halfHeight = wp.underlineThickness * (1.0f / 18.0f / 2.0f) * wp.getTextSize();
+ float underlineTop = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();
int previousColor = wp.getColor();
Paint.Style previousStyle = wp.getStyle();
+ boolean previousAntiAlias = wp.isAntiAlias();
- wp.setColor(wp.underlineColor);
wp.setStyle(Paint.Style.FILL);
- c.drawRect(x, middle - halfHeight, x + ret, middle + halfHeight, wp);
+ wp.setAntiAlias(true);
+
+ for (int i = 0; i < wp.underlineCount; i++) {
+ wp.setColor(wp.underlineColors[i]);
+ c.drawRect(x, underlineTop, x + ret, underlineTop + wp.underlineThicknesses[i],
+ wp);
+ }
wp.setStyle(previousStyle);
wp.setColor(previousColor);
+ wp.setAntiAlias(previousAntiAlias);
}
drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl,
diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java
index de57dfabdb5b..625d8693dbde 100644
--- a/core/java/android/text/TextPaint.java
+++ b/core/java/android/text/TextPaint.java
@@ -23,6 +23,9 @@ import android.graphics.Paint;
* data used during text measuring and drawing.
*/
public class TextPaint extends Paint {
+
+ private static final int DEFAULT_UNDERLINE_SIZE = 3;
+
// Special value 0 means no background paint
public int bgColor;
public int baselineShift;
@@ -33,12 +36,17 @@ public class TextPaint extends Paint {
* Special value 0 means no custom underline
* @hide
*/
- public int underlineColor;
+ public int[] underlineColors;
/**
* Defined as a multiplier of the default underline thickness. Use 1.0f for default thickness.
* @hide
*/
- public float underlineThickness;
+ public float[] underlineThicknesses;
+ /**
+ * The number of underlines currently stored in the array. If 0, no underline is drawn.
+ * @hide
+ */
+ public int underlineCount;
public TextPaint() {
super();
@@ -64,24 +72,43 @@ public class TextPaint extends Paint {
linkColor = tp.linkColor;
drawableState = tp.drawableState;
density = tp.density;
- underlineColor = tp.underlineColor;
- underlineThickness = tp.underlineThickness;
+ underlineColors = tp.underlineColors;
+ underlineThicknesses = tp.underlineThicknesses;
+ underlineCount = tp.underlineCount;
}
/**
* Defines a custom underline for this Paint.
* @param color underline solid color
- * @param thickness underline thickness, defined as a multiplier of the default underline
- * thickness.
+ * @param thickness underline thickness
* @hide
*/
- public void setUnderlineText(boolean isUnderlined, int color, float thickness) {
- setUnderlineText(false);
- if (isUnderlined) {
- underlineColor = color;
- underlineThickness = thickness;
+ public void setUnderlineText(int color, float thickness) {
+ if (color == 0) {
+ // No underline
+ return;
+ }
+
+ if (underlineCount == 0) {
+ underlineColors = new int[DEFAULT_UNDERLINE_SIZE];
+ underlineThicknesses = new float[DEFAULT_UNDERLINE_SIZE];
+ underlineColors[underlineCount] = color;
+ underlineThicknesses[underlineCount] = thickness;
+ underlineCount++;
} else {
- underlineColor = 0;
+ if (underlineCount == underlineColors.length) {
+ int[] newColors = new int[underlineColors.length + DEFAULT_UNDERLINE_SIZE];
+ float[] newThickness = new float[underlineThicknesses.length
+ + DEFAULT_UNDERLINE_SIZE];
+ System.arraycopy(underlineColors, 0, newColors, 0, underlineColors.length);
+ System.arraycopy(
+ underlineThicknesses, 0, newThickness, 0, underlineThicknesses.length);
+ underlineColors = newColors;
+ underlineThicknesses = newThickness;
+ }
+ underlineColors[underlineCount] = color;
+ underlineThicknesses[underlineCount] = thickness;
+ underlineCount++;
}
}
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index b8b54f47bd98..e91431689776 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -25,6 +25,7 @@ import android.text.style.BackgroundColorSpan;
import android.text.style.BulletSpan;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
+import android.text.style.EasyEditSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.MetricAffectingSpan;
import android.text.style.QuoteSpan;
@@ -585,6 +586,8 @@ public class TextUtils {
public static final int SPELL_CHECK_SPAN = 20;
/** @hide */
public static final int SUGGESTION_RANGE_SPAN = 21;
+ /** @hide */
+ public static final int EASY_EDIT_SPAN = 22;
/**
* Flatten a CharSequence and whatever styles can be copied across processes
@@ -748,6 +751,10 @@ public class TextUtils {
readSpan(p, sp, new SuggestionRangeSpan());
break;
+ case EASY_EDIT_SPAN:
+ readSpan(p, sp, new EasyEditSpan(p));
+ break;
+
default:
throw new RuntimeException("bogus span encoding " + kind);
}
diff --git a/core/java/android/text/style/EasyEditSpan.java b/core/java/android/text/style/EasyEditSpan.java
new file mode 100644
index 000000000000..e6e4d2c89959
--- /dev/null
+++ b/core/java/android/text/style/EasyEditSpan.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.os.Parcel;
+import android.text.ParcelableSpan;
+import android.text.TextUtils;
+import android.widget.TextView;
+
+/**
+ * Provides an easy way to edit a portion of text.
+ * <p>
+ * The {@link TextView} uses this span to allow the user to delete a chuck of text in one click.
+ * the text. {@link TextView} removes this span as soon as the text is edited, or the cursor moves.
+ */
+public class EasyEditSpan implements ParcelableSpan {
+
+ public EasyEditSpan() {
+ // Empty
+ }
+
+ public EasyEditSpan(Parcel src) {
+ this();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // Empty
+ }
+
+ @Override
+ public int getSpanTypeId() {
+ return TextUtils.EASY_EDIT_SPAN;
+ }
+}
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index ea57f917fc1a..86252578db79 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -61,12 +61,6 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";
- /**
- * The default underline thickness as a percentage of the system's default underline thickness
- * (i.e., 100 means the default thickness, and 200 is a double thickness).
- */
- private static final int DEFAULT_UNDERLINE_PERCENTAGE = 100;
-
public static final int SUGGESTIONS_MAX_SIZE = 5;
/*
@@ -82,10 +76,8 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
private final String mNotificationTargetClassName;
private final int mHashCode;
- private float mMisspelledUnderlineThickness;
- private int mMisspelledUnderlineColor;
- private float mEasyCorrectUnderlineThickness;
- private int mEasyCorrectUnderlineColor;
+ private float mUnderlineThickness;
+ private int mUnderlineColor;
/*
* TODO: If switching IME is required, needs to add parameters for ids of InputMethodInfo
@@ -140,31 +132,26 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
}
private void initStyle(Context context) {
- // Read the colors. We need to store the color and the underline thickness, as the span
- // does not have access to the context when it is read from a parcel.
- TypedArray typedArray;
+ int defStyle = 0;
+ if ((getFlags() & FLAG_MISSPELLED) != 0) {
+ defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
+ } else if ((getFlags() & FLAG_EASY_CORRECT) != 0) {
+ defStyle = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
+ } else {
+ // No style is applied.
+ mUnderlineThickness = 0;
+ mUnderlineColor = 0;
+ return;
+ }
- typedArray = context.obtainStyledAttributes(null,
+ TypedArray typedArray = context.obtainStyledAttributes(null,
com.android.internal.R.styleable.SuggestionSpan,
- com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion, 0);
+ defStyle, 0);
- mEasyCorrectUnderlineThickness = getThicknessPercentage(typedArray,
- com.android.internal.R.styleable.SuggestionSpan_textUnderlineThicknessPercentage);
- mEasyCorrectUnderlineColor = typedArray.getColor(
+ mUnderlineThickness = typedArray.getDimension(
+ com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
+ mUnderlineColor = typedArray.getColor(
com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
-
- typedArray = context.obtainStyledAttributes(null,
- com.android.internal.R.styleable.SuggestionSpan,
- com.android.internal.R.attr.textAppearanceMisspelledSuggestion, 0);
- mMisspelledUnderlineThickness = getThicknessPercentage(typedArray,
- com.android.internal.R.styleable.SuggestionSpan_textUnderlineThicknessPercentage);
- mMisspelledUnderlineColor = typedArray.getColor(
- com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
- }
-
- private static float getThicknessPercentage(TypedArray typedArray, int index) {
- int value = typedArray.getInteger(index, DEFAULT_UNDERLINE_PERCENTAGE);
- return value / 100.0f;
}
public SuggestionSpan(Parcel src) {
@@ -173,10 +160,8 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
mLocaleString = src.readString();
mNotificationTargetClassName = src.readString();
mHashCode = src.readInt();
- mEasyCorrectUnderlineColor = src.readInt();
- mEasyCorrectUnderlineThickness = src.readFloat();
- mMisspelledUnderlineColor = src.readInt();
- mMisspelledUnderlineThickness = src.readFloat();
+ mUnderlineColor = src.readInt();
+ mUnderlineThickness = src.readFloat();
}
/**
@@ -226,10 +211,8 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
dest.writeString(mLocaleString);
dest.writeString(mNotificationTargetClassName);
dest.writeInt(mHashCode);
- dest.writeInt(mEasyCorrectUnderlineColor);
- dest.writeFloat(mEasyCorrectUnderlineThickness);
- dest.writeInt(mMisspelledUnderlineColor);
- dest.writeFloat(mMisspelledUnderlineThickness);
+ dest.writeInt(mUnderlineColor);
+ dest.writeFloat(mUnderlineThickness);
}
@Override
@@ -271,10 +254,6 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
@Override
public void updateDrawState(TextPaint tp) {
- if ((getFlags() & FLAG_MISSPELLED) != 0) {
- tp.setUnderlineText(true, mMisspelledUnderlineColor, mMisspelledUnderlineThickness);
- } else if ((getFlags() & FLAG_EASY_CORRECT) != 0) {
- tp.setUnderlineText(true, mEasyCorrectUnderlineColor, mEasyCorrectUnderlineThickness);
- }
+ tp.setUnderlineText(mUnderlineColor, mUnderlineThickness);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 94f1604b16e1..135797fda89f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -81,7 +81,9 @@ import android.text.method.TimeKeyListener;
import android.text.method.TransformationMethod;
import android.text.method.TransformationMethod2;
import android.text.method.WordIterator;
+import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
+import android.text.style.EasyEditSpan;
import android.text.style.ParagraphStyle;
import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionRangeSpan;
@@ -7705,10 +7707,148 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ /**
+ * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
+ * pop-up should be displayed.
+ */
+ private class EditTextShortcutController {
+
+ private EditTextShortcutPopupWindow mPopupWindow;
+
+ private EasyEditSpan mEditTextShortcutSpan;
+
+ private void hide() {
+ if (mEditTextShortcutSpan != null) {
+ mPopupWindow.hide();
+ if (mText instanceof Spannable) {
+ ((Spannable) mText).removeSpan(mEditTextShortcutSpan);
+ }
+ mEditTextShortcutSpan = null;
+ }
+ }
+
+ /**
+ * Monitors the changes in the text.
+ *
+ * <p>{@link ChangeWatcher#onSpanAdded(Spannable, Object, int, int)} cannot be used,
+ * as the notifications are not sent when a spannable (with spans) is inserted.
+ */
+ public void onTextChange(CharSequence buffer) {
+ if (mEditTextShortcutSpan != null) {
+ hide();
+ }
+
+ if (buffer instanceof Spanned) {
+ mEditTextShortcutSpan = getSpan((Spanned) buffer);
+ if (mEditTextShortcutSpan != null) {
+ if (mPopupWindow == null) {
+ mPopupWindow = new EditTextShortcutPopupWindow();
+ }
+ mPopupWindow.show(mEditTextShortcutSpan);
+ }
+ }
+ }
+
+ private EasyEditSpan getSpan(Spanned spanned) {
+ EasyEditSpan[] inputMethodSpans = spanned.getSpans(0, spanned.length(),
+ EasyEditSpan.class);
+
+ if (inputMethodSpans.length == 0) {
+ return null;
+ } else {
+ return inputMethodSpans[0];
+ }
+ }
+ }
+
+ /**
+ * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
+ * by {@link EditTextShortcutController}.
+ */
+ private class EditTextShortcutPopupWindow extends PinnedPopupWindow
+ implements OnClickListener {
+ private static final int POPUP_TEXT_LAYOUT =
+ com.android.internal.R.layout.text_edit_action_popup_text;
+ private TextView mDeleteTextView;
+ private EasyEditSpan mEditTextShortcutSpan;
+
+ @Override
+ protected void createPopupWindow() {
+ mPopupWindow = new PopupWindow(TextView.this.mContext, null,
+ com.android.internal.R.attr.textSelectHandleWindowStyle);
+ mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+ mPopupWindow.setClippingEnabled(true);
+ }
+
+ @Override
+ protected void initContentView() {
+ mContentView.setOrientation(LinearLayout.HORIZONTAL);
+ mContentView.setBackgroundResource(
+ com.android.internal.R.drawable.text_edit_side_paste_window);
+
+ LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
+ getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mDeleteTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
+ mDeleteTextView.setLayoutParams(wrapContent);
+ mDeleteTextView.setText(com.android.internal.R.string.delete);
+ mDeleteTextView.setOnClickListener(this);
+ mContentView.addView(mDeleteTextView);
+ }
+
+ public void show(EasyEditSpan inputMethodSpan) {
+ mEditTextShortcutSpan = inputMethodSpan;
+ super.show();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == mDeleteTextView) {
+ deleteText();
+ }
+ }
+
+ private void deleteText() {
+ Editable editable = (Editable) mText;
+ int start = editable.getSpanStart(mEditTextShortcutSpan);
+ int end = editable.getSpanEnd(mEditTextShortcutSpan);
+ if (start >= 0 && end >= 0) {
+ editable.delete(start, end);
+ }
+ }
+
+ @Override
+ protected int getTextOffset() {
+ // Place the pop-up at the end of the span
+ Editable editable = (Editable) mText;
+ return editable.getSpanEnd(mEditTextShortcutSpan);
+ }
+
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineBottom(line);
+ }
+
+ @Override
+ protected int clipVertically(int positionY) {
+ // As we display the pop-up below the span, no vertical clipping is required.
+ return positionY;
+ }
+ }
+
private class ChangeWatcher implements TextWatcher, SpanWatcher {
private CharSequence mBeforeText;
+ private EditTextShortcutController mEditTextShortcutController;
+
+ private ChangeWatcher() {
+ mEditTextShortcutController = new EditTextShortcutController();
+ }
+
public void beforeTextChanged(CharSequence buffer, int start,
int before, int after) {
if (DEBUG_EXTRACT) Log.v(LOG_TAG, "beforeTextChanged start=" + start
@@ -7729,6 +7869,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
+ " before=" + before + " after=" + after + ": " + buffer);
TextView.this.handleTextChanged(buffer, start, before, after);
+ mEditTextShortcutController.onTextChange(buffer);
+
if (AccessibilityManager.getInstance(mContext).isEnabled() &&
(isFocused() || isSelected() && isShown())) {
sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
@@ -7763,6 +7905,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
+ " what=" + what + ": " + buf);
TextView.this.spanChange(buf, what, s, -1, e, -1);
}
+
+ private void hideControllers() {
+ mEditTextShortcutController.hide();
+ }
}
/**
@@ -9184,6 +9330,34 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ private static class SuggestionRangeSpan extends CharacterStyle {
+
+ private final int mTextColor;
+ private final int mBackgroundColor;
+
+ public SuggestionRangeSpan(Context context) {
+ TypedArray typedArray = context.obtainStyledAttributes(null,
+ com.android.internal.R.styleable.SuggestionRangeSpan,
+ com.android.internal.R.attr.textAppearanceSuggestionRange, 0);
+
+ mTextColor = typedArray.getColor(
+ com.android.internal.R.styleable.SuggestionRangeSpan_textColor, 0);
+ mBackgroundColor = typedArray.getColor(
+ com.android.internal.R.styleable.SuggestionRangeSpan_colorBackground, 0);
+ }
+
+ @Override
+ public void updateDrawState(TextPaint tp) {
+ if (mTextColor != 0) {
+ tp.setColor(mTextColor);
+ }
+
+ if (mBackgroundColor != 0) {
+ tp.bgColor = mBackgroundColor;
+ }
+ }
+ }
+
private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnClickListener {
private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
private static final int NO_SUGGESTIONS = -1;
@@ -9368,7 +9542,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (totalNbSuggestions == 0) return false;
- if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
+ if (mSuggestionRangeSpan == null) {
+ mSuggestionRangeSpan = new SuggestionRangeSpan(getContext());
+ }
+
+ ((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ if (mSuggestionRangeSpan == null) mSuggestionRangeSpan =
+ new SuggestionRangeSpan(getContext());
((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -10695,6 +10877,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void hideControllers() {
hideInsertionPointCursorController();
stopSelectionActionMode();
+
+ if (mChangeWatcher != null) {
+ mChangeWatcher.hideControllers();
+ }
}
/**
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8c0d8262b7ce..fed56511372e 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -158,11 +158,14 @@
<!-- The underline color and thickness for misspelled suggestion -->
<attr name="textAppearanceMisspelledSuggestion" format="reference" />
+ <!-- The text color and the background for suggestion range span. This span identifies the
+ portion of text the suggestions refer to). -->
+ <attr name="textAppearanceSuggestionRange" format="reference" />
+
<!-- The underline color -->
<attr name="textUnderlineColor" format="reference|color" />
- <!-- The underline thickness, expressed as a percentage of the default underline thickness
- (i.e., 100 means default thickness, and 200 means double thickness). -->
- <attr name="textUnderlineThicknessPercentage" format="reference|integer" />
+ <!-- The underline thickness -->
+ <attr name="textUnderlineThickness" format="reference|dimension" />
<!-- EditText text foreground color. -->
<attr name="editTextColor" format="reference|color" />
@@ -3149,7 +3152,11 @@
</declare-styleable>
<declare-styleable name="SuggestionSpan">
<attr name="textUnderlineColor" />
- <attr name="textUnderlineThicknessPercentage" />
+ <attr name="textUnderlineThickness" />
+ </declare-styleable>
+ <declare-styleable name="SuggestionRangeSpan">
+ <attr name="textColor" />
+ <attr name="colorBackground" />
</declare-styleable>
<!-- An <code>input-extras</code> is a container for extra data to supply to
an input method. Contains
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 547e1fcb8663..a9e2971d6e46 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2472,6 +2472,9 @@
<!-- Item on EditText context menu. This action is used to replace the current word by other suggested words, suggested by the IME or the spell checker -->
<string name="replace">Replace\u2026</string>
+ <!-- Item on EditText pop-up window. This action is used to delete the text that the user recently added. [CHAR LIMIT=15] -->
+ <string name="delete">Delete</string>
+
<!-- Item on EditText context menu. This action is used to copy a URL from the edit field into the clipboard. -->
<string name="copyUrl">Copy URL</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 052a040b09e3..1a2ad05bb2d8 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -244,7 +244,7 @@ please see styles_device_defaults.xml.
</style>
<style name="TextAppearance.Suggestion">
- <item name="android:textUnderlineThicknessPercentage">200</item>
+ <item name="android:textUnderlineThickness">2dip</item>
</style>
<style name="TextAppearance.EasyCorrectSuggestion" parent="TextAppearance.Suggestion">
@@ -255,6 +255,11 @@ please see styles_device_defaults.xml.
<item name="android:textUnderlineColor">@color/holo_red_light</item>
</style>
+ <style name="TextAppearance.SuggestionRange">
+ <item name="android:textColor">@color/white</item>
+ <item name="android:colorBackground">@color/holo_blue_dark</item>
+ </style>
+
<!-- Widget Styles -->
<style name="Widget">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index f434ce8af06f..899c9d52eb44 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -91,6 +91,7 @@ please see themes_device_defaults.xml.
<item name="textAppearanceEasyCorrectSuggestion">@android:style/TextAppearance.EasyCorrectSuggestion</item>
<item name="textAppearanceMisspelledSuggestion">@android:style/TextAppearance.MisspelledSuggestion</item>
+ <item name="textAppearanceSuggestionRange">@android:style/TextAppearance.SuggestionRange</item>
<item name="textAppearanceButton">@android:style/TextAppearance.Widget.Button</item>