diff options
| author | 2011-10-03 18:28:59 -0700 | |
|---|---|---|
| committer | 2011-10-03 18:34:28 -0700 | |
| commit | 8f3105ff9bc331a3d664cf06793d47f4763db3c5 (patch) | |
| tree | 524594527c54cb9f3cb082a6ae03d1c0c402983f | |
| parent | 2588a07730ff511329c87b5f61b20419b2443d48 (diff) | |
5402566: Copy/cut icons do not appear if the text is Japanese only
When the word iterator return an empty range, select an arbitrary
character so that cut/copy icons are available.
Change-Id: I16e5a3c7f10886db967d870706da7f2d690af013
| -rw-r--r-- | core/java/android/widget/TextView.java | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index f833bb5590cf..478158f9b2a5 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8925,10 +8925,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // If a URLSpan (web address, email, phone...) is found at that position, select it. URLSpan[] urlSpans = ((Spanned) mText).getSpans(minOffset, maxOffset, URLSpan.class); - if (urlSpans.length == 1) { - URLSpan url = urlSpans[0]; - selectionStart = ((Spanned) mText).getSpanStart(url); - selectionEnd = ((Spanned) mText).getSpanEnd(url); + if (urlSpans.length >= 1) { + URLSpan urlSpan = urlSpans[0]; + selectionStart = ((Spanned) mText).getSpanStart(urlSpan); + selectionEnd = ((Spanned) mText).getSpanEnd(urlSpan); } else { final int shift = prepareWordIterator(minOffset, maxOffset); @@ -8939,10 +8939,42 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener selectionEnd = mWordIterator.getEnd(maxOffset - shift); if (selectionEnd == BreakIterator.DONE) return false; selectionEnd += shift; + + if (selectionStart == selectionEnd) { + // Possible when the word iterator does not properly handle the text's language + long range = getCharRange(selectionStart); + selectionStart = extractRangeStartFromLong(range); + selectionEnd = extractRangeEndFromLong(range); + } } Selection.setSelection((Spannable) mText, selectionStart, selectionEnd); - return true; + return selectionEnd > selectionStart; + } + + private long getCharRange(int offset) { + final int textLength = mText.length(); + if (offset + 1 < textLength) { + final char currentChar = mText.charAt(offset); + final char nextChar = mText.charAt(offset + 1); + if (Character.isSurrogatePair(currentChar, nextChar)) { + return packRangeInLong(offset, offset + 2); + } + } + if (offset < textLength) { + return packRangeInLong(offset, offset + 1); + } + if (offset - 2 >= 0) { + final char previousChar = mText.charAt(offset - 1); + final char previousPreviousChar = mText.charAt(offset - 2); + if (Character.isSurrogatePair(previousPreviousChar, previousChar)) { + return packRangeInLong(offset - 2, offset); + } + } + if (offset - 1 >= 0) { + return packRangeInLong(offset - 1, offset); + } + return packRangeInLong(offset, offset); } int prepareWordIterator(int start, int end) { @@ -9330,7 +9362,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Start a new selection if (!handled) { - handled = startSelectionActionMode(); + vibrate = handled = startSelectionActionMode(); } if (vibrate) { @@ -10166,8 +10198,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (!hasSelection()) { // There may already be a selection on device rotation - boolean currentWordSelected = selectCurrentWord(); - if (!currentWordSelected) { + if (!selectCurrentWord()) { // No word found under cursor or text selection not permitted. return false; } |