diff options
| author | 2010-11-30 10:07:41 -0800 | |
|---|---|---|
| committer | 2010-11-30 10:07:41 -0800 | |
| commit | 458f4633b84c0a2303a1dc764dca8dcee803e838 (patch) | |
| tree | 700c6d3dd6568be876753b02253406b843909902 | |
| parent | 84e3916720e430e0d6debfaf5343b8a14fdf1ce4 (diff) | |
| parent | 4ae0f29d26825b468ad9d38ef12a121572410646 (diff) | |
Merge "Dragging inside the same TextView is a move instead of a copy."
| -rw-r--r-- | core/java/android/widget/TextView.java | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index d164d11cdf09..c49deaaeef5f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7761,14 +7761,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener /** * 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. + * Note that if there was two spaces (or more) at that position before, they are kept. We just + * make sure we do not add an extra one from the paste content. */ 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 (paste.length() > 0 && 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, ""); + ((Editable) mText).delete(min - 1, min); // Due to filters, there is no guarantee that exactly one character was // removed. Count instead. final int delta = mText.length() - originalLength; @@ -7787,10 +7789,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - if (Character.isSpaceChar(paste.charAt(paste.length() - 1))) { + if (paste.length() > 0 && 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, ""); + ((Editable) mText).delete(max, max + 1); } } else { if (max < mText.length() && !Character.isSpaceChar(mTransformed.charAt(max))) { @@ -7798,6 +7800,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener ((Editable) mText).replace(max, max, " "); } } + return packRangeInLong(min, max); } @@ -7854,6 +7857,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener CharSequence selectedText = mTransformed.subSequence(start, end); ClipData data = ClipData.newPlainText(null, null, selectedText); startDrag(data, getTextThumbnailBuilder(selectedText), false); + mDragSourcePositions = packRangeInLong(start, end); stopSelectionActionMode(); } else { selectCurrentWord(); @@ -8989,17 +8993,58 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Item item = clipData.getItem(i); content.append(item.coerceToText(TextView.this.mContext)); } + final int offset = getOffset((int) event.getX(), (int) event.getY()); + + if (mDragSourcePositions != -1) { + final int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions); + final int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions); + if (offset >= dragSourceStart && offset < dragSourceEnd) { + // A drop inside the original selection discards the drop. + return true; + } + } + + final int originalLength = mText.length(); long minMax = prepareSpacesAroundPaste(offset, offset, content); int min = extractRangeStartFromLong(minMax); int max = extractRangeEndFromLong(minMax); + Selection.setSelection((Spannable) mText, max); ((Editable) mText).replace(min, max, content); + + if (mDragSourcePositions != -1) { + int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions); + int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions); + if (max <= dragSourceStart) { + // Inserting text before selection has shifted positions + final int shift = mText.length() - originalLength; + dragSourceStart += shift; + dragSourceEnd += shift; + } + + // Delete original selection + ((Editable) mText).delete(dragSourceStart, dragSourceEnd); + + // Make sure we do not leave two adjacent spaces. + if ((dragSourceStart == 0 || + Character.isSpaceChar(mTransformed.charAt(dragSourceStart - 1))) && + (dragSourceStart == mText.length() || + Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) { + final int pos = dragSourceStart == mText.length() ? + dragSourceStart - 1 : dragSourceStart; + ((Editable) mText).delete(pos, pos + 1); + } + } + return true; } - case DragEvent.ACTION_DRAG_EXITED: case DragEvent.ACTION_DRAG_ENDED: + mDragSourcePositions = -1; + return true; + + case DragEvent.ACTION_DRAG_EXITED: default: return true; } @@ -9166,6 +9211,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private InputFilter[] mFilters = NO_FILTERS; private static final Spanned EMPTY_SPANNED = new SpannedString(""); private static int DRAG_THUMBNAIL_MAX_TEXT_LENGTH = 20; + // A packed range containing the drag source if it occured in that TextView. -1 otherwise. + private long mDragSourcePositions = -1; // System wide time for last cut or copy action. private static long sLastCutOrCopyTime; } |