resolved conflicts for merge of ba04dbc6 to master

Change-Id: I175aa21ef01b98b0c3c46aea0b754d14984128b9
This commit is contained in:
Gilles Debunne
2010-10-07 20:46:03 -07:00

View File

@@ -4364,6 +4364,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = true;
// If ALT modifier is held, then we always insert a
// newline character.
if ((event.getMetaState()&KeyEvent.META_ALT_ON) == 0) {
@@ -4396,6 +4397,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
mDPadCenterIsDown = true;
if (shouldAdvanceFocusOnEnter()) {
return 0;
}
@@ -4490,6 +4492,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
mDPadCenterIsDown = false;
/*
* If there is a click listener, just call through to
* super, which will invoke it.
@@ -4510,6 +4513,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = false;
if (mInputContentType != null
&& mInputContentType.onEditorActionListener != null
&& mInputContentType.enterDown) {
@@ -7288,9 +7292,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// Two ints packed in a long
return packRangeInLong(start, end);
}
private static long packRangeInLong(int start, int end) {
return (((long) start) << 32) | end;
}
private static int extractRangeStartFromLong(long range) {
return (int) (range >>> 32);
}
private static int extractRangeEndFromLong(long range) {
return (int) (range & 0x00000000FFFFFFFFL);
}
private void selectCurrentWord() {
// In case selection mode is started after an orientation change or after a select all,
// use the current selection instead of creating one
@@ -7298,67 +7314,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return;
}
int selectionStart, selectionEnd;
int minOffset, maxOffset;
// selectionModifierCursorController is not null at that point
SelectionModifierCursorController selectionModifierCursorController =
((SelectionModifierCursorController) mSelectionModifierCursorController);
int minOffset = selectionModifierCursorController.getMinTouchOffset();
int maxOffset = selectionModifierCursorController.getMaxTouchOffset();
if (minOffset == maxOffset) {
int offset = Math.max(0, Math.min(minOffset, mTransformed.length()));
// Tolerance, number of charaters around tapped position
final int range = 1;
final int max = mTransformed.length() - 1;
// 'Smart' word selection: detect position between words
for (int i = -range; i <= range; i++) {
int index = offset + i;
if (index >= 0 && index <= max) {
if (Character.isSpaceChar(mTransformed.charAt(index))) {
// Select current space
selectionStart = index;
selectionEnd = selectionStart + 1;
// Extend selection to maximum space range
while (selectionStart > 0 &&
Character.isSpaceChar(mTransformed.charAt(selectionStart - 1))) {
selectionStart--;
}
while (selectionEnd < max &&
Character.isSpaceChar(mTransformed.charAt(selectionEnd))) {
selectionEnd++;
}
Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
return;
}
}
}
// 'Smart' word selection: detect position at beginning or end of text.
if (offset <= range) {
Selection.setSelection((Spannable) mText, 0, 0);
return;
}
if (offset >= (max - range)) {
Selection.setSelection((Spannable) mText, max + 1, max + 1);
return;
}
if (mDPadCenterIsDown || mEnterKeyIsDown) {
minOffset = getSelectionStart();
maxOffset = getSelectionEnd();
} else {
// selectionModifierCursorController is not null at that point
SelectionModifierCursorController selectionModifierCursorController =
((SelectionModifierCursorController) mSelectionModifierCursorController);
minOffset = selectionModifierCursorController.getMinTouchOffset();
maxOffset = selectionModifierCursorController.getMaxTouchOffset();
}
int selectionStart, selectionEnd;
long wordLimits = getWordLimitsAt(minOffset);
if (wordLimits >= 0) {
selectionStart = (int) (wordLimits >>> 32);
selectionStart = extractRangeStartFromLong(wordLimits);
} else {
selectionStart = Math.max(minOffset - 5, 0);
}
wordLimits = getWordLimitsAt(maxOffset);
if (wordLimits >= 0) {
selectionEnd = (int) (wordLimits & 0x00000000FFFFFFFFL);
selectionEnd = extractRangeEndFromLong(wordLimits);
} else {
selectionEnd = Math.min(maxOffset + 5, mText.length());
}
@@ -7487,7 +7467,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
switch (id) {
case ID_COPY_URL:
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
if (urls.length >= 1) {
ClipData clip = null;
@@ -7513,6 +7492,49 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return false;
}
/**
* Prepare text so that there are not zero or two spaces at beginning and end of region defined
* by [min, max] when replacing this region by paste.
*/
private long prepareSpacesAroundPaste(int min, int max, CharSequence paste) {
// Paste adds/removes spaces before or after insertion as needed.
if (Character.isSpaceChar(paste.charAt(0))) {
if (min > 0 && Character.isSpaceChar(mTransformed.charAt(min - 1))) {
// Two spaces at beginning of paste: remove one
final int originalLength = mText.length();
((Editable) mText).replace(min - 1, min, "");
// Due to filters, there is no garantee that exactly one character was
// removed. Count instead.
final int delta = mText.length() - originalLength;
min += delta;
max += delta;
}
} else {
if (min > 0 && !Character.isSpaceChar(mTransformed.charAt(min - 1))) {
// No space at beginning of paste: add one
final int originalLength = mText.length();
((Editable) mText).replace(min, min, " ");
// Taking possible filters into account as above.
final int delta = mText.length() - originalLength;
min += delta;
max += delta;
}
}
if (Character.isSpaceChar(paste.charAt(paste.length() - 1))) {
if (max < mText.length() && Character.isSpaceChar(mTransformed.charAt(max))) {
// Two spaces at end of paste: remove one
((Editable) mText).replace(max, max + 1, "");
}
} else {
if (max < mText.length() && !Character.isSpaceChar(mTransformed.charAt(max))) {
// No space at end of paste: add one
((Editable) mText).replace(max, max, " ");
}
}
return packRangeInLong(min, max);
}
@Override
public boolean performLongClick() {
if (super.performLongClick()) {
@@ -7704,6 +7726,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
CharSequence paste = clip.getItem(i).coerceToText(getContext());
if (paste != null) {
if (!didfirst) {
long minMax = prepareSpacesAroundPaste(min, max, paste);
min = extractRangeStartFromLong(minMax);
max = extractRangeEndFromLong(minMax);
Selection.setSelection((Spannable) mText, max);
((Editable) mText).replace(min, max, paste);
} else {
@@ -7714,7 +7739,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
stopSelectionActionMode();
}
return true;
case ID_CUT:
@@ -8329,6 +8353,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private CursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
private int mLastTouchOffset = -1;
// 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;
private boolean mEnterKeyIsDown = false;
// Created once and shared by different CursorController helper methods.
// Only one cursor controller is active at any time which prevent race conditions.
private static Rect sCursorControllerTempRect = new Rect();