diff options
author | Jeff Brown <jeffbrown@google.com> | 2010-12-21 16:06:44 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2010-12-21 18:04:26 -0800 |
commit | 14d0ca1473b991288b2dfab57409054dec7cd2fa (patch) | |
tree | 633112a99d3c0730332564a250e4f39c47d05cb6 | |
parent | d1e8e94368d8b6ac245fdcee227c6349654446ff (diff) | |
download | frameworks_base-14d0ca1473b991288b2dfab57409054dec7cd2fa.zip frameworks_base-14d0ca1473b991288b2dfab57409054dec7cd2fa.tar.gz frameworks_base-14d0ca1473b991288b2dfab57409054dec7cd2fa.tar.bz2 |
Add support for forward delete key.
Change-Id: Ib356abddd92db12d6b33e19234136c0d167f0e15
-rw-r--r-- | core/java/android/text/method/BaseKeyListener.java | 175 | ||||
-rw-r--r-- | core/java/android/text/method/QwertyKeyListener.java | 4 |
2 files changed, 116 insertions, 63 deletions
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java index 350c9a8..191c250 100644 --- a/core/java/android/text/method/BaseKeyListener.java +++ b/core/java/android/text/method/BaseKeyListener.java @@ -33,75 +33,116 @@ 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 (deleteSelection(view, content)) { + return true; + } - if (to != selEnd) { - content.delete(Math.min(to, selEnd), Math.max(to, selEnd)); - } - else { - result = false; - } + if (modifier == MODIFIER_ALT && deleteLine(view, content)) { + return true; } - if (result) - adjustMetaAfterKeypress(content); + 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; + } - return result; + return false; } - private boolean altBackspace(View view, Editable content, int keyCode, - KeyEvent event) { - if (!event.isAltPressed() && getMetaState(content, META_ALT_ON) != 1) { + /** + * 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; } - if (!(view instanceof TextView)) { - return false; + if (deleteSelection(view, content)) { + return true; } - Layout layout = ((TextView) view).getLayout(); + 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) { - return false; + 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; + } - content.delete(start, end); - return true; + 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) { @@ -122,17 +163,29 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener } return contentType; } - + 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); } - + /** * Base implementation handles ACTION_MULTIPLE KEYCODE_UNKNOWN by inserting * the event's text into the content. @@ -143,23 +196,21 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener // Not something we are interested in. 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(); if (text == null) { return false; } - - content.replace(selStart, selEnd, text); + + content.replace(selectionStart, selectionEnd, text); return true; } } diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java index 09388c0..4c82b81 100644 --- a/core/java/android/text/method/QwertyKeyListener.java +++ b/core/java/android/text/method/QwertyKeyListener.java @@ -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; |