summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/widget/TextView.java127
1 files changed, 98 insertions, 29 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b30b6b1d3841..41c973614b82 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3758,7 +3758,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would
// allow to test for hasSelection in onFocusChanged, which would trigger a
// startTextSelectionMode here. TODO
- if (selectionController != null && hasSelection()) {
+ if (this instanceof ExtractEditText && selectionController != null && hasSelection()) {
startTextSelectionMode();
}
@@ -4819,6 +4819,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public void beginBatchEdit() {
+ mInBatchEditControllers = true;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = ++ims.mBatchEditNesting;
@@ -4841,6 +4842,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public void endBatchEdit() {
+ mInBatchEditControllers = false;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = --ims.mBatchEditNesting;
@@ -6747,10 +6749,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Restore previous selection
Selection.setSelection((Spannable)mText, prevStart, prevEnd);
- if (mSelectionModifierCursorController != null &&
- !mSelectionModifierCursorController.isShowing()) {
+ if (hasSelectionController() && !getSelectionController().isShowing()) {
// If the anchors aren't showing, revive them.
- mSelectionModifierCursorController.show();
+ getSelectionController().show();
} else {
// Tapping inside the selection displays the cut/copy/paste context menu
// as long as the anchors are already showing.
@@ -6761,12 +6762,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Tapping outside stops selection mode, if any
stopTextSelectionMode();
- if (mInsertionPointCursorController != null && mText.length() > 0) {
- mInsertionPointCursorController.show();
+ if (hasInsertionController() && mText.length() > 0) {
+ getInsertionController().show();
}
}
- } else if (hasSelection() && mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.show();
+ } else if (hasSelection() && hasSelectionController()) {
+ getSelectionController().show();
}
}
@@ -6800,11 +6801,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onTouchEvent(event);
+ if (hasInsertionController()) {
+ getInsertionController().onTouchEvent(event);
}
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onTouchEvent(event);
+ if (hasSelectionController()) {
+ getSelectionController().onTouchEvent(event);
}
// Reset this state; it will be re-set if super.onTouchEvent
@@ -6826,11 +6827,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if ((mMovement != null || onCheckIsTextEditor()) && mText instanceof Spannable && mLayout != null) {
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onTouchEvent(event);
+ if (hasInsertionController()) {
+ getInsertionController().onTouchEvent(event);
}
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onTouchEvent(event);
+ if (hasSelectionController()) {
+ getSelectionController().onTouchEvent(event);
}
boolean handled = false;
@@ -6892,19 +6893,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// TODO Add an extra android:cursorController flag to disable the controller?
- if (windowSupportsHandles && mCursorVisible && mLayout != null) {
- if (mInsertionPointCursorController == null) {
- mInsertionPointCursorController = new InsertionPointCursorController();
- }
- } else {
+ mInsertionControllerEnabled = windowSupportsHandles && mCursorVisible && mLayout != null;
+ mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() &&
+ mLayout != null;
+
+ if (!mInsertionControllerEnabled) {
mInsertionPointCursorController = null;
}
- if (windowSupportsHandles && textCanBeSelected() && mLayout != null) {
- if (mSelectionModifierCursorController == null) {
- mSelectionModifierCursorController = new SelectionModifierCursorController();
- }
- } else {
+ if (!mSelectionControllerEnabled) {
// Stop selection mode if the controller becomes unavailable.
stopTextSelectionMode();
mSelectionModifierCursorController = null;
@@ -7535,10 +7532,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case ID_SELECT_ALL:
Selection.setSelection((Spannable) mText, 0, mText.length());
startTextSelectionMode();
+ getSelectionController().show();
return true;
case ID_START_SELECTING_TEXT:
startTextSelectionMode();
+ getSelectionController().show();
return true;
case ID_CUT:
@@ -7648,7 +7647,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void startTextSelectionMode() {
if (!mIsInTextSelectionMode) {
- if (mSelectionModifierCursorController == null) {
+ if (!hasSelectionController()) {
Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
return;
}
@@ -7658,7 +7657,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
selectCurrentWord();
- mSelectionModifierCursorController.show();
mIsInTextSelectionMode = true;
}
}
@@ -7837,6 +7835,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
}
+ if (isInBatchEditMode()) {
+ return false;
+ }
+
final int extendedPaddingTop = getExtendedPaddingTop();
final int extendedPaddingBottom = getExtendedPaddingBottom();
final int compoundPaddingLeft = getCompoundPaddingLeft();
@@ -7876,7 +7878,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mPositionY = y - TextView.this.mScrollY;
if (isPositionVisible()) {
int[] coords = null;
- if (mContainer.isShowing()){
+ if (mContainer.isShowing()) {
coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
mContainer.update(coords[0] + mPositionX, coords[1] + mPositionY,
@@ -8065,6 +8067,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public void show() {
+ if (isInBatchEditMode()) {
+ return;
+ }
+
mIsShowing = true;
updatePosition();
mStartHandle.show();
@@ -8128,6 +8134,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public void updatePosition() {
+ if (!isShowing()) {
+ return;
+ }
+
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
@@ -8288,6 +8298,62 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return getOffsetForHorizontal(line, x);
}
+ /**
+ * @return True if this view supports insertion handles.
+ */
+ boolean hasInsertionController() {
+ return mInsertionControllerEnabled;
+ }
+
+ /**
+ * @return True if this view supports selection handles.
+ */
+ boolean hasSelectionController() {
+ return mSelectionControllerEnabled;
+ }
+
+ CursorController getInsertionController() {
+ if (!mInsertionControllerEnabled) {
+ return null;
+ }
+
+ if (mInsertionPointCursorController == null) {
+ mInsertionPointCursorController = new InsertionPointCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null) {
+ observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
+ }
+ }
+
+ return mInsertionPointCursorController;
+ }
+
+ CursorController getSelectionController() {
+ if (!mSelectionControllerEnabled) {
+ return null;
+ }
+
+ if (mSelectionModifierCursorController == null) {
+ mSelectionModifierCursorController = new SelectionModifierCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null) {
+ observer.addOnTouchModeChangeListener(mSelectionModifierCursorController);
+ }
+ }
+
+ return mSelectionModifierCursorController;
+ }
+
+ boolean isInBatchEditMode() {
+ final InputMethodState ims = mInputMethodState;
+ if (ims != null) {
+ return ims.mBatchEditNesting > 0;
+ }
+ return mInBatchEditControllers;
+ }
+
@ViewDebug.ExportedProperty
private CharSequence mText;
private CharSequence mTransformed;
@@ -8319,6 +8385,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Cursor Controllers. Null when disabled.
private CursorController mInsertionPointCursorController;
private CursorController mSelectionModifierCursorController;
+ private boolean mInsertionControllerEnabled;
+ private boolean mSelectionControllerEnabled;
+ private boolean mInBatchEditControllers;
private boolean mIsInTextSelectionMode = false;
// These are needed to desambiguate a long click. If the long click comes from ones of these, we
// select from the current cursor position. Otherwise, select from long pressed position.