private void press(Editable content, Object what) { int state = content.getSpanFlags(what); if (state == PRESSED) ; // repeat before use else if (state == RELEASED) content.setSpan(what, 0, 0, LOCKED); else if (state == USED) ; // repeat after use else if (state == LOCKED) content.removeSpan(what); else content.setSpan(what, 0, 0, PRESSED); }
private static boolean hasCompositionString(Editable content) { Object[] spans = content.getSpans(0, content.length(), Object.class); if (spans != null) { for (Object span : spans) { if ((content.getSpanFlags(span) & Spanned.SPAN_COMPOSING) != 0) { // Found composition string. return true; } } } return false; }
@TestTargetNew( level = TestLevel.COMPLETE, method = "clearMetaKeyState", args = {android.text.Editable.class, int.class}) public void testClearMetaKeyState2() { CharSequence str = "123456"; Editable text = Editable.Factory.getInstance().newEditable(str); text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT); text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT); MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_SHIFT_ON); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START)); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END)); str = "abc"; text = Editable.Factory.getInstance().newEditable(str); text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT); text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT); MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_ALT_ON); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START)); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END)); str = "#@%#$^%^"; text = Editable.Factory.getInstance().newEditable(str); text.setSpan(Selection.SELECTION_START, 0, 0, Spanned.SPAN_POINT_POINT); text.setSpan(Selection.SELECTION_END, str.length(), str.length(), Spanned.SPAN_POINT_POINT); MetaKeyKeyListener.clearMetaKeyState(text, MetaKeyKeyListener.META_SYM_ON); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_START)); assertEquals(Spanned.SPAN_POINT_POINT, text.getSpanFlags(Selection.SELECTION_END)); }
private Object getLast(Editable text, Class kind) { Object[] objs = text.getSpans(0, text.length(), kind); if (objs.length == 0) { return null; } else { for (int i = objs.length; i > 0; i--) { if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) { return objs[i - 1]; } } return null; } }
private void release(Editable content, Object what) { int current = content.getSpanFlags(what); if (current == USED) content.removeSpan(what); else if (current == PRESSED) content.setSpan(what, 0, 0, RELEASED); }
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); }