Loading core/java/android/text/method/BaseKeyListener.java +113 −62 Original line number Diff line number Diff line Loading @@ -33,76 +33,117 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener implements KeyListener { /* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete(); private static final int MODIFIER_NONE = 0; private static final int MODIFIER_ALT = 1; private static final int MODIFIER_INVALID = 2; private static int getModifier(Editable content, KeyEvent event) { if (event.hasModifiers(KeyEvent.META_ALT_ON)) { return MODIFIER_ALT; } if (!event.hasNoModifiers()) { return MODIFIER_INVALID; } if (getMetaState(content, META_ALT_ON) == 1) { return MODIFIER_ALT; } return MODIFIER_NONE; } /** * Performs the action that happens when you press the DEL key in * a TextView. If there is a selection, deletes the selection; * otherwise, DEL alone deletes the character before the cursor, * if any; * ALT+DEL deletes everything on the line the cursor is on. * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_DEL} key in * a {@link TextView}. If there is a selection, deletes the selection; otherwise, * deletes the character before the cursor, if any; ALT+DEL deletes everything on * the line the cursor is on. * * @return true if anything was deleted; false otherwise. */ public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) { int selStart, selEnd; boolean result = true; { int a = Selection.getSelectionStart(content); int b = Selection.getSelectionEnd(content); selStart = Math.min(a, b); selEnd = Math.max(a, b); public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) { int modifier = getModifier(content, event); if (modifier == MODIFIER_INVALID) { return false; } if (selStart != selEnd) { content.delete(selStart, selEnd); } else if (altBackspace(view, content, keyCode, event)) { result = true; } else { int to = TextUtils.getOffsetBefore(content, selEnd); if (to != selEnd) { content.delete(Math.min(to, selEnd), Math.max(to, selEnd)); } else { result = false; } if (deleteSelection(view, content)) { return true; } if (result) adjustMetaAfterKeypress(content); if (modifier == MODIFIER_ALT && deleteLine(view, content)) { return true; } return result; final int start = Selection.getSelectionEnd(content); final int end = TextUtils.getOffsetBefore(content, start); if (start != end) { content.delete(Math.min(start, end), Math.max(start, end)); return true; } private boolean altBackspace(View view, Editable content, int keyCode, KeyEvent event) { if (!event.isAltPressed() && getMetaState(content, META_ALT_ON) != 1) { return false; } if (!(view instanceof TextView)) { /** * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_FORWARD_DEL} * key in a {@link TextView}. If there is a selection, deletes the selection; otherwise, * deletes the character before the cursor, if any; ALT+FORWARD_DEL deletes everything on * the line the cursor is on. * * @return true if anything was deleted; false otherwise. */ public boolean forwardDelete(View view, Editable content, int keyCode, KeyEvent event) { int modifier = getModifier(content, event); if (modifier == MODIFIER_INVALID) { return false; } Layout layout = ((TextView) view).getLayout(); if (deleteSelection(view, content)) { return true; } if (modifier == MODIFIER_ALT && deleteLine(view, content)) { return true; } if (layout == null) { return false; final int start = Selection.getSelectionEnd(content); final int end = TextUtils.getOffsetAfter(content, start); if (start != end) { content.delete(Math.min(start, end), Math.max(start, end)); return true; } int l = layout.getLineForOffset(Selection.getSelectionStart(content)); int start = layout.getLineStart(l); int end = layout.getLineEnd(l); return false; } if (end == start) { private boolean deleteSelection(View view, Editable content) { int selectionStart = Selection.getSelectionStart(content); int selectionEnd = Selection.getSelectionEnd(content); if (selectionEnd < selectionStart) { int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } if (selectionStart != selectionEnd) { content.delete(selectionStart, selectionEnd); return true; } return false; } private boolean deleteLine(View view, Editable content) { if (view instanceof TextView) { final Layout layout = ((TextView) view).getLayout(); if (layout != null) { final int line = layout.getLineForOffset(Selection.getSelectionStart(content)); final int start = layout.getLineStart(line); final int end = layout.getLineEnd(line); if (end != start) { content.delete(start, end); return true; } } } return false; } static int makeTextContentType(Capitalize caps, boolean autoText) { int contentType = InputType.TYPE_CLASS_TEXT; Loading @@ -125,9 +166,21 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DEL) { backspace(view, content, keyCode, event); return true; boolean handled; switch (keyCode) { case KeyEvent.KEYCODE_DEL: handled = backspace(view, content, keyCode, event); break; case KeyEvent.KEYCODE_FORWARD_DEL: handled = forwardDelete(view, content, keyCode, event); break; default: handled = false; break; } if (handled) { adjustMetaAfterKeypress(content); } return super.onKeyDown(view, content, keyCode, event); Loading @@ -144,14 +197,12 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener return false; } int selStart, selEnd; { int a = Selection.getSelectionStart(content); int b = Selection.getSelectionEnd(content); selStart = Math.min(a, b); selEnd = Math.max(a, b); int selectionStart = Selection.getSelectionStart(content); int selectionEnd = Selection.getSelectionEnd(content); if (selectionEnd < selectionStart) { int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } CharSequence text = event.getCharacters(); Loading @@ -159,7 +210,7 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener return false; } content.replace(selStart, selEnd, text); content.replace(selectionStart, selectionEnd, text); return true; } } Loading core/java/android/text/method/QwertyKeyListener.java +3 −1 Original line number Diff line number Diff line Loading @@ -295,7 +295,9 @@ public class QwertyKeyListener extends BaseKeyListener { } return true; } else if (keyCode == KeyEvent.KEYCODE_DEL && selStart == selEnd) { } else if (keyCode == KeyEvent.KEYCODE_DEL && (event.hasNoModifiers() || event.hasModifiers(KeyEvent.META_ALT_ON)) && selStart == selEnd) { // special backspace case for undoing autotext int consider = 1; Loading Loading
core/java/android/text/method/BaseKeyListener.java +113 −62 Original line number Diff line number Diff line Loading @@ -33,76 +33,117 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener implements KeyListener { /* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete(); private static final int MODIFIER_NONE = 0; private static final int MODIFIER_ALT = 1; private static final int MODIFIER_INVALID = 2; private static int getModifier(Editable content, KeyEvent event) { if (event.hasModifiers(KeyEvent.META_ALT_ON)) { return MODIFIER_ALT; } if (!event.hasNoModifiers()) { return MODIFIER_INVALID; } if (getMetaState(content, META_ALT_ON) == 1) { return MODIFIER_ALT; } return MODIFIER_NONE; } /** * Performs the action that happens when you press the DEL key in * a TextView. If there is a selection, deletes the selection; * otherwise, DEL alone deletes the character before the cursor, * if any; * ALT+DEL deletes everything on the line the cursor is on. * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_DEL} key in * a {@link TextView}. If there is a selection, deletes the selection; otherwise, * deletes the character before the cursor, if any; ALT+DEL deletes everything on * the line the cursor is on. * * @return true if anything was deleted; false otherwise. */ public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) { int selStart, selEnd; boolean result = true; { int a = Selection.getSelectionStart(content); int b = Selection.getSelectionEnd(content); selStart = Math.min(a, b); selEnd = Math.max(a, b); public boolean backspace(View view, Editable content, int keyCode, KeyEvent event) { int modifier = getModifier(content, event); if (modifier == MODIFIER_INVALID) { return false; } if (selStart != selEnd) { content.delete(selStart, selEnd); } else if (altBackspace(view, content, keyCode, event)) { result = true; } else { int to = TextUtils.getOffsetBefore(content, selEnd); if (to != selEnd) { content.delete(Math.min(to, selEnd), Math.max(to, selEnd)); } else { result = false; } if (deleteSelection(view, content)) { return true; } if (result) adjustMetaAfterKeypress(content); if (modifier == MODIFIER_ALT && deleteLine(view, content)) { return true; } return result; final int start = Selection.getSelectionEnd(content); final int end = TextUtils.getOffsetBefore(content, start); if (start != end) { content.delete(Math.min(start, end), Math.max(start, end)); return true; } private boolean altBackspace(View view, Editable content, int keyCode, KeyEvent event) { if (!event.isAltPressed() && getMetaState(content, META_ALT_ON) != 1) { return false; } if (!(view instanceof TextView)) { /** * Performs the action that happens when you press the {@link KeyEvent#KEYCODE_FORWARD_DEL} * key in a {@link TextView}. If there is a selection, deletes the selection; otherwise, * deletes the character before the cursor, if any; ALT+FORWARD_DEL deletes everything on * the line the cursor is on. * * @return true if anything was deleted; false otherwise. */ public boolean forwardDelete(View view, Editable content, int keyCode, KeyEvent event) { int modifier = getModifier(content, event); if (modifier == MODIFIER_INVALID) { return false; } Layout layout = ((TextView) view).getLayout(); if (deleteSelection(view, content)) { return true; } if (modifier == MODIFIER_ALT && deleteLine(view, content)) { return true; } if (layout == null) { return false; final int start = Selection.getSelectionEnd(content); final int end = TextUtils.getOffsetAfter(content, start); if (start != end) { content.delete(Math.min(start, end), Math.max(start, end)); return true; } int l = layout.getLineForOffset(Selection.getSelectionStart(content)); int start = layout.getLineStart(l); int end = layout.getLineEnd(l); return false; } if (end == start) { private boolean deleteSelection(View view, Editable content) { int selectionStart = Selection.getSelectionStart(content); int selectionEnd = Selection.getSelectionEnd(content); if (selectionEnd < selectionStart) { int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } if (selectionStart != selectionEnd) { content.delete(selectionStart, selectionEnd); return true; } return false; } private boolean deleteLine(View view, Editable content) { if (view instanceof TextView) { final Layout layout = ((TextView) view).getLayout(); if (layout != null) { final int line = layout.getLineForOffset(Selection.getSelectionStart(content)); final int start = layout.getLineStart(line); final int end = layout.getLineEnd(line); if (end != start) { content.delete(start, end); return true; } } } return false; } static int makeTextContentType(Capitalize caps, boolean autoText) { int contentType = InputType.TYPE_CLASS_TEXT; Loading @@ -125,9 +166,21 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DEL) { backspace(view, content, keyCode, event); return true; boolean handled; switch (keyCode) { case KeyEvent.KEYCODE_DEL: handled = backspace(view, content, keyCode, event); break; case KeyEvent.KEYCODE_FORWARD_DEL: handled = forwardDelete(view, content, keyCode, event); break; default: handled = false; break; } if (handled) { adjustMetaAfterKeypress(content); } return super.onKeyDown(view, content, keyCode, event); Loading @@ -144,14 +197,12 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener return false; } int selStart, selEnd; { int a = Selection.getSelectionStart(content); int b = Selection.getSelectionEnd(content); selStart = Math.min(a, b); selEnd = Math.max(a, b); int selectionStart = Selection.getSelectionStart(content); int selectionEnd = Selection.getSelectionEnd(content); if (selectionEnd < selectionStart) { int temp = selectionEnd; selectionEnd = selectionStart; selectionStart = temp; } CharSequence text = event.getCharacters(); Loading @@ -159,7 +210,7 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener return false; } content.replace(selStart, selEnd, text); content.replace(selectionStart, selectionEnd, text); return true; } } Loading
core/java/android/text/method/QwertyKeyListener.java +3 −1 Original line number Diff line number Diff line Loading @@ -295,7 +295,9 @@ public class QwertyKeyListener extends BaseKeyListener { } return true; } else if (keyCode == KeyEvent.KEYCODE_DEL && selStart == selEnd) { } else if (keyCode == KeyEvent.KEYCODE_DEL && (event.hasNoModifiers() || event.hasModifiers(KeyEvent.META_ALT_ON)) && selStart == selEnd) { // special backspace case for undoing autotext int consider = 1; Loading