• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.text.method;
18 
19 import android.view.KeyEvent;
20 import android.view.View;
21 import android.text.*;
22 import android.text.method.TextKeyListener.Capitalize;
23 import android.widget.TextView;
24 
25 public abstract class BaseKeyListener
26 extends MetaKeyKeyListener
27 implements 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      */
backspace(View view, Editable content, int keyCode, KeyEvent event)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 
altBackspace(View view, Editable content, int keyCode, KeyEvent event)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 
makeTextContentType(Capitalize caps, boolean autoText)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 
onKeyDown(View view, Editable content, int keyCode, KeyEvent event)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      */
onKeyOther(View view, Editable content, KeyEvent event)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