Java Code Examples for android.text.TextUtils#concat()

The following examples show how to use android.text.TextUtils#concat() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: SocialSDKAndroid   File: WXHandler.java    License: Apache License 2.0 6 votes vote down vote up
protected void onAuthCallback(SendAuth.Resp resp) {
    switch (resp.errCode) {
        case BaseResp.ErrCode.ERR_OK:       //授权成功
            Map<String, String> data = new HashMap<String, String>();
            data.put("code", resp.code);
            this.mAuthListener.onComplete(PlatformType.WEIXIN, data);
            break;

        case BaseResp.ErrCode.ERR_USER_CANCEL:      //授权取消
            if(this.mAuthListener != null) {
                this.mAuthListener.onCancel(PlatformType.WEIXIN);
            }
            break;

        default:    //授权失败
            CharSequence err = TextUtils.concat(new CharSequence[]{"weixin auth error (", String.valueOf(resp.errCode), "):", resp.errStr});
            if(mAuthListener != null) {
                mAuthListener.onError(PlatformType.WEIXIN, err.toString());
            }
            break;
    }
}
 
Example 2
/**
 * Create a full colored sector trailer (representing the last block of
 * every sector).
 * @param data Block data as hex string (16 Byte, 32 Chars.).
 * @return A full colored string.
 */
private SpannableString colorSectorTrailer(String data) {
    // Get sector trailer colors.
    int colorKeyA = getResources().getColor(
            R.color.light_green);
    int colorKeyB = getResources().getColor(
            R.color.dark_green);
    int colorAC = getResources().getColor(
            R.color.orange);
    try {
        SpannableString keyA = Common.colorString(
                data.substring(0, 12), colorKeyA);
        SpannableString keyB = Common.colorString(
                data.substring(20), colorKeyB);
        SpannableString ac = Common.colorString(
                data.substring(12, 20), colorAC);
        return new SpannableString(
                TextUtils.concat(keyA, ac, keyB));
    } catch (IndexOutOfBoundsException e) {
        Log.d(LOG_TAG, "Error while coloring " +
                "sector trailer");
    }
    return new SpannableString(data);
}
 
Example 3
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    CharSequence returnStr = source;
    String curStr = dest.subSequence(dstart, dend).toString();
    String newStr = source.toString();
    int length = end - start;
    int dlength = dend - dstart;
    if (dlength > 0 && length == 0) {
        // Case: Remove chars, Simple
        returnStr = TextListener.this.removeStr(dest.subSequence(dstart, dend), dstart);
    } else if (length > 0 && dlength == 0) {
        // Case: Insert chars, Simple
        returnStr = TextListener.this.insertStr(source.subSequence(start, end), dstart);
    } else if (curStr.length() > newStr.length()) {
        // Case: Remove string or replace
        if (curStr.startsWith(newStr)) {
            // Case: Insert chars, by append
            returnStr = TextUtils.concat(curStr.subSequence(0, newStr.length()), TextListener.this.removeStr(curStr.subSequence(newStr.length(), curStr.length()), dstart + curStr.length()));
        } else {
            // Case Replace chars.
            returnStr = TextListener.this.updateStr(curStr, dstart, newStr);
        }
    } else if (curStr.length() < newStr.length()) {
        // Case: Append String or rrepace.
        if (newStr.startsWith(curStr)) {
            // Addend, Insert
            returnStr = TextUtils.concat(curStr, TextListener.this.insertStr(newStr.subSequence(curStr.length(), newStr.length()), dstart + curStr.length()));
        } else {
            returnStr = TextListener.this.updateStr(curStr, dstart, newStr);
        }
    } else {
        // No update os str...
    }

    // If the return value is same as the source values, return the source value.
    return returnStr;
}
 
Example 4
private CharSequence parseFormatting(Element bodyLine, String currentBoard, String resto, FragmentManager fragmentManager, InfiniteDbHelper infiniteDbHelper){
    CharSequence parsedText = "";
    for (Node childNode : bodyLine.childNodes()){
        if (childNode instanceof TextNode){
            parsedText = TextUtils.concat(parsedText, parseNormalText(new SpannableString(((TextNode) childNode).text())));
        } else if (childNode instanceof Element){
            Element childElement = (Element) childNode;
            switch(childElement.tagName()){
                default:
                    parsedText = TextUtils.concat(parsedText, parseNormalText(new SpannableString(childElement.text())));
                    break;
                case "span":
                    CharSequence spanText = parseSpanText(childElement);
                    parsedText = TextUtils.concat(parsedText, spanText);
                    break;
                case "em":
                    parsedText = TextUtils.concat(parsedText, parseItalicText(new SpannableString(childElement.text())));
                    break;
                case "strong":
                    parsedText = TextUtils.concat(parsedText, parseBoldText(new SpannableString(childElement.text())));
                    break;
                case "u":
                    parsedText = TextUtils.concat(parsedText, parseUnderlineText(new SpannableString(childElement.text())));
                    break;
                case "s":
                    parsedText = TextUtils.concat(parsedText, parseStrikethroughText(new SpannableString(childElement.text())));
                    break;
                case "a":
                    parsedText = TextUtils.concat(parsedText, parseAnchorText(childElement, currentBoard, resto, fragmentManager, infiniteDbHelper));
            }
        }
    }
    return parsedText;
}
 
Example 5
Source Project: homeassist   File: Changelog.java    License: Apache License 2.0 5 votes vote down vote up
public CharSequence getChangelog(Context context) {
        CharSequence result = "";
        for (int i = 0; i < logs.size(); i++) {
            Log.d("YouQi", logs.get(i));
            result = TextUtils.concat(result, CommonUtil.getSpanText(context, " - " + logs.get(i), R.color.md_blue_grey_500, null), i == (logs.size() - 1) ? "" : "\n");
        }
//        Spannable subString = new SpannableString(text);
//        subString.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(context.getResources(), R.color.colorPrimary, null)), 0, subString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//        response = TextUtils.concat(response, subString);

        return result;
    }
 
Example 6
Source Project: litho   File: TextSpec.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Truncates text which is too long and appends the given custom ellipsis CharSequence to the end
 * of the visible text.
 *
 * @param text Text to truncate
 * @param customEllipsisText Text to append to the end to indicate truncation happened
 * @param newLayout A Layout object populated with measurement information for this text
 * @param ellipsizedLineNumber The line number within the text at which truncation occurs (i.e.
 *     the last visible line).
 * @return The provided text truncated in such a way that the 'customEllipsisText' can appear at
 *     the end.
 */
private static CharSequence truncateText(
    CharSequence text,
    CharSequence customEllipsisText,
    Layout newLayout,
    int ellipsizedLineNumber,
    float layoutWidth) {
  Rect bounds = new Rect();
  newLayout
      .getPaint()
      .getTextBounds(customEllipsisText.toString(), 0, customEllipsisText.length(), bounds);
  // Identify the X position at which to truncate the final line:
  // Note: The left position of the line is needed for the case of RTL text.
  final float ellipsisTarget =
      layoutWidth - bounds.width() + newLayout.getLineLeft(ellipsizedLineNumber);
  // Get character offset number corresponding to that X position:
  int ellipsisOffset = newLayout.getOffsetForHorizontal(ellipsizedLineNumber, ellipsisTarget);
  if (ellipsisOffset > 0) {
    // getOffsetForHorizontal returns the closest character, but we need to guarantee no
    // truncation, so subtract 1 from the result:
    ellipsisOffset -= 1;

    // Ensure that we haven't chosen an ellipsisOffset that's past the end of the ellipsis start.
    // This can occur in several cases, including when the width of the customEllipsisText is less
    // than the width of the default ellipsis character, and when in RTL mode and there is
    // whitespace to the left of the text. In these cases, getOffsetForHorizontal will return the
    // end of the string because our ellipsisTarget was in the middle of the ellipsis character.
    if (newLayout.getEllipsisCount(ellipsizedLineNumber) > 0) {
      final int ellipsisStart =
          newLayout.getLineStart(ellipsizedLineNumber)
              + newLayout.getEllipsisStart(ellipsizedLineNumber);
      if (ellipsisOffset > ellipsisStart) {
        ellipsisOffset = ellipsisStart;
      }
    }
    return TextUtils.concat(text.subSequence(0, ellipsisOffset), customEllipsisText);
  } else {
    return text;
  }
}
 
Example 7
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    CharSequence returnStr = source;
    String curStr = dest.subSequence(dstart, dend).toString();
    String newStr = source.toString();
    int length = end - start;
    int dlength = dend - dstart;
    if (dlength > 0 && length == 0) {
        // Case: Remove chars, Simple
        returnStr = TextListener.this.removeStr(dest.subSequence(dstart, dend), dstart);
    } else if (length > 0 && dlength == 0) {
        // Case: Insert chars, Simple
        returnStr = TextListener.this.insertStr(source.subSequence(start, end), dstart);
    } else if (curStr.length() > newStr.length()) {
        // Case: Remove string or replace
        if (curStr.startsWith(newStr)) {
            // Case: Insert chars, by append
            returnStr = TextUtils.concat(curStr.subSequence(0, newStr.length()), TextListener.this.removeStr(curStr.subSequence(newStr.length(), curStr.length()), dstart + curStr.length()));
        } else {
            // Case Replace chars.
            returnStr = TextListener.this.updateStr(curStr, dstart, newStr);
        }
    } else if (curStr.length() < newStr.length()) {
        // Case: Append String or rrepace.
        if (newStr.startsWith(curStr)) {
            // Addend, Insert
            returnStr = TextUtils.concat(curStr, TextListener.this.insertStr(newStr.subSequence(curStr.length(), newStr.length()), dstart + curStr.length()));
        } else {
            returnStr = TextListener.this.updateStr(curStr, dstart, newStr);
        }
    } else {
        // No update os str...
    }

    // If the return value is same as the source values, return the source value.
    return returnStr;
}
 
Example 8
/**
 * Uses the given string array to create a text paragraph. The strings are separated by bullet
 * characters.
 *
 * @param strings The string array to use for the text paragraph
 * @return a charSequence, which can directly be applied to a textView
 */
static public CharSequence createBulletParagraph(CharSequence[] strings){

    SpannableString spanns[] = new SpannableString[strings.length];

    //apply the bullet characters
    for (int i=0;i<strings.length;i++){
        spanns[i] = new SpannableString(strings[i] + (i<strings.length-1 ? "\n" : ""));
        spanns[i].setSpan(new BulletSpan(15), 0, strings[i].length(), 0);
    }

    //set up the textView
    return TextUtils.concat(spanns);
}
 
Example 9
private CharSequence createText(int pos){

        List<CharSequence> stringList = new ArrayList<>(MAX_LINES_PER_VERSION);

        //load the lines from the changelog separately
        for (int i = 1; i <= MAX_LINES_PER_VERSION; i++) {

            int ID = getResources().getIdentifier(
                    "changelog_" + Integer.toString(pos) + "_" + Integer.toString(i),
                    "string", getActivity().getPackageName());

            if (ID != 0) {
                stringList.add(getString(ID));
            } else {
                break;
            }
        }

        //convert to array
        CharSequence[] strings = new CharSequence[stringList.size()];

        for (int i=0; i<strings.length; i++){
            strings[i] = stringList.get(i);
        }

        return TextUtils.concat(createBulletParagraph(stringList.toArray(new CharSequence[stringList.size()])));
    }
 
Example 10
Source Project: android-proguards   File: Bypass.java    License: Apache License 2.0 5 votes vote down vote up
public CharSequence markdownToSpannable(String markdown, TextView textView, LoadImageCallback loadImageCallback) {
    Document document = processMarkdown(markdown);

    int size = document.getElementCount();
    CharSequence[] spans = new CharSequence[size];

    for (int i = 0; i < size; i++) {
        spans[i] = recurseElement(document.getElement(i), i, size, textView, loadImageCallback);
    }

    return TextUtils.concat(spans);
}
 
Example 11
private void createMiniContact(@NonNull final NewMessageRecyclerAdapter adapter) {
    CharSequence friendsList = "";

    for (final Friend friend : adapter.getSelectedFriends()) {
        SpannableStringBuilder sb = new SpannableStringBuilder();
        LinearLayout miniContact = createContactTextView(friend.userName);
        BitmapDrawable bd = convertViewToDrawable(miniContact);
        bd.setBounds(0, 0, bd.getIntrinsicWidth() * 3, bd.getIntrinsicHeight() * 3);

        sb.append(friend.userName).append(" ");
        sb.setSpan(new ImageSpan(bd),
                sb.length() - (friend.userName.length() + 1),
                sb.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mSelectedMini.setMovementMethod(LinkMovementMethod.getInstance());
        sb.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                int i = 0;

                for (Friend item : adapter.getItems()) {
                    if (item.id == friend.id) {
                        adapter.selectItem(i);
                        selectItem(i);
                    }
                    i += 1;
                }
            }
        }, sb.length() - (friend.userName.length() + 1), sb.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        friendsList = TextUtils.concat(friendsList, sb);
    }

    mSelectedMini.setText(friendsList);
}
 
Example 12
Source Project: android-discourse   File: Bypass.java    License: Apache License 2.0 5 votes vote down vote up
public CharSequence markdownToSpannable(String markdown) {
	Document document = processMarkdown(markdown);

	CharSequence[] spans = new CharSequence[document.getElementCount()];
	for (int i = 0; i < document.getElementCount(); i++) {
		spans[i] = recurseElement(document.getElement(i));
	}

	return TextUtils.concat(spans);
}
 
Example 13
/**
 * Uses the given string array to create a text paragraph. The strings are separated by bullet
 * characters.
 *
 * @param strings The string array to use for the text paragraph
 * @return a charSequence, which can directly be applied to a textView
 */
static public CharSequence createBulletParagraph(CharSequence[] strings) {

    SpannableString spanns[] = new SpannableString[strings.length];

    //apply the bullet characters
    for (int i = 0; i < strings.length; i++) {
        spanns[i] = new SpannableString(strings[i] + (i < strings.length - 1 ? "\n" : ""));
        spanns[i].setSpan(new BulletSpan(15), 0, strings[i].length(), 0);
    }

    //set up the textView
    return TextUtils.concat(spanns);
}
 
Example 14
private CharSequence createText(int pos) {

        int MAX_LINES_PER_VERSION = 10;
        List<CharSequence> stringList = new ArrayList<>(MAX_LINES_PER_VERSION);

        //load the lines from the changelog separately
        for (int i = 1; i <= MAX_LINES_PER_VERSION; i++) {

            int ID = getResources().getIdentifier(
                    "changelog_" + Integer.toString(pos) + "_" + Integer.toString(i),
                    "string", getActivity().getPackageName());

            if (ID != 0) {
                stringList.add(getString(ID));
            } else {
                break;
            }
        }

        //convert to array
        CharSequence[] strings = new CharSequence[stringList.size()];

        for (int i = 0; i < strings.length; i++) {
            strings[i] = stringList.get(i);
        }

        return TextUtils.concat(createBulletParagraph(stringList.toArray(new CharSequence[0])));
    }
 
Example 15
CharSequence getFormattedText() {
  return TextUtils.concat(leadingWhitespace, text);
}
 
Example 16
Source Project: SteamGifts   File: GiveawayCardViewHolder.java    License: MIT License 4 votes vote down vote up
@SuppressWarnings("deprecation")
private void setupIndicators(final Giveaway giveaway) {
    List<Spannable> spans = new ArrayList<>();

    if (giveaway.isPrivate())
        spans.add(new SpannableString("{faw-lock} "));

    if (giveaway.isWhitelist())
        spans.add(new SpannableString("{faw-heart} "));

    if (giveaway.isGroup())
        spans.add(new SpannableString("{faw-users} "));

    if (giveaway.isRegionRestricted())
        spans.add(new SpannableString("{faw-globe} "));

    if (giveaway.isLevelPositive())
        spans.add(new SpannableString("L" + giveaway.getLevel()));

    if (giveaway.isLevelNegative()) {
        Spannable span = new SpannableString("L" + giveaway.getLevel());
        span.setSpan(new ForegroundColorSpan(fragment.getResources().getColor(R.color.giveawayIndicatorColorLevelTooHigh)), 0, span.toString().length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        spans.add(span);
    }

    if (!spans.isEmpty()) {
        indicator.setVisibility(View.VISIBLE);

        CharSequence text = TextUtils.concat(spans.toArray(new Spannable[spans.size()]));
        indicator.setText(text);

        if (giveaway.isGroup()) {
            indicator.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(fragment.getContext(), DetailActivity.class);
                    intent.putExtra(DetailActivity.ARG_GIVEAWAY_DETAILS, new DetailActivity.GiveawayDetails(DetailActivity.GiveawayDetails.Type.GROUPS, giveaway.getGiveawayId() + "/" + giveaway.getName(), giveaway.getTitle()));

                    fragment.getActivity().startActivityForResult(intent, CommonActivity.REQUEST_LOGIN_PASSIVE);
                }
            });
        } else {
            indicator.setOnClickListener(null);
        }
    }
}
 
Example 17
/**
 * Initialize the activity with the data from the Intent
 * ({@link DumpEditor#EXTRA_DUMP}) by displaying them as
 * US-ASCII. Non printable ASCII characters will be displayed as ".".
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_hex_to_ascii);

    if (getIntent().hasExtra(DumpEditor.EXTRA_DUMP)) {
        String[] dump = getIntent().getStringArrayExtra(
                DumpEditor.EXTRA_DUMP);
        if (dump.length != 0) {
            String s = System.getProperty("line.separator");
            CharSequence ascii = "";
            for (String line : dump) {
                if (line.startsWith("+")) {
                    // Header.
                    String sectorNumber = line.split(": ")[1];
                    ascii = TextUtils.concat(ascii, Common.colorString(
                            getString(R.string.text_sector)
                            + ": " + sectorNumber,
                            getResources().getColor(R.color.blue)), s);
                } else {
                    // Data.
                    // Replace non printable ASCII with ".".
                    byte[] hex = Common.hexStringToByteArray(line);
                    for(int i = 0; i < hex.length; i++) {
                        if (hex[i] < (byte)0x20 || hex[i] == (byte)0x7F) {
                            hex[i] = (byte)0x2E;
                        }
                    }
                    // Hex to ASCII.
                    try {
                        ascii = TextUtils.concat(ascii, " ",
                                new String(hex, "US-ASCII"), s);
                    } catch (UnsupportedEncodingException e) {
                        Log.e(LOG_TAG, "Error while encoding to ASCII", e);
                    }
                }
            }
            TextView tv = findViewById(R.id.textViewHexToAscii);
            tv.setText(ascii);
        }
        setIntent(null);
    }
}
 
Example 18
Source Project: materialup   File: AboutActivity.java    License: Apache License 2.0 4 votes vote down vote up
private View getPage(int position, ViewGroup parent) {
    switch (position) {
        case 0:
            if (aboutPlaid == null) {
                aboutPlaid = layoutInflater.inflate(R.layout.about_plaid, parent, false);
                ButterKnife.bind(this, aboutPlaid);

                // fun with spans & markdown
                CharSequence about0 = markdown.markdownToSpannable(parent.getResources()
                        .getString(R.string.about_0), plaidDescription, null);
                SpannableString about1 = new SpannableString(
                        parent.getResources().getString(R.string.about_1, BuildConfig.VERSION_NAME));
                about1.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                        0, about1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                SpannableString about2 = new SpannableString(markdown.markdownToSpannable
                        (parent.getResources().getString(R.string.about_2),
                                plaidDescription, null));
                about2.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                        0, about2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

                SpannableString about3 = new SpannableString(markdown.markdownToSpannable
                        (parent.getResources().getString(R.string.about_3),
                                plaidDescription, null));
                about3.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                        0, about3.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                CharSequence desc = TextUtils.concat(about0, "\n", about3, "\n\n", about1, "\n", about2,
                        "\n\n");
                HtmlUtils.setTextWithNiceLinks(plaidDescription, desc);
            }
            return aboutPlaid;
        case 1:
            if (aboutIcon == null) {
                aboutIcon = layoutInflater.inflate(R.layout.about_icon, parent, false);
                ButterKnife.bind(this, aboutIcon);
                CharSequence icon0 = parent.getResources().getString(R.string.about_icon_0);
                CharSequence icon1 = markdown.markdownToSpannable(parent.getResources()
                        .getString(R.string.about_icon_1), iconDescription, null);
                CharSequence iconDesc = TextUtils.concat(icon0, "\n", icon1);
                HtmlUtils.setTextWithNiceLinks(iconDescription, iconDesc);
            }
            return aboutIcon;
        case 2:
            if (aboutLibs == null) {
                aboutLibs = layoutInflater.inflate(R.layout.about_libs, parent, false);
                ButterKnife.bind(this, aboutLibs);
                libsList.setAdapter(new LibraryAdapter(parent.getContext()));
            }
            return aboutLibs;
    }
    throw new InvalidParameterException();
}
 
Example 19
Source Project: AndroidChromium   File: UrlBar.java    License: Apache License 2.0 4 votes vote down vote up
/**
 * Autocompletes the text on the url bar and selects the text that was not entered by the
 * user. Using append() instead of setText() to preserve the soft-keyboard layout.
 * @param userText user The text entered by the user.
 * @param inlineAutocompleteText The suggested autocompletion for the user's text.
 */
public void setAutocompleteText(CharSequence userText, CharSequence inlineAutocompleteText) {
    boolean emptyAutocomplete = TextUtils.isEmpty(inlineAutocompleteText);

    if (!emptyAutocomplete) mDisableTextScrollingFromAutocomplete = true;

    int autocompleteIndex = userText.length();

    String previousText = getQueryText();
    CharSequence newText = TextUtils.concat(userText, inlineAutocompleteText);

    setIgnoreTextChangesForAutocomplete(true);
    mDisableTextAccessibilityEvents = true;

    if (!TextUtils.equals(previousText, newText)) {
        // The previous text may also have included autocomplete text, so we only
        // append the new autocomplete text that has changed.
        if (TextUtils.indexOf(newText, previousText) == 0) {
            append(newText.subSequence(previousText.length(), newText.length()));
        } else {
            setUrl(newText.toString(), null);
        }
    }

    if (getSelectionStart() != autocompleteIndex
            || getSelectionEnd() != getText().length()) {
        setSelection(autocompleteIndex, getText().length());

        if (inlineAutocompleteText.length() != 0) {
            // Sending a TYPE_VIEW_TEXT_SELECTION_CHANGED accessibility event causes the
            // previous TYPE_VIEW_TEXT_CHANGED event to be swallowed. As a result the user
            // hears the autocomplete text but *not* the text they typed. Instead we send a
            // TYPE_ANNOUNCEMENT event, which doesn't swallow the text-changed event.
            announceForAccessibility(inlineAutocompleteText);
        }
    }

    if (emptyAutocomplete) {
        mAutocompleteSpan.clearSpan();
    } else {
        mAutocompleteSpan.setSpan(userText, inlineAutocompleteText);
    }

    setIgnoreTextChangesForAutocomplete(false);
    mDisableTextAccessibilityEvents = false;
}
 
Example 20
Source Project: talkback   File: TextEditActor.java    License: Apache License 2.0 4 votes vote down vote up
/** Inserts text in edit-text. Modifies edit history. */
public boolean insert(
    AccessibilityNodeInfoCompat node, CharSequence textToInsert, EventId eventId) {

  if (node == null || Role.getRole(node) != Role.ROLE_EDIT_TEXT) {
    return false;
  }

  // Find current selected text or cursor position.
  int selectionStart = node.getTextSelectionStart();
  if (selectionStart < 0) {
    selectionStart = 0;
  }
  int selectionEnd = node.getTextSelectionEnd();
  if (selectionEnd < 0) {
    selectionEnd = selectionStart;
  }
  if (selectionEnd < selectionStart) {
    // Swap start and end to make sure they are in order.
    int newStart = selectionEnd;
    selectionEnd = selectionStart;
    selectionStart = newStart;
  }
  CharSequence currentText = node.getText();
  LogUtils.v(
      "RuleEditText",
      "insert() currentText=\"%s\"",
      (currentText == null ? "null" : currentText));
  if (currentText == null) {
    currentText = "";
  }

  // Set updated text.
  CharSequence textUpdated =
      TextUtils.concat(
          currentText.subSequence(0, selectionStart),
          textToInsert,
          currentText.subSequence(selectionEnd, currentText.length()));
  Bundle arguments = new Bundle();
  arguments.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, textUpdated);
  boolean result = PerformActionUtils.performAction(node, ACTION_SET_TEXT, arguments, eventId);
  if (!result) {
    return false;
  }

  // Move cursor to end of inserted text.
  return moveCursor(node, selectionStart + textToInsert.length(), eventId);
}