Merge "Cherry-pick Ib76a95d9e7669016cf11b8b0add8843b438068ea from gingerbread"
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5320b10..b143325 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3869,7 +3869,7 @@
// - 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()) {
startSelectionActionMode();
}
@@ -5042,6 +5042,7 @@
}
public void beginBatchEdit() {
+ mInBatchEditControllers = true;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = ++ims.mBatchEditNesting;
@@ -5064,6 +5065,7 @@
}
public void endBatchEdit() {
+ mInBatchEditControllers = false;
final InputMethodState ims = mInputMethodState;
if (ims != null) {
int nesting = --ims.mBatchEditNesting;
@@ -6991,26 +6993,21 @@
// 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();
- } else {
- // Tapping inside the selection displays the cut/copy/paste context menu
- // as long as the anchors are already showing.
- showContextMenu();
+ getSelectionController().show();
}
return;
} else {
// Tapping outside stops selection mode, if any
stopSelectionActionMode();
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.show();
+ if (hasInsertionController()) {
+ getInsertionController().show();
}
}
- } else if (hasSelection() && mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.show();
+ } else if (hasSelection() && hasSelectionController()) {
+ getSelectionController().show();
}
}
@@ -7043,11 +7040,12 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onTouchEvent(event);
+
+ if (hasInsertionController()) {
+ getInsertionController().onTouchEvent(event);
}
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onTouchEvent(event);
+ if (hasSelectionController()) {
+ getSelectionController().onTouchEvent(event);
}
if (action == MotionEvent.ACTION_DOWN) {
@@ -7129,21 +7127,17 @@
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
- if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null &&
- !mTextIsSelectable) {
- if (mInsertionPointCursorController == null) {
- mInsertionPointCursorController = new InsertionPointCursorController();
- }
- } else {
- hideInsertionPointCursorController();
+ // TODO Add an extra android:cursorController flag to disable the controller?
+ mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible &&
+ mLayout != null && !mTextIsSelectable;
+ 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.
if (mSelectionModifierCursorController != null) {
stopSelectionActionMode();
@@ -8348,6 +8342,10 @@
return true;
}
+ if (isInBatchEditMode()) {
+ return false;
+ }
+
final int extendedPaddingTop = getExtendedPaddingTop();
final int extendedPaddingBottom = getExtendedPaddingBottom();
final int compoundPaddingLeft = getCompoundPaddingLeft();
@@ -8387,7 +8385,7 @@
mPositionY = y - TextView.this.mScrollY;
if (isPositionVisible()) {
int[] coords = null;
- if (mContainer.isShowing()){
+ if (mContainer.isShowing()) {
coords = mTempCoords;
TextView.this.getLocationInWindow(coords);
final int containerPositionX = coords[0] + mPositionX;
@@ -8626,6 +8624,10 @@
}
public void show() {
+ if (isInBatchEditMode()) {
+ return;
+ }
+
mIsShowing = true;
updatePosition();
mStartHandle.show();
@@ -8689,6 +8691,10 @@
}
public void updatePosition() {
+ if (!isShowing()) {
+ return;
+ }
+
final int selectionStart = getSelectionStart();
final int selectionEnd = getSelectionEnd();
@@ -8913,8 +8919,62 @@
}
}
+ /**
+ * @return True if this view supports insertion handles.
+ */
+ boolean hasInsertionController() {
+ return mInsertionControllerEnabled;
+ }
- @ViewDebug.ExportedProperty(category = "text")
+ /**
+ * @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;
+ }
+
private CharSequence mText;
private CharSequence mTransformed;
private BufferType mBufferType = BufferType.NORMAL;
@@ -8942,10 +9002,14 @@
private Blink mBlink;
private boolean mCursorVisible = true;
- // Cursor Controllers. Null when disabled.
+ // Cursor Controllers.
private CursorController mInsertionPointCursorController;
private CursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
+ private boolean mInsertionControllerEnabled;
+ private boolean mSelectionControllerEnabled;
+ private boolean mInBatchEditControllers;
+
// 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.
private boolean mDPadCenterIsDown = false;