Merge "Separate the SelectionActionMode into Insertion and Selection." into mnc-dev

This commit is contained in:
Clara Bayarri
2015-06-05 00:40:41 +00:00
committed by Android (Google) Code Review
5 changed files with 183 additions and 131 deletions

View File

@@ -41542,6 +41542,7 @@ package android.widget {
method public int getCompoundPaddingTop();
method public final int getCurrentHintTextColor();
method public final int getCurrentTextColor();
method public android.view.ActionMode.Callback getCustomInsertionActionModeCallback();
method public android.view.ActionMode.Callback getCustomSelectionActionModeCallback();
method protected boolean getDefaultEditable();
method protected android.text.method.MovementMethod getDefaultMovementMethod();
@@ -41644,6 +41645,7 @@ package android.widget {
method public void setCompoundDrawablesWithIntrinsicBounds(int, int, int, int);
method public void setCompoundDrawablesWithIntrinsicBounds(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public void setCursorVisible(boolean);
method public void setCustomInsertionActionModeCallback(android.view.ActionMode.Callback);
method public void setCustomSelectionActionModeCallback(android.view.ActionMode.Callback);
method public final void setEditableFactory(android.text.Editable.Factory);
method public void setElegantTextHeight(boolean);

View File

@@ -44121,6 +44121,7 @@ package android.widget {
method public int getCompoundPaddingTop();
method public final int getCurrentHintTextColor();
method public final int getCurrentTextColor();
method public android.view.ActionMode.Callback getCustomInsertionActionModeCallback();
method public android.view.ActionMode.Callback getCustomSelectionActionModeCallback();
method protected boolean getDefaultEditable();
method protected android.text.method.MovementMethod getDefaultMovementMethod();
@@ -44223,6 +44224,7 @@ package android.widget {
method public void setCompoundDrawablesWithIntrinsicBounds(int, int, int, int);
method public void setCompoundDrawablesWithIntrinsicBounds(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public void setCursorVisible(boolean);
method public void setCustomInsertionActionModeCallback(android.view.ActionMode.Callback);
method public void setCustomSelectionActionModeCallback(android.view.ActionMode.Callback);
method public final void setEditableFactory(android.text.Editable.Factory);
method public void setElegantTextHeight(boolean);

View File

@@ -106,7 +106,7 @@ public class ExtractEditText extends EditText {
if (mIME != null && mIME.onExtractTextContextMenuItem(id)) {
// Mode was started on Extracted, needs to be stopped here.
// Cut and paste will change the text, which stops selection mode.
if (id == android.R.id.copy) stopSelectionActionMode();
if (id == android.R.id.copy) stopTextActionMode();
return true;
}
return super.onTextContextMenuItem(id);

View File

@@ -134,7 +134,8 @@ public class Editor {
// Cursor Controllers.
InsertionPointCursorController mInsertionPointCursorController;
SelectionModifierCursorController mSelectionModifierCursorController;
ActionMode mSelectionActionMode;
// Action mode used when text is selected or when actions on an insertion cursor are triggered.
ActionMode mTextActionMode;
boolean mInsertionControllerEnabled;
boolean mSelectionControllerEnabled;
@@ -205,13 +206,14 @@ public class Editor {
float mLastDownPositionX, mLastDownPositionY;
Callback mCustomSelectionActionModeCallback;
Callback mCustomInsertionActionModeCallback;
// Set when this TextView gained focus with some text selected. Will start selection mode.
boolean mCreatedWithASelection;
boolean mDoubleTap = false;
private Runnable mSelectionModeWithoutSelectionRunnable;
private Runnable mInsertionActionModeRunnable;
// The span controller helps monitoring the changes to which the Editor needs to react:
// - EasyEditSpans, for which we have some UI to display on attach and on hide
@@ -236,8 +238,8 @@ public class Editor {
private final Runnable mHideFloatingToolbar = new Runnable() {
@Override
public void run() {
if (mSelectionActionMode != null) {
mSelectionActionMode.snooze(ActionMode.SNOOZE_TIME_DEFAULT);
if (mTextActionMode != null) {
mTextActionMode.snooze(ActionMode.SNOOZE_TIME_DEFAULT);
}
}
};
@@ -245,8 +247,8 @@ public class Editor {
private final Runnable mShowFloatingToolbar = new Runnable() {
@Override
public void run() {
if (mSelectionActionMode != null) {
mSelectionActionMode.snooze(0); // snooze off.
if (mTextActionMode != null) {
mTextActionMode.snooze(0); // snooze off.
}
}
};
@@ -310,7 +312,7 @@ public class Editor {
void replace() {
int middle = (mTextView.getSelectionStart() + mTextView.getSelectionEnd()) / 2;
stopSelectionActionMode();
stopTextActionMode();
Selection.setSelection((Spannable) mTextView.getText(), middle);
showSuggestions();
}
@@ -343,7 +345,7 @@ public class Editor {
mTextView.setHasTransientState(false);
// We had an active selection from before, start the selection mode.
startSelectionActionModeWithSelection();
startSelectionActionMode();
}
getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true);
@@ -372,8 +374,8 @@ public class Editor {
}
// Cancel the single tap delayed runnable.
if (mSelectionModeWithoutSelectionRunnable != null) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
if (mInsertionActionModeRunnable != null) {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
mTextView.removeCallbacks(mHideFloatingToolbar);
@@ -390,7 +392,7 @@ public class Editor {
mPreserveDetachedSelection = true;
hideControllers();
stopSelectionActionMode();
stopTextActionMode();
mPreserveDetachedSelection = false;
mTemporaryDetach = false;
}
@@ -586,7 +588,7 @@ public class Editor {
}
if (!mSelectionControllerEnabled) {
stopSelectionActionMode();
stopTextActionMode();
if (mSelectionModifierCursorController != null) {
mSelectionModifierCursorController.onDetached();
mSelectionModifierCursorController = null;
@@ -984,14 +986,14 @@ public class Editor {
mInsertionControllerEnabled) {
final int offset = mTextView.getOffsetForPosition(mLastDownPositionX,
mLastDownPositionY);
stopSelectionActionMode();
stopTextActionMode();
Selection.setSelection((Spannable) mTextView.getText(), offset);
getInsertionController().show();
startSelectionActionModeWithoutSelection();
startInsertionActionMode();
handled = true;
}
if (!handled && mSelectionActionMode != null) {
if (!handled && mTextActionMode != null) {
if (touchPositionIsInSelection()) {
// Start a drag
final int start = mTextView.getSelectionStart();
@@ -1001,9 +1003,9 @@ public class Editor {
DragLocalState localState = new DragLocalState(mTextView, start, end);
mTextView.startDrag(data, getTextThumbnailBuilder(selectedText), localState,
View.DRAG_FLAG_GLOBAL);
stopSelectionActionMode();
stopTextActionMode();
} else {
stopSelectionActionMode();
stopTextActionMode();
selectCurrentWordAndStartDrag();
}
handled = true;
@@ -1101,12 +1103,12 @@ public class Editor {
final int selStart = mTextView.getSelectionStart();
final int selEnd = mTextView.getSelectionEnd();
hideControllers();
stopSelectionActionMode();
stopTextActionMode();
Selection.setSelection((Spannable) mTextView.getText(), selStart, selEnd);
} else {
if (mTemporaryDetach) mPreserveDetachedSelection = true;
hideControllers();
stopSelectionActionMode();
stopTextActionMode();
if (mTemporaryDetach) mPreserveDetachedSelection = false;
downgradeEasyCorrectionSpans();
}
@@ -1149,7 +1151,7 @@ public class Editor {
// We do not hide the span controllers, since they can be added when a new text is
// inserted into the text view (voice IME).
hideCursorControllers();
stopSelectionActionMode();
stopTextActionMode();
}
private int getLastTapPosition() {
@@ -1216,7 +1218,7 @@ public class Editor {
}
private void updateFloatingToolbarVisibility(MotionEvent event) {
if (mSelectionActionMode != null) {
if (mTextActionMode != null) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_MOVE:
hideFloatingToolbar();
@@ -1229,7 +1231,7 @@ public class Editor {
}
private void hideFloatingToolbar() {
if (mSelectionActionMode != null) {
if (mTextActionMode != null) {
mTextView.removeCallbacks(mShowFloatingToolbar);
// Delay the "hide" a little bit just in case a "show" will happen almost immediately.
mTextView.postDelayed(mHideFloatingToolbar, 100);
@@ -1237,7 +1239,7 @@ public class Editor {
}
private void showFloatingToolbar() {
if (mSelectionActionMode != null) {
if (mTextActionMode != null) {
mTextView.removeCallbacks(mHideFloatingToolbar);
// Delay "show" so it doesn't interfere with click confirmations
// or double-clicks that could "dismiss" the floating toolbar.
@@ -1701,26 +1703,20 @@ public class Editor {
/**
* @return true if the selection mode was actually started.
*/
private boolean startSelectionActionModeWithoutSelection() {
private boolean startInsertionActionMode() {
if (mInsertionActionModeRunnable != null) {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
if (extractedTextModeWillBeStarted()) {
// Cancel the single tap delayed runnable.
if (mSelectionModeWithoutSelectionRunnable != null) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
}
return false;
}
stopTextActionMode();
if (mSelectionActionMode != null) {
// Selection action mode is already started
// TODO: revisit invocations to minimize this case.
mSelectionActionMode.invalidate();
return false;
}
ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
mSelectionActionMode = mTextView.startActionMode(
ActionMode.Callback actionModeCallback =
new TextActionModeCallback(false /* hasSelection */);
mTextActionMode = mTextView.startActionMode(
actionModeCallback, ActionMode.TYPE_FLOATING);
return mSelectionActionMode != null;
return mTextActionMode != null;
}
/**
@@ -1730,8 +1726,8 @@ public class Editor {
*
* @return true if the selection mode was actually started.
*/
boolean startSelectionActionModeWithSelection() {
boolean selectionStarted = startSelectionActionModeWithSelectionInternal();
boolean startSelectionActionMode() {
boolean selectionStarted = startSelectionActionModeInternal();
if (selectionStarted) {
getSelectionController().show();
} else if (getInsertionController() != null) {
@@ -1749,13 +1745,13 @@ public class Editor {
private boolean selectCurrentWordAndStartDrag() {
if (extractedTextModeWillBeStarted()) {
// Cancel the single tap delayed runnable.
if (mSelectionModeWithoutSelectionRunnable != null) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
if (mInsertionActionModeRunnable != null) {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
return false;
}
if (mSelectionActionMode != null) {
mSelectionActionMode.finish();
if (mTextActionMode != null) {
mTextActionMode.finish();
}
if (!checkFieldAndSelectCurrentWord()) {
return false;
@@ -1784,10 +1780,10 @@ public class Editor {
return true;
}
private boolean startSelectionActionModeWithSelectionInternal() {
if (mSelectionActionMode != null) {
private boolean startSelectionActionModeInternal() {
if (mTextActionMode != null) {
// Selection action mode is already started
mSelectionActionMode.invalidate();
mTextActionMode.invalidate();
return false;
}
@@ -1800,12 +1796,13 @@ public class Editor {
// Do not start the action mode when extracted text will show up full screen, which would
// immediately hide the newly created action bar and would be visually distracting.
if (!willExtract) {
ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
mSelectionActionMode = mTextView.startActionMode(
ActionMode.Callback actionModeCallback =
new TextActionModeCallback(true /* hasSelection */);
mTextActionMode = mTextView.startActionMode(
actionModeCallback, ActionMode.TYPE_FLOATING);
}
final boolean selectionStarted = mSelectionActionMode != null || willExtract;
final boolean selectionStarted = mTextActionMode != null || willExtract;
if (selectionStarted && !mTextView.isTextSelectable() && mShowSoftInputOnFocus) {
// Show the IME to be able to replace text, except when selecting non editable text.
final InputMethodManager imm = InputMethodManager.peekInstance();
@@ -1906,7 +1903,7 @@ public class Editor {
void onTouchUpEvent(MotionEvent event) {
boolean selectAllGotFocus = mSelectAllOnFocus && mTextView.didTouchFocusSelect();
hideControllers();
stopSelectionActionMode();
stopTextActionMode();
CharSequence text = mTextView.getText();
if (!selectAllGotFocus && text.length() > 0) {
// Move cursor
@@ -1920,8 +1917,8 @@ public class Editor {
if (!extractedTextModeWillBeStarted()) {
if (isCursorInsideEasyCorrectionSpan()) {
// Cancel the single tap delayed runnable.
if (mSelectionModeWithoutSelectionRunnable != null) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
if (mInsertionActionModeRunnable != null) {
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
mShowSuggestionRunnable = new Runnable() {
@@ -1939,10 +1936,10 @@ public class Editor {
}
}
protected void stopSelectionActionMode() {
if (mSelectionActionMode != null) {
protected void stopTextActionMode() {
if (mTextActionMode != null) {
// This will hide the mSelectionModifierCursorController
mSelectionActionMode.finish();
mTextActionMode.finish();
}
}
@@ -2027,7 +2024,7 @@ public class Editor {
mSuggestionsPopupWindow = new SuggestionsPopupWindow();
}
hideControllers();
stopSelectionActionMode();
stopTextActionMode();
mSuggestionsPopupWindow.show();
}
@@ -2035,8 +2032,8 @@ public class Editor {
if (mPositionListener != null) {
mPositionListener.onScrollChanged();
}
if (mSelectionActionMode != null) {
mSelectionActionMode.invalidateContentRect();
if (mTextActionMode != null) {
mTextActionMode.invalidateContentRect();
}
}
@@ -3087,45 +3084,51 @@ public class Editor {
}
/**
* An ActionMode Callback class that is used to provide actions while in text selection mode.
* An ActionMode Callback class that is used to provide actions while in text insertion or
* selection mode.
*
* The default callback provides a subset of Select All, Cut, Copy and Paste actions, depending
* on which of these this TextView supports.
* The default callback provides a subset of Select All, Cut, Copy, Paste, Share and Replace
* actions, depending on which of these this TextView supports and the current selection.
*/
private class SelectionActionModeCallback extends ActionMode.Callback2 {
private class TextActionModeCallback extends ActionMode.Callback2 {
private final Path mSelectionPath = new Path();
private final RectF mSelectionBounds = new RectF();
private final boolean mHasSelection;
private int mSelectionHandleHeight;
private int mInsertionHandleHeight;
private int mHandleHeight;
public SelectionActionModeCallback() {
SelectionModifierCursorController selectionController = getSelectionController();
if (selectionController.mStartHandle == null) {
// As these are for initializing selectionController, hide() must be called.
selectionController.initDrawables();
selectionController.initHandles();
selectionController.hide();
}
mSelectionHandleHeight = Math.max(
mSelectHandleLeft.getMinimumHeight(), mSelectHandleRight.getMinimumHeight());
InsertionPointCursorController insertionController = getInsertionController();
if (insertionController != null) {
insertionController.getHandle();
mInsertionHandleHeight = mSelectHandleCenter.getMinimumHeight();
public TextActionModeCallback(boolean hasSelection) {
mHasSelection = hasSelection;
if (mHasSelection) {
SelectionModifierCursorController selectionController = getSelectionController();
if (selectionController.mStartHandle == null) {
// As these are for initializing selectionController, hide() must be called.
selectionController.initDrawables();
selectionController.initHandles();
selectionController.hide();
}
mHandleHeight = Math.max(
mSelectHandleLeft.getMinimumHeight(),
mSelectHandleRight.getMinimumHeight());
} else {
InsertionPointCursorController insertionController = getInsertionController();
if (insertionController != null) {
insertionController.getHandle();
mHandleHeight = mSelectHandleCenter.getMinimumHeight();
}
}
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle(mTextView.getContext().getString(
com.android.internal.R.string.textSelectionCABTitle));
mode.setTitle(null);
mode.setSubtitle(null);
mode.setTitleOptionalHint(true);
populateMenuWithItems(menu);
if (mCustomSelectionActionModeCallback != null) {
if (!mCustomSelectionActionModeCallback.onCreateActionMode(mode, menu)) {
Callback customCallback = getCustomCallback();
if (customCallback != null) {
if (!customCallback.onCreateActionMode(mode, menu)) {
// The custom mode can choose to cancel the action mode
return false;
}
@@ -3141,6 +3144,12 @@ public class Editor {
}
}
private Callback getCustomCallback() {
return mHasSelection
? mCustomSelectionActionModeCallback
: mCustomInsertionActionModeCallback;
}
private void populateMenuWithItems(Menu menu) {
if (mTextView.canCut()) {
menu.add(0, TextView.ID_CUT, 0, com.android.internal.R.string.cut).
@@ -3203,8 +3212,9 @@ public class Editor {
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
updateReplaceItem(menu);
if (mCustomSelectionActionModeCallback != null) {
return mCustomSelectionActionModeCallback.onPrepareActionMode(mode, menu);
Callback customCallback = getCustomCallback();
if (customCallback != null) {
return customCallback.onPrepareActionMode(mode, menu);
}
return true;
}
@@ -3230,8 +3240,8 @@ public class Editor {
item.getIntent(), TextView.PROCESS_TEXT_REQUEST_CODE);
return true;
}
if (mCustomSelectionActionModeCallback != null &&
mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
Callback customCallback = getCustomCallback();
if (customCallback != null && customCallback.onActionItemClicked(mode, item)) {
return true;
}
return mTextView.onTextContextMenuItem(item.getItemId());
@@ -3239,8 +3249,9 @@ public class Editor {
@Override
public void onDestroyActionMode(ActionMode mode) {
if (mCustomSelectionActionModeCallback != null) {
mCustomSelectionActionModeCallback.onDestroyActionMode(mode);
Callback customCallback = getCustomCallback();
if (customCallback != null) {
customCallback.onDestroyActionMode(mode);
}
/*
@@ -3259,7 +3270,7 @@ public class Editor {
mSelectionModifierCursorController.resetTouchOffsets();
}
mSelectionActionMode = null;
mTextActionMode = null;
}
@Override
@@ -3274,7 +3285,7 @@ public class Editor {
mTextView.getLayout().getSelectionPath(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(), mSelectionPath);
mSelectionPath.computeBounds(mSelectionBounds, true);
mSelectionBounds.bottom += mSelectionHandleHeight;
mSelectionBounds.bottom += mHandleHeight;
} else if (mCursorCount == 2) {
// We have a split cursor. In this case, we take the rectangle that includes both
// parts of the cursor to ensure we don't obscure either of them.
@@ -3285,7 +3296,7 @@ public class Editor {
Math.min(firstCursorBounds.top, secondCursorBounds.top),
Math.max(firstCursorBounds.right, secondCursorBounds.right),
Math.max(firstCursorBounds.bottom, secondCursorBounds.bottom)
+ mInsertionHandleHeight);
+ mHandleHeight);
} else {
// We have a single cursor.
int line = mTextView.getLayout().getLineForOffset(mTextView.getSelectionStart());
@@ -3295,7 +3306,7 @@ public class Editor {
primaryHorizontal,
mTextView.getLayout().getLineTop(line),
primaryHorizontal + 1,
mTextView.getLayout().getLineTop(line + 1) + mInsertionHandleHeight);
mTextView.getLayout().getLineTop(line + 1) + mHandleHeight);
}
// Take TextView's padding and scroll into account.
int textHorizontalOffset = mTextView.viewportToContentHorizontalOffset();
@@ -3847,25 +3858,25 @@ public class Editor {
SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime;
// Cancel the single tap delayed runnable.
if (mSelectionModeWithoutSelectionRunnable != null
if (mInsertionActionModeRunnable != null
&& (mDoubleTap || isCursorInsideEasyCorrectionSpan())) {
mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
mTextView.removeCallbacks(mInsertionActionModeRunnable);
}
// Prepare and schedule the single tap runnable to run exactly after the double tap
// timeout has passed.
if (!mDoubleTap && !isCursorInsideEasyCorrectionSpan()
&& (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
if (mSelectionModeWithoutSelectionRunnable == null) {
mSelectionModeWithoutSelectionRunnable = new Runnable() {
if (mInsertionActionModeRunnable == null) {
mInsertionActionModeRunnable = new Runnable() {
public void run() {
startSelectionActionModeWithoutSelection();
startInsertionActionMode();
}
};
}
mTextView.postDelayed(
mSelectionModeWithoutSelectionRunnable,
mInsertionActionModeRunnable,
ViewConfiguration.getDoubleTapTimeout() + 1);
}
@@ -3934,15 +3945,15 @@ public class Editor {
if (distanceSquared < touchSlop * touchSlop) {
// Tapping on the handle toggles the selection action mode.
if (mSelectionActionMode != null) {
mSelectionActionMode.finish();
if (mTextActionMode != null) {
mTextActionMode.finish();
} else {
startSelectionActionModeWithoutSelection();
startInsertionActionMode();
}
}
} else {
if (mSelectionActionMode != null) {
mSelectionActionMode.invalidateContentRect();
if (mTextActionMode != null) {
mTextActionMode.invalidateContentRect();
}
}
hideAfterDelay();
@@ -3972,8 +3983,8 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
if (mSelectionActionMode != null) {
mSelectionActionMode.invalidate();
if (mTextActionMode != null) {
mTextActionMode.invalidate();
}
}
@@ -4024,8 +4035,8 @@ public class Editor {
Selection.setSelection((Spannable) mTextView.getText(), offset,
mTextView.getSelectionEnd());
updateDrawable();
if (mSelectionActionMode != null) {
mSelectionActionMode.invalidate();
if (mTextActionMode != null) {
mTextActionMode.invalidate();
}
}
@@ -4150,8 +4161,8 @@ public class Editor {
public void updateSelection(int offset) {
Selection.setSelection((Spannable) mTextView.getText(),
mTextView.getSelectionStart(), offset);
if (mSelectionActionMode != null) {
mSelectionActionMode.invalidate();
if (mTextActionMode != null) {
mTextActionMode.invalidate();
}
updateDrawable();
}
@@ -4515,7 +4526,7 @@ public class Editor {
mEndHandle.showAtLocation(endOffset);
// No longer the first dragging motion, reset.
startSelectionActionModeWithSelection();
startSelectionActionMode();
mDragAcceleratorActive = false;
mStartOffset = -1;
}

View File

@@ -1481,7 +1481,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
if (mEditor.hasSelectionController()) {
mEditor.startSelectionActionModeWithSelection();
mEditor.startSelectionActionMode();
}
}
}
@@ -5282,7 +5282,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// - onFocusChanged cannot start it when focus is given to a view with selected text (after
// a screen rotation) since layout is not yet initialized at that point.
if (mEditor != null && mEditor.mCreatedWithASelection) {
mEditor.startSelectionActionModeWithSelection();
mEditor.startSelectionActionMode();
mEditor.mCreatedWithASelection = false;
}
@@ -5290,7 +5290,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// ExtractEditText does not call onFocus when it is displayed, and mHasSelectionOnFocus can
// not be set. Do the test here instead.
if (this instanceof ExtractEditText && hasSelection() && mEditor != null) {
mEditor.startSelectionActionModeWithSelection();
mEditor.startSelectionActionMode();
}
unregisterForPreDraw();
@@ -5908,7 +5908,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
boolean isInSelectionMode = mEditor != null && mEditor.mSelectionActionMode != null;
boolean isInSelectionMode = mEditor != null && mEditor.mTextActionMode != null;
if (isInSelectionMode) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
@@ -5923,7 +5923,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
state.handleUpEvent(event);
}
if (event.isTracking() && !event.isCanceled()) {
stopSelectionActionMode();
stopTextActionMode();
return true;
}
}
@@ -6092,8 +6092,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Has to be done on key down (and not on key up) to correctly be intercepted.
case KeyEvent.KEYCODE_BACK:
if (mEditor != null && mEditor.mSelectionActionMode != null) {
stopSelectionActionMode();
if (mEditor != null && mEditor.mTextActionMode != null) {
stopTextActionMode();
return -1;
}
break;
@@ -6423,7 +6423,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// extracted mode will start. Some text is selected though, and will trigger an action mode
// in the extracted view.
mEditor.hideControllers();
stopSelectionActionMode();
stopTextActionMode();
}
/**
@@ -8258,7 +8258,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.onVisibilityChanged(changedView, visibility);
if (mEditor != null && visibility != VISIBLE) {
mEditor.hideControllers();
stopSelectionActionMode();
stopTextActionMode();
}
}
@@ -8976,7 +8976,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Selection.setSelection((Spannable) text, start, end);
// Make sure selection mode is engaged.
if (mEditor != null) {
mEditor.startSelectionActionModeWithSelection();
mEditor.startSelectionActionMode();
}
return true;
}
@@ -9100,12 +9100,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case ID_CUT:
setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
deleteText_internal(min, max);
stopSelectionActionMode();
stopTextActionMode();
return true;
case ID_COPY:
setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
stopSelectionActionMode();
stopTextActionMode();
return true;
case ID_REPLACE:
@@ -9195,14 +9195,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* selection is initiated in this View.
*
* The standard implementation populates the menu with a subset of Select All, Cut, Copy,
* Paste and Share actions, depending on what this View supports.
* Paste, Replace and Share actions, depending on what this View supports.
*
* A custom implementation can add new entries in the default menu in its
* {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
* default actions can also be removed from the menu using
* {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
* {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste} or
* {@link android.R.id#shareText} ids as parameters.
* {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste},
* {@link android.R.id#replaceText} or {@link android.R.id#shareText} ids as parameters.
*
* Returning false from
* {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
@@ -9229,12 +9229,49 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return mEditor == null ? null : mEditor.mCustomSelectionActionModeCallback;
}
/**
* If provided, this ActionMode.Callback will be used to create the ActionMode when text
* insertion is initiated in this View.
*
* The standard implementation populates the menu with a subset of Select All,
* Paste and Replace actions, depending on what this View supports.
*
* A custom implementation can add new entries in the default menu in its
* {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
* default actions can also be removed from the menu using
* {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll},
* {@link android.R.id#paste} or {@link android.R.id#replaceText} ids as parameters.
*
* Returning false from
* {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
* the action mode from being started.
*
* Action click events should be handled by the custom implementation of
* {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
*
* Note that text insertion mode is not started when a TextView receives focus and the
* {@link android.R.attr#selectAllOnFocus} flag has been set.
*/
public void setCustomInsertionActionModeCallback(ActionMode.Callback actionModeCallback) {
createEditorIfNeeded();
mEditor.mCustomInsertionActionModeCallback = actionModeCallback;
}
/**
* Retrieves the value set in {@link #setCustomInsertionActionModeCallback}. Default is null.
*
* @return The current custom insertion callback.
*/
public ActionMode.Callback getCustomInsertionActionModeCallback() {
return mEditor == null ? null : mEditor.mCustomInsertionActionModeCallback;
}
/**
* @hide
*/
protected void stopSelectionActionMode() {
protected void stopTextActionMode() {
if (mEditor != null) {
mEditor.stopSelectionActionMode();
mEditor.stopTextActionMode();
}
}
@@ -9346,7 +9383,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
}
stopSelectionActionMode();
stopTextActionMode();
sLastCutCopyOrTextChangedTime = 0;
}
}
@@ -9359,7 +9396,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
sharingIntent.removeExtra(android.content.Intent.EXTRA_TEXT);
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, selectedText);
getContext().startActivity(Intent.createChooser(sharingIntent, null));
stopSelectionActionMode();
stopTextActionMode();
}
}