コード例 #1
0
  public static void format(Editable text) {
    // Here, "root" means the position of "'":
    // 0'3, 0'90, and +81'-90
    // (dash will be deleted soon, so it is actually +81'90).
    int rootIndex = 1;
    int length = text.length();
    if (length > 3 && text.subSequence(0, 3).toString().equals("+81")) {
      rootIndex = 3;
    } else if (length < 1 || text.charAt(0) != '0') {
      return;
    }

    CharSequence saved = text.subSequence(0, length);

    // Strip the dashes first, as we're going to add them back
    int i = 0;
    while (i < text.length()) {
      if (text.charAt(i) == '-') {
        text.delete(i, i + 1);
      } else {
        i++;
      }
    }

    length = text.length();
    int dashposition;

    i = rootIndex;
    int base = 0;
    while (i < length) {
      char ch = text.charAt(i);
      if (!Character.isDigit(ch)) {
        text.replace(0, length, saved);
        return;
      }
      short value = FORMAT_MAP[base + ch - '0'];
      if (value < 0) {
        if (value <= -100) {
          text.replace(0, length, saved);
          return;
        }
        int dashPos2 = rootIndex + (Math.abs(value) % 10);
        if (length > dashPos2) {
          text.insert(dashPos2, "-");
        }
        int dashPos1 = rootIndex + (Math.abs(value) / 10);
        if (length > dashPos1) {
          text.insert(dashPos1, "-");
        }
        break;
      } else {
        base = value;
        i++;
      }
    }

    if (length > 3 && rootIndex == 3) {
      text.insert(rootIndex, "-");
    }
  }
コード例 #2
0
  @Override
  protected void replaceText(CharSequence text) {
    clearComposingText();
    SpannableStringBuilder ssb = buildSpannableForText(text);
    TokenImageSpan tokenSpan = buildSpanForObject(selectedObject);

    Editable editable = getText();
    int end = getSelectionEnd();
    int start = tokenizer.findTokenStart(editable, end);
    if (start < prefix.length()) {
      start = prefix.length();
    }
    String original = TextUtils.substring(editable, start, end);

    if (editable != null) {
      if (tokenSpan == null) {
        editable.replace(start, end, " ");
      } else if (!allowDuplicates && objects.contains(tokenSpan.getToken())) {
        editable.replace(start, end, " ");
      } else {
        QwertyKeyListener.markAsReplaced(editable, start, end, original);
        editable.replace(start, end, ssb);
        editable.setSpan(
            tokenSpan, start, start + ssb.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
    }
  }
コード例 #3
0
  @Override
  public void afterTextChanged(Editable s) {
    String mask = mMask;
    String value = s.toString();
    if (value.equals(mResult)) return;
    try {
        /* prepare the formatter*/
      MaskedFormatter formatter = new MaskedFormatter(mask);
      formatter.setValueContainsLiteralCharacters(false);
      formatter.setPlaceholderCharacter(
          (char) 1); /* get a string with applied mask and placeholder chars*/
      value = formatter.valueToString(value);
      try {
          /* find first placeholder*/
        value = value.substring(0, value.indexOf((char) 1)); /*process a mask char*/
        if (value.charAt(value.length() - 1) == mask.charAt(value.length() - 1))
          value = value.substring(0, value.length() - 1);

      } catch (Exception e) {
      }

      mResult = value;

      s.replace(0, s.length(), value);

    } catch (ParseException e) {

      // the entered value does not match a mask
      int offset = e.getErrorOffset();
      value = removeCharAt(value, offset);
      s.replace(0, s.length(), value);
    }
  }
コード例 #4
0
ファイル: TagHandler.java プロジェクト: cao1rui2/S1-Next
  /**
   * Replace {@link android.view.View.OnClickListener} with {@link
   * cl.monsoon.s1next.widget.TagHandler.ImageClickableSpan}.
   *
   * <p>See android.text.HtmlToSpannedConverter#startImg(android.text.SpannableStringBuilder,
   * org.xml.sax.Attributes, android.text.Html.ImageGetter)
   */
  private void handleImg(boolean opening, Editable output) {
    if (!opening) {
      int end = output.length();

      // \uFFFC: OBJECT REPLACEMENT CHARACTER
      int len = "\uFFFC".length();
      ImageSpan imageSpan = output.getSpans(end - len, end, ImageSpan.class)[0];

      String url = imageSpan.getSource();
      // replace \uFFFC with ImageSpan's source
      // in order to support url copy when selected
      output.replace(end - len, end, url);

      // image from server doesn't have domain
      // skip this because we don't want to
      // make this image (emoticon or something
      // others) clickable
      if (URLUtil.isNetworkUrl(url)) {

        output.removeSpan(imageSpan);
        // make this ImageSpan clickable
        output.setSpan(
            new ImageClickableSpan(mContext, imageSpan.getDrawable(), url),
            end - len,
            output.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
    }
  }
コード例 #5
0
  private void submitItemAtPosition(int position) {
    User user = (User) getAdapter().getItem(position);

    if (user == null) {
      return;
    }

    clearComposingText();

    int end = getSelectionEnd();
    int start = mTokenizer.findTokenStart(getText(), end);

    Editable editable = getText();
    QwertyKeyListener.markAsReplaced(editable, start, end, "");
    CharSequence chip = createChip(user, false);

    if (chip != null && start >= 0 && end >= 0) {
      // TODO chip 사이에 새 칩을 넣을 때tokenizer가
      // start를 end와 같은 위치로 잡음. 그래서 일단 start를 강제로 조절해놓음
      start = end - chip.length();
      editable.replace(start, end, chip);
      ((MemberSearchTextViewAdapter) getAdapter()).addExcludeIdxs(user.idx);
    }

    sanitizeBetween();
  }
コード例 #6
0
  private void updateHint() {
    Editable text = getText();
    CharSequence hintText = getHint();
    if (text == null || hintText == null) {
      return;
    }

    // Show hint if we need to
    if (prefix.length() > 0) {
      HintSpan[] hints = text.getSpans(0, text.length(), HintSpan.class);
      HintSpan hint = null;
      int testLength = prefix.length();
      if (hints.length > 0) {
        hint = hints[0];
        testLength += text.getSpanEnd(hint) - text.getSpanStart(hint);
      }

      if (text.length() == testLength) {
        hintVisible = true;

        if (hint != null) {
          return; // hint already visible
        }

        // We need to display the hint manually
        Typeface tf = getTypeface();
        int style = Typeface.NORMAL;
        if (tf != null) {
          style = tf.getStyle();
        }
        ColorStateList colors = getHintTextColors();

        HintSpan hintSpan = new HintSpan(null, style, (int) getTextSize(), colors, colors);
        text.insert(prefix.length(), hintText);
        text.setSpan(
            hintSpan,
            prefix.length(),
            prefix.length() + getHint().length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        setSelection(prefix.length());

      } else {
        if (hint == null) {
          return; // hint already removed
        }

        // Remove the hint. There should only ever be one
        int sStart = text.getSpanStart(hint);
        int sEnd = text.getSpanEnd(hint);

        text.removeSpan(hint);
        text.replace(sStart, sEnd, "");

        hintVisible = false;
      }
    }
  }
コード例 #7
0
 /**
  * Update the mEditable state to reflect what Blink will do in response to the KeyDown for a
  * unicode-mapped key event.
  *
  * @param unicodeChar The Unicode character to update selection with.
  */
 private void replaceSelectionWithUnicodeChar(int unicodeChar) {
   if (unicodeChar == 0) return;
   int selectionStart = Selection.getSelectionStart(mEditable);
   int selectionEnd = Selection.getSelectionEnd(mEditable);
   if (selectionStart > selectionEnd) {
     int temp = selectionStart;
     selectionStart = selectionEnd;
     selectionEnd = temp;
   }
   mEditable.replace(selectionStart, selectionEnd, Character.toString((char) unicodeChar));
   updateSelectionIfRequired();
 }
コード例 #8
0
  /**
   * Updates the AdapterInputConnection's internal representation of the text being edited and its
   * selection and composition properties. The resulting Editable is accessible through the
   * getEditable() method. If the text has not changed, this also calls updateSelection on the
   * InputMethodManager.
   *
   * @param text The String contents of the field being edited.
   * @param selectionStart The character offset of the selection start, or the caret position if
   *     there is no selection.
   * @param selectionEnd The character offset of the selection end, or the caret position if there
   *     is no selection.
   * @param compositionStart The character offset of the composition start, or -1 if there is no
   *     composition.
   * @param compositionEnd The character offset of the composition end, or -1 if there is no
   *     selection.
   * @param isNonImeChange True when the update was caused by non-IME (e.g. Javascript).
   */
  @VisibleForTesting
  public void updateState(
      String text,
      int selectionStart,
      int selectionEnd,
      int compositionStart,
      int compositionEnd,
      boolean isNonImeChange) {
    if (DEBUG) {
      Log.w(
          TAG,
          "updateState ["
              + text
              + "] ["
              + selectionStart
              + " "
              + selectionEnd
              + "] ["
              + compositionStart
              + " "
              + compositionEnd
              + "] ["
              + isNonImeChange
              + "]");
    }
    // If this update is from the IME, no further state modification is necessary because the
    // state should have been updated already by the IM framework directly.
    if (!isNonImeChange) return;

    // Non-breaking spaces can cause the IME to get confused. Replace with normal spaces.
    text = text.replace('\u00A0', ' ');

    selectionStart = Math.min(selectionStart, text.length());
    selectionEnd = Math.min(selectionEnd, text.length());
    compositionStart = Math.min(compositionStart, text.length());
    compositionEnd = Math.min(compositionEnd, text.length());

    String prevText = mEditable.toString();
    boolean textUnchanged = prevText.equals(text);

    if (!textUnchanged) {
      mEditable.replace(0, mEditable.length(), text);
    }

    Selection.setSelection(mEditable, selectionStart, selectionEnd);

    if (compositionStart == compositionEnd) {
      removeComposingSpans(mEditable);
    } else {
      super.setComposingRegion(compositionStart, compositionEnd);
    }
    updateSelectionIfRequired();
  }
コード例 #9
0
  @DSComment("Private Method")
  @DSBan(DSCat.PRIVATE_METHOD)
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 12:27:59.224 -0500",
      hash_original_method = "889637D7E351CCF8A657470FC2914F00",
      hash_generated_method = "36883B57129A6A258181D8CA0419954E")
  private void replaceCharacterAndClose(CharSequence replace) {
    int selEnd = Selection.getSelectionEnd(mText);
    if (mInsert || selEnd == 0) {
      mText.insert(selEnd, replace);
    } else {
      mText.replace(selEnd - 1, selEnd, replace);
    }

    dismiss();
  }
コード例 #10
0
 public void onClearStyles() {
   if (DBG) {
     Log.d(LOG_TAG, "--- onClearStyles");
   }
   Editable txt = mEST.getText();
   int len = txt.length();
   Object[] styles = txt.getSpans(0, len, Object.class);
   for (Object style : styles) {
     if (style instanceof ParagraphStyle
         || style instanceof QuoteSpan
         || style instanceof CharacterStyle) {
       if (style instanceof ImageSpan) {
         int start = txt.getSpanStart(style);
         int end = txt.getSpanEnd(style);
         txt.replace(start, end, "");
       }
       txt.removeSpan(style);
     }
   }
   mEST.setBackgroundDrawable(mEST.mDefaultBackground);
   mEST.mBackgroundColor = DEFAULT_BACKGROUND_COLOR;
 }
コード例 #11
0
  private void replaceText(CharSequence text, int newCursorPosition, boolean composing) {
    if (DEBUG) {
      Log.d(
          LOGTAG,
          String.format("IME: replaceText(\"%s\", %d, %b)", text, newCursorPosition, composing));
    }

    if (text == null) text = "";

    final Editable content = getEditable();
    if (content == null) {
      return;
    }

    beginBatchEdit();

    // delete composing text set previously.
    int a = getComposingSpanStart(content);
    int b = getComposingSpanEnd(content);

    if (DEBUG) Log.d(LOGTAG, "Composing span: " + a + " to " + b);

    if (b < a) {
      int tmp = a;
      a = b;
      b = tmp;
    }

    if (a != -1 && b != -1) {
      removeComposingSpans(content);
    } else {
      clampSelection();
      a = Selection.getSelectionStart(content);
      b = Selection.getSelectionEnd(content);
    }

    if (composing) {
      Spannable sp = null;
      if (!(text instanceof Spannable)) {
        sp = new SpannableStringBuilder(text);
        text = sp;
        // Underline the active composition string.
        sp.setSpan(
            new UnderlineSpan(),
            0,
            sp.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
      } else {
        sp = (Spannable) text;
      }
      setComposingSpans(sp);
    }

    if (DEBUG)
      Log.d(
          LOGTAG,
          "Replacing from "
              + a
              + " to "
              + b
              + " with \""
              + text
              + "\", composing="
              + composing
              + ", type="
              + text.getClass().getCanonicalName());

    if (DEBUG) {
      LogPrinter lp = new LogPrinter(Log.VERBOSE, LOGTAG);
      lp.println("Current text:");
      TextUtils.dumpSpans(content, lp, "  ");
      lp.println("Composing text:");
      TextUtils.dumpSpans(text, lp, "  ");
    }

    // Position the cursor appropriately, so that after replacing the
    // desired range of text it will be located in the correct spot.
    // This allows us to deal with filters performing edits on the text
    // we are providing here.
    if (newCursorPosition > 0) {
      newCursorPosition += b - 1;
    } else {
      newCursorPosition += a;
    }
    if (newCursorPosition < 0) newCursorPosition = 0;
    if (newCursorPosition > content.length()) newCursorPosition = content.length();
    Selection.setSelection(content, newCursorPosition);

    content.replace(a, b, text);

    if (DEBUG) {
      LogPrinter lp = new LogPrinter(Log.VERBOSE, LOGTAG);
      lp.println("Final text:");
      TextUtils.dumpSpans(content, lp, "  ");
    }

    endBatchEdit();
  }
コード例 #12
0
 public void setEditable(String contents) {
   mEditable.removeSpan(this);
   mEditable.replace(0, mEditable.length(), contents);
   mEditable.setSpan(this, 0, contents.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
   Selection.setSelection(mEditable, contents.length());
 }
コード例 #13
0
  public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
    int selStart, selEnd;
    int pref = 0;

    if (view != null) {
      pref = TextKeyListener.getInstance().getPrefs(view.getContext());
    }

    {
      int a = Selection.getSelectionStart(content);
      int b = Selection.getSelectionEnd(content);

      selStart = Math.min(a, b);
      selEnd = Math.max(a, b);
    }

    int activeStart = content.getSpanStart(TextKeyListener.ACTIVE);
    int activeEnd = content.getSpanEnd(TextKeyListener.ACTIVE);

    // now for the multitap cases...

    // Try to increment the character we were working on before
    // if we have one and it's still the same key.

    int rec =
        (content.getSpanFlags(TextKeyListener.ACTIVE) & Spannable.SPAN_USER)
            >>> Spannable.SPAN_USER_SHIFT;

    if (activeStart == selStart
        && activeEnd == selEnd
        && selEnd - selStart == 1
        && rec >= 0
        && rec < sRecs.size()) {
      if (keyCode == KeyEvent.KEYCODE_STAR) {
        char current = content.charAt(selStart);

        if (Character.isLowerCase(current)) {
          content.replace(selStart, selEnd, String.valueOf(current).toUpperCase());
          removeTimeouts(content);
          new Timeout(content); // for its side effects

          return true;
        }
        if (Character.isUpperCase(current)) {
          content.replace(selStart, selEnd, String.valueOf(current).toLowerCase());
          removeTimeouts(content);
          new Timeout(content); // for its side effects

          return true;
        }
      }

      if (sRecs.indexOfKey(keyCode) == rec) {
        String val = sRecs.valueAt(rec);
        char ch = content.charAt(selStart);
        int ix = val.indexOf(ch);

        if (ix >= 0) {
          ix = (ix + 1) % (val.length());

          content.replace(selStart, selEnd, val, ix, ix + 1);
          removeTimeouts(content);
          new Timeout(content); // for its side effects

          return true;
        }
      }

      // Is this key one we know about at all?  If so, acknowledge
      // that the selection is our fault but the key has changed
      // or the text no longer matches, so move the selection over
      // so that it inserts instead of replaces.

      rec = sRecs.indexOfKey(keyCode);

      if (rec >= 0) {
        Selection.setSelection(content, selEnd, selEnd);
        selStart = selEnd;
      }
    } else {
      rec = sRecs.indexOfKey(keyCode);
    }

    if (rec >= 0) {
      // We have a valid key.  Replace the selection or insertion point
      // with the first character for that key, and remember what
      // record it came from for next time.

      String val = sRecs.valueAt(rec);

      int off = 0;
      if ((pref & TextKeyListener.AUTO_CAP) != 0
          && TextKeyListener.shouldCap(mCapitalize, content, selStart)) {
        for (int i = 0; i < val.length(); i++) {
          if (Character.isUpperCase(val.charAt(i))) {
            off = i;
            break;
          }
        }
      }

      if (selStart != selEnd) {
        Selection.setSelection(content, selEnd);
      }

      content.setSpan(OLD_SEL_START, selStart, selStart, Spannable.SPAN_MARK_MARK);

      content.replace(selStart, selEnd, val, off, off + 1);

      int oldStart = content.getSpanStart(OLD_SEL_START);
      selEnd = Selection.getSelectionEnd(content);

      if (selEnd != oldStart) {
        Selection.setSelection(content, oldStart, selEnd);

        content.setSpan(
            TextKeyListener.LAST_TYPED, oldStart, selEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        content.setSpan(
            TextKeyListener.ACTIVE,
            oldStart,
            selEnd,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE | (rec << Spannable.SPAN_USER_SHIFT));
      }

      removeTimeouts(content);
      new Timeout(content); // for its side effects

      // Set up the callback so we can remove the timeout if the
      // cursor moves.

      if (content.getSpanStart(this) < 0) {
        KeyListener[] methods = content.getSpans(0, content.length(), KeyListener.class);
        for (Object method : methods) {
          content.removeSpan(method);
        }
        content.setSpan(this, 0, content.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
      }

      return true;
    }

    return super.onKeyDown(view, content, keyCode, event);
  }