Loading core/java/android/text/SpannableStringBuilder.java +21 −46 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ 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; Loading Loading @@ -153,7 +155,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; Loading @@ -179,7 +181,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; } Loading @@ -190,7 +192,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; } Loading Loading @@ -419,53 +421,26 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class); sendBeforeTextChanged(textWatchers, start, origLen, newLen); 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); if (mGapLength < 2) resizeFor(length() + 1); for (int i = mSpanCount - 1; i >= 0; i--) { if (mSpanStarts[i] == mGapStart) mSpanStarts[i]++; if (mSpanEnds[i] == mGapStart) mSpanEnds[i]++; // 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); } mText[mGapStart] = ' '; mGapStart++; mGapLength--; if (mGapLength < 1) { new Exception("mGapLength < 1").printStackTrace(); } checkRange("replace", start, end); change(start + 1, start + 1, tb, tbstart, tbend); change(start, start + 1, "", 0, 0); change(start + newLen, start + newLen + origLen, "", 0, 0); change(start, end, tb, tbstart, tbend); /* * 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 (adjustSelection) { if (selstart > start && selstart < end) { long off = selstart - start; off = off * newLen / (end - start); off = off * newLen / origLen; selstart = (int) off + start; setSpan(false, Selection.SELECTION_START, selstart, selstart, Loading @@ -474,7 +449,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selend > start && selend < end) { long off = selend - start; off = off * newLen / (end - start); off = off * newLen / origLen; selend = (int) off + start; setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT); Loading Loading
core/java/android/text/SpannableStringBuilder.java +21 −46 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ 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; Loading Loading @@ -153,7 +155,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; Loading @@ -179,7 +181,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; } Loading @@ -190,7 +192,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; } Loading Loading @@ -419,53 +421,26 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class); sendBeforeTextChanged(textWatchers, start, origLen, newLen); 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); if (mGapLength < 2) resizeFor(length() + 1); for (int i = mSpanCount - 1; i >= 0; i--) { if (mSpanStarts[i] == mGapStart) mSpanStarts[i]++; if (mSpanEnds[i] == mGapStart) mSpanEnds[i]++; // 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); } mText[mGapStart] = ' '; mGapStart++; mGapLength--; if (mGapLength < 1) { new Exception("mGapLength < 1").printStackTrace(); } checkRange("replace", start, end); change(start + 1, start + 1, tb, tbstart, tbend); change(start, start + 1, "", 0, 0); change(start + newLen, start + newLen + origLen, "", 0, 0); change(start, end, tb, tbstart, tbend); /* * 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 (adjustSelection) { if (selstart > start && selstart < end) { long off = selstart - start; off = off * newLen / (end - start); off = off * newLen / origLen; selstart = (int) off + start; setSpan(false, Selection.SELECTION_START, selstart, selstart, Loading @@ -474,7 +449,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable if (selend > start && selend < end) { long off = selend - start; off = off * newLen / (end - start); off = off * newLen / origLen; selend = (int) off + start; setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT); Loading