Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 202ef9e8 authored by Gilles Debunne's avatar Gilles Debunne Committed by Android (Google) Code Review
Browse files

Merge "AutoLink identified spans are selected when long pressed."

parents 8c972f2c 4dfe0863
Loading
Loading
Loading
Loading
+58 −29
Original line number Diff line number Diff line
@@ -7690,25 +7690,25 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        if (hasPasswordTransformationMethod()) {
            // selectCurrentWord is not available on a password field and would return an
            // arbitrary 10-charater selection around pressed position. Select all instead.
            // Note that cut/copy menu entries are not available for passwords.
            // This is however useful to delete or paste to replace the entire content.
            // Cut/copy menu entries are not available for passwords, but being able to select all
            // is however useful to delete or paste to replace the entire content.
            selectAll();
            return;
        }

        int minOffset, maxOffset;

        if (mContextMenuTriggeredByKey) {
            minOffset = getSelectionStart();
            maxOffset = getSelectionEnd();
        } else {
            SelectionModifierCursorController selectionController = getSelectionController();
            minOffset = selectionController.getMinTouchOffset();
            maxOffset = selectionController.getMaxTouchOffset();
        }
        long lastTouchOffset = getLastTouchOffsets();
        final int minOffset = extractRangeStartFromLong(lastTouchOffset);
        final int maxOffset = extractRangeEndFromLong(lastTouchOffset);

        int selectionStart, selectionEnd;

        // 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);
        } else {
            long wordLimits = getWordLimitsAt(minOffset);
            if (wordLimits >= 0) {
                selectionStart = extractRangeStartFromLong(wordLimits);
@@ -7722,10 +7722,26 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            } else {
                selectionEnd = Math.min(maxOffset + 5, mText.length());
            }
        }

        Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
    }

    private long getLastTouchOffsets() {
        int minOffset, maxOffset;

        if (mContextMenuTriggeredByKey) {
            minOffset = getSelectionStart();
            maxOffset = getSelectionEnd();
        } else {
            SelectionModifierCursorController selectionController = getSelectionController();
            minOffset = selectionController.getMinTouchOffset();
            maxOffset = selectionController.getMaxTouchOffset();
        }

        return packRangeInLong(minOffset, maxOffset);
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        if (!isShown()) {
@@ -7779,13 +7795,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        MenuHandler handler = new MenuHandler();

        if (mText instanceof Spanned) {
            int selStart = getSelectionStart();
            int selEnd = getSelectionEnd();

            int min = Math.min(selStart, selEnd);
            int max = Math.max(selStart, selEnd);
            long lastTouchOffset = getLastTouchOffsets();
            final int selStart = extractRangeStartFromLong(lastTouchOffset);
            final int selEnd = extractRangeEndFromLong(lastTouchOffset);

            URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
            URLSpan[] urls = ((Spanned) mText).getSpans(selStart, selEnd, URLSpan.class);
            if (urls.length > 0) {
                menu.add(0, ID_COPY_URL, 0, com.android.internal.R.string.copyUrl).
                        setOnMenuItemClickListener(handler);
@@ -7869,10 +7883,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                        setPrimaryClip(clip);
                    }
                }
                stopSelectionActionMode();
                return true;

            case ID_SELECTION_MODE:
                if (mSelectionActionMode != null) {
                    // Selection mode is already started, simply change selected part.
                    updateSelectedRegion();
                } else {
                    startSelectionActionMode();
                }
                return true;
            }

@@ -7993,9 +8013,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                startDrag(data, getTextThumbnailBuilder(selectedText), false, localState);
                stopSelectionActionMode();
            } else {
                // Start a new selection at current position, keep selectionAction mode on
                selectCurrentWord();
                getSelectionController().show();
                updateSelectedRegion();
            }
            performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            mDiscardNextActionUp = true;
@@ -8012,6 +8030,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return false;
    }

    /**
     * When selection mode is already started, this method simply updates the selected part of text
     * to the text under the finger.
     */
    private void updateSelectedRegion() {
        // Start a new selection at current position, keep selectionAction mode on
        selectCurrentWord();
        // Updates handles' positions
        getSelectionController().show();
    }

    private boolean touchPositionIsInSelection() {
        int selectionStart = getSelectionStart();
        int selectionEnd = getSelectionEnd();