BaseKeyListener.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.text.method; 18 19import android.view.KeyEvent; 20import android.view.View; 21import android.text.*; 22import android.text.method.TextKeyListener.Capitalize; 23import android.widget.TextView; 24 25public abstract class BaseKeyListener 26extends MetaKeyKeyListener 27implements KeyListener { 28 /* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete(); 29 30 /** 31 * Performs the action that happens when you press the DEL key in 32 * a TextView. If there is a selection, deletes the selection; 33 * otherwise, DEL alone deletes the character before the cursor, 34 * if any; 35 * ALT+DEL deletes everything on the line the cursor is on. 36 * 37 * @return true if anything was deleted; false otherwise. 38 */ 39 public boolean backspace(View view, Editable content, int keyCode, 40 KeyEvent event) { 41 int selStart, selEnd; 42 boolean result = true; 43 44 { 45 int a = Selection.getSelectionStart(content); 46 int b = Selection.getSelectionEnd(content); 47 48 selStart = Math.min(a, b); 49 selEnd = Math.max(a, b); 50 } 51 52 if (selStart != selEnd) { 53 content.delete(selStart, selEnd); 54 } else if (altBackspace(view, content, keyCode, event)) { 55 result = true; 56 } else { 57 int to = TextUtils.getOffsetBefore(content, selEnd); 58 59 if (to != selEnd) { 60 content.delete(Math.min(to, selEnd), Math.max(to, selEnd)); 61 } 62 else { 63 result = false; 64 } 65 } 66 67 if (result) 68 adjustMetaAfterKeypress(content); 69 70 return result; 71 } 72 73 private boolean altBackspace(View view, Editable content, int keyCode, 74 KeyEvent event) { 75 if (getMetaState(content, META_ALT_ON) != 1) { 76 return false; 77 } 78 79 if (!(view instanceof TextView)) { 80 return false; 81 } 82 83 Layout layout = ((TextView) view).getLayout(); 84 85 if (layout == null) { 86 return false; 87 } 88 89 int l = layout.getLineForOffset(Selection.getSelectionStart(content)); 90 int start = layout.getLineStart(l); 91 int end = layout.getLineEnd(l); 92 93 if (end == start) { 94 return false; 95 } 96 97 content.delete(start, end); 98 return true; 99 } 100 101 static int makeTextContentType(Capitalize caps, boolean autoText) { 102 int contentType = InputType.TYPE_CLASS_TEXT; 103 switch (caps) { 104 case CHARACTERS: 105 contentType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; 106 break; 107 case WORDS: 108 contentType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS; 109 break; 110 case SENTENCES: 111 contentType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; 112 break; 113 } 114 if (autoText) { 115 contentType |= InputType.TYPE_TEXT_FLAG_AUTO_CORRECT; 116 } 117 return contentType; 118 } 119 120 public boolean onKeyDown(View view, Editable content, 121 int keyCode, KeyEvent event) { 122 if (keyCode == KeyEvent.KEYCODE_DEL) { 123 backspace(view, content, keyCode, event); 124 return true; 125 } 126 127 return super.onKeyDown(view, content, keyCode, event); 128 } 129 130 /** 131 * Base implementation handles ACTION_MULTIPLE KEYCODE_UNKNOWN by inserting 132 * the event's text into the content. 133 */ 134 public boolean onKeyOther(View view, Editable content, KeyEvent event) { 135 if (event.getAction() != KeyEvent.ACTION_MULTIPLE 136 || event.getKeyCode() != KeyEvent.KEYCODE_UNKNOWN) { 137 // Not something we are interested in. 138 return false; 139 } 140 141 int selStart, selEnd; 142 143 { 144 int a = Selection.getSelectionStart(content); 145 int b = Selection.getSelectionEnd(content); 146 147 selStart = Math.min(a, b); 148 selEnd = Math.max(a, b); 149 } 150 151 CharSequence text = event.getCharacters(); 152 if (text == null) { 153 return false; 154 } 155 156 content.replace(selStart, selEnd, text); 157 return true; 158 } 159} 160 161