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

Commit bc686230 authored by Gilles Debunne's avatar Gilles Debunne
Browse files

Revert "Faster and simpler replace in SSB"

Bug 6300658

This change reveals a weird race condition where sometimes the
text is entered twice. Adding a debugger slows down everything,
and the problem is no longer reproducable. Reverting for now.

This reverts commit ebd9a238.
parent 5713c9cf
Loading
Loading
Loading
Loading
+46 −21
Original line number Diff line number Diff line
@@ -50,8 +50,6 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
    public SpannableStringBuilder(CharSequence text, int start, int end) {
        int srclen = end - start;

        if (srclen < 0) throw new StringIndexOutOfBoundsException();

        int len = ArrayUtils.idealCharArraySize(srclen + 1);
        mText = new char[len];
        mGapStart = srclen;
@@ -155,7 +153,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
        if (where == mGapStart)
            return;

        boolean atEnd = (where == length());
        boolean atend = (where == length());

        if (where < mGapStart) {
            int overlap = mGapStart - where;
@@ -181,7 +179,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
            else if (start == where) {
                int flag = (mSpanFlags[i] & START_MASK) >> START_SHIFT;

                if (flag == POINT || (atEnd && flag == PARAGRAPH))
                if (flag == POINT || (atend && flag == PARAGRAPH))
                    start += mGapLength;
            }

@@ -192,7 +190,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
            else if (end == where) {
                int flag = (mSpanFlags[i] & END_MASK);

                if (flag == POINT || (atEnd && flag == PARAGRAPH))
                if (flag == POINT || (atend && flag == PARAGRAPH))
                    end += mGapLength;
            }

@@ -421,26 +419,53 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
        TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
        sendBeforeTextChanged(textWatchers, start, origLen, newLen);

        // Try to keep the cursor / selection at the same relative position during
        // a text replacement. If replaced or replacement text length is zero, this
        // is already taken care of.
        boolean adjustSelection = origLen != 0 && newLen != 0;
        int selstart = 0;
        int selend = 0;
        if (adjustSelection) {
            selstart = Selection.getSelectionStart(this);
            selend = Selection.getSelectionEnd(this);
        }
        if (origLen == 0 || newLen == 0) {
            change(start, end, tb, tbstart, tbend);
        } else {
            int selstart = Selection.getSelectionStart(this);
            int selend = Selection.getSelectionEnd(this);

            // XXX just make the span fixups in change() do the right thing
            // instead of this madness!

            checkRange("replace", start, end);
            moveGapTo(end);

        change(start, end, tb, tbstart, tbend);
            if (mGapLength < 2)
                resizeFor(length() + 1);

            for (int i = mSpanCount - 1; i >= 0; i--) {
                if (mSpanStarts[i] == mGapStart)
                    mSpanStarts[i]++;

        if (adjustSelection) {
                if (mSpanEnds[i] == mGapStart)
                    mSpanEnds[i]++;
            }

            mText[mGapStart] = ' ';
            mGapStart++;
            mGapLength--;

            if (mGapLength < 1) {
                new Exception("mGapLength < 1").printStackTrace();
            }

            change(start + 1, start + 1, tb, tbstart, tbend);
            change(start, start + 1, "", 0, 0);
            change(start + newLen, start + newLen + origLen, "", 0, 0);

            /*
             * Special case to keep the cursor in the same position
             * if it was somewhere in the middle of the replaced region.
             * If it was at the start or the end or crossing the whole
             * replacement, it should already be where it belongs.
             * TODO: Is there some more general mechanism that could
             * accomplish this?
             */
            if (selstart > start && selstart < end) {
                long off = selstart - start;

                off = off * newLen / origLen;
                off = off * newLen / (end - start);
                selstart = (int) off + start;

                setSpan(false, Selection.SELECTION_START, selstart, selstart,
@@ -449,7 +474,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
            if (selend > start && selend < end) {
                long off = selend - start;

                off = off * newLen / origLen;
                off = off * newLen / (end - start);
                selend = (int) off + start;

                setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT);