blob: 8f9c96c8f0e9ca9274aa49511c34950338b12275 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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.widget;
18
19import android.content.Context;
Aurimas Liutikas99441c52016-10-11 16:48:32 -070020import android.graphics.Rect;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.text.Editable;
22import android.text.InputFilter;
23import android.text.Selection;
24import android.text.Spannable;
25import android.text.Spanned;
26import android.text.TextWatcher;
27import android.text.method.DialerKeyListener;
28import android.text.method.KeyListener;
29import android.text.method.TextKeyListener;
30import android.util.AttributeSet;
Aurimas Liutikas99441c52016-10-11 16:48:32 -070031import android.view.KeyEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Chet Haasedf103322016-08-25 08:47:20 -070034/**
35 * This widget is a layout that contains several specifically-named child views that
36 * handle keyboard entry interpreted as standard phone dialpad digits.
37 *
38 * @deprecated Use a custom view or layout to handle this functionality instead
39 */
40@Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041public class DialerFilter extends RelativeLayout
42{
43 public DialerFilter(Context context) {
44 super(context);
45 }
46
47 public DialerFilter(Context context, AttributeSet attrs) {
48 super(context, attrs);
49 }
50
51 @Override
52 protected void onFinishInflate() {
53 super.onFinishInflate();
54
55 // Setup the filter view
56 mInputFilters = new InputFilter[] { new InputFilter.AllCaps() };
57
58 mHint = (EditText) findViewById(com.android.internal.R.id.hint);
59 if (mHint == null) {
60 throw new IllegalStateException("DialerFilter must have a child EditText named hint");
61 }
62 mHint.setFilters(mInputFilters);
63
64 mLetters = mHint;
65 mLetters.setKeyListener(TextKeyListener.getInstance());
66 mLetters.setMovementMethod(null);
67 mLetters.setFocusable(false);
68
69 // Setup the digits view
70 mPrimary = (EditText) findViewById(com.android.internal.R.id.primary);
71 if (mPrimary == null) {
72 throw new IllegalStateException("DialerFilter must have a child EditText named primary");
73 }
74 mPrimary.setFilters(mInputFilters);
75
76 mDigits = mPrimary;
77 mDigits.setKeyListener(DialerKeyListener.getInstance());
78 mDigits.setMovementMethod(null);
79 mDigits.setFocusable(false);
80
81 // Look for an icon
82 mIcon = (ImageView) findViewById(com.android.internal.R.id.icon);
83
84 // Setup focus & highlight for this view
85 setFocusable(true);
86
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 // XXX Force the mode to QWERTY for now, since 12-key isn't supported
88 mIsQwerty = true;
89 setMode(DIGITS_AND_LETTERS);
90 }
91
92 /**
93 * Only show the icon view when focused, if there is one.
94 */
95 @Override
96 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
97 super.onFocusChanged(focused, direction, previouslyFocusedRect);
98
99 if (mIcon != null) {
100 mIcon.setVisibility(focused ? View.VISIBLE : View.GONE);
101 }
102 }
103
104
105 public boolean isQwertyKeyboard() {
106 return mIsQwerty;
107 }
108
109 @Override
110 public boolean onKeyDown(int keyCode, KeyEvent event) {
111 boolean handled = false;
112
113 switch (keyCode) {
114 case KeyEvent.KEYCODE_DPAD_UP:
115 case KeyEvent.KEYCODE_DPAD_DOWN:
116 case KeyEvent.KEYCODE_DPAD_LEFT:
117 case KeyEvent.KEYCODE_DPAD_RIGHT:
118 case KeyEvent.KEYCODE_ENTER:
119 case KeyEvent.KEYCODE_DPAD_CENTER:
120 break;
121
122 case KeyEvent.KEYCODE_DEL:
123 switch (mMode) {
124 case DIGITS_AND_LETTERS:
125 handled = mDigits.onKeyDown(keyCode, event);
126 handled &= mLetters.onKeyDown(keyCode, event);
127 break;
128
129 case DIGITS_AND_LETTERS_NO_DIGITS:
130 handled = mLetters.onKeyDown(keyCode, event);
131 if (mLetters.getText().length() == mDigits.getText().length()) {
132 setMode(DIGITS_AND_LETTERS);
133 }
134 break;
135
136 case DIGITS_AND_LETTERS_NO_LETTERS:
137 if (mDigits.getText().length() == mLetters.getText().length()) {
138 mLetters.onKeyDown(keyCode, event);
139 setMode(DIGITS_AND_LETTERS);
140 }
141 handled = mDigits.onKeyDown(keyCode, event);
142 break;
143
144 case DIGITS_ONLY:
145 handled = mDigits.onKeyDown(keyCode, event);
146 break;
147
148 case LETTERS_ONLY:
149 handled = mLetters.onKeyDown(keyCode, event);
150 break;
151 }
152 break;
153
154 default:
155 //mIsQwerty = msg.getKeyIsQwertyKeyboard();
156
157 switch (mMode) {
158 case DIGITS_AND_LETTERS:
159 handled = mLetters.onKeyDown(keyCode, event);
160
161 // pass this throw so the shift state is correct (for example,
162 // on a standard QWERTY keyboard, * and 8 are on the same key)
163 if (KeyEvent.isModifierKey(keyCode)) {
164 mDigits.onKeyDown(keyCode, event);
165 handled = true;
166 break;
167 }
168
169 // Only check to see if the digit is valid if the key is a printing key
170 // in the TextKeyListener. This prevents us from hiding the digits
171 // line when keys like UP and DOWN are hit.
Aurimas Liutikas99441c52016-10-11 16:48:32 -0700172 // XXX note that KEYCODE_TAB is special-cased here for
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 // devices that share tab and 0 on a single key.
174 boolean isPrint = event.isPrintingKey();
175 if (isPrint || keyCode == KeyEvent.KEYCODE_SPACE
176 || keyCode == KeyEvent.KEYCODE_TAB) {
177 char c = event.getMatch(DialerKeyListener.CHARACTERS);
178 if (c != 0) {
179 handled &= mDigits.onKeyDown(keyCode, event);
180 } else {
181 setMode(DIGITS_AND_LETTERS_NO_DIGITS);
182 }
183 }
184 break;
185
186 case DIGITS_AND_LETTERS_NO_LETTERS:
187 case DIGITS_ONLY:
188 handled = mDigits.onKeyDown(keyCode, event);
189 break;
190
191 case DIGITS_AND_LETTERS_NO_DIGITS:
192 case LETTERS_ONLY:
193 handled = mLetters.onKeyDown(keyCode, event);
194 break;
195 }
196 }
197
198 if (!handled) {
199 return super.onKeyDown(keyCode, event);
200 } else {
201 return true;
202 }
203 }
204
205 @Override
206 public boolean onKeyUp(int keyCode, KeyEvent event) {
207 boolean a = mLetters.onKeyUp(keyCode, event);
208 boolean b = mDigits.onKeyUp(keyCode, event);
209 return a || b;
210 }
211
212 public int getMode() {
213 return mMode;
214 }
215
216 /**
217 * Change the mode of the widget.
218 *
219 * @param newMode The mode to switch to.
220 */
221 public void setMode(int newMode) {
222 switch (newMode) {
223 case DIGITS_AND_LETTERS:
224 makeDigitsPrimary();
225 mLetters.setVisibility(View.VISIBLE);
226 mDigits.setVisibility(View.VISIBLE);
227 break;
228
229 case DIGITS_ONLY:
230 makeDigitsPrimary();
231 mLetters.setVisibility(View.GONE);
232 mDigits.setVisibility(View.VISIBLE);
233 break;
234
235 case LETTERS_ONLY:
236 makeLettersPrimary();
237 mLetters.setVisibility(View.VISIBLE);
238 mDigits.setVisibility(View.GONE);
239 break;
240
241 case DIGITS_AND_LETTERS_NO_LETTERS:
242 makeDigitsPrimary();
243 mLetters.setVisibility(View.INVISIBLE);
244 mDigits.setVisibility(View.VISIBLE);
245 break;
246
247 case DIGITS_AND_LETTERS_NO_DIGITS:
248 makeLettersPrimary();
249 mLetters.setVisibility(View.VISIBLE);
250 mDigits.setVisibility(View.INVISIBLE);
251 break;
252
253 }
254 int oldMode = mMode;
255 mMode = newMode;
256 onModeChange(oldMode, newMode);
257 }
258
259 private void makeLettersPrimary() {
260 if (mPrimary == mDigits) {
261 swapPrimaryAndHint(true);
262 }
263 }
264
265 private void makeDigitsPrimary() {
266 if (mPrimary == mLetters) {
267 swapPrimaryAndHint(false);
268 }
269 }
270
271 private void swapPrimaryAndHint(boolean makeLettersPrimary) {
272 Editable lettersText = mLetters.getText();
273 Editable digitsText = mDigits.getText();
274 KeyListener lettersInput = mLetters.getKeyListener();
275 KeyListener digitsInput = mDigits.getKeyListener();
276
277 if (makeLettersPrimary) {
278 mLetters = mPrimary;
279 mDigits = mHint;
280 } else {
281 mLetters = mHint;
282 mDigits = mPrimary;
283 }
284
285 mLetters.setKeyListener(lettersInput);
286 mLetters.setText(lettersText);
287 lettersText = mLetters.getText();
288 Selection.setSelection(lettersText, lettersText.length());
289
290 mDigits.setKeyListener(digitsInput);
291 mDigits.setText(digitsText);
292 digitsText = mDigits.getText();
293 Selection.setSelection(digitsText, digitsText.length());
294
295 // Reset the filters
296 mPrimary.setFilters(mInputFilters);
297 mHint.setFilters(mInputFilters);
298 }
299
300
301 public CharSequence getLetters() {
302 if (mLetters.getVisibility() == View.VISIBLE) {
303 return mLetters.getText();
304 } else {
305 return "";
306 }
307 }
308
309 public CharSequence getDigits() {
310 if (mDigits.getVisibility() == View.VISIBLE) {
311 return mDigits.getText();
312 } else {
313 return "";
314 }
315 }
316
317 public CharSequence getFilterText() {
318 if (mMode != DIGITS_ONLY) {
319 return getLetters();
320 } else {
321 return getDigits();
322 }
323 }
324
325 public void append(String text) {
326 switch (mMode) {
327 case DIGITS_AND_LETTERS:
328 mDigits.getText().append(text);
329 mLetters.getText().append(text);
330 break;
331
332 case DIGITS_AND_LETTERS_NO_LETTERS:
333 case DIGITS_ONLY:
334 mDigits.getText().append(text);
335 break;
336
337 case DIGITS_AND_LETTERS_NO_DIGITS:
338 case LETTERS_ONLY:
339 mLetters.getText().append(text);
340 break;
341 }
342 }
343
344 /**
345 * Clears both the digits and the filter text.
346 */
347 public void clearText() {
348 Editable text;
349
350 text = mLetters.getText();
351 text.clear();
352
353 text = mDigits.getText();
354 text.clear();
355
356 // Reset the mode based on the hardware type
357 if (mIsQwerty) {
358 setMode(DIGITS_AND_LETTERS);
359 } else {
360 setMode(DIGITS_ONLY);
361 }
362 }
363
364 public void setLettersWatcher(TextWatcher watcher) {
365 CharSequence text = mLetters.getText();
366 Spannable span = (Spannable)text;
367 span.setSpan(watcher, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
368 }
369
370 public void setDigitsWatcher(TextWatcher watcher) {
371 CharSequence text = mDigits.getText();
372 Spannable span = (Spannable)text;
373 span.setSpan(watcher, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
374 }
375
376 public void setFilterWatcher(TextWatcher watcher) {
377 if (mMode != DIGITS_ONLY) {
378 setLettersWatcher(watcher);
379 } else {
380 setDigitsWatcher(watcher);
381 }
382 }
383
384 public void removeFilterWatcher(TextWatcher watcher) {
385 Spannable text;
386 if (mMode != DIGITS_ONLY) {
387 text = mLetters.getText();
388 } else {
389 text = mDigits.getText();
390 }
391 text.removeSpan(watcher);
392 }
393
394 /**
395 * Called right after the mode changes to give subclasses the option to
396 * restyle, etc.
397 */
398 protected void onModeChange(int oldMode, int newMode) {
399 }
400
401 /** This mode has both lines */
402 public static final int DIGITS_AND_LETTERS = 1;
403 /** This mode is when after starting in {@link #DIGITS_AND_LETTERS} mode the filter
404 * has removed all possibility of the digits matching, leaving only the letters line */
405 public static final int DIGITS_AND_LETTERS_NO_DIGITS = 2;
406 /** This mode is when after starting in {@link #DIGITS_AND_LETTERS} mode the filter
407 * has removed all possibility of the letters matching, leaving only the digits line */
408 public static final int DIGITS_AND_LETTERS_NO_LETTERS = 3;
409 /** This mode has only the digits line */
410 public static final int DIGITS_ONLY = 4;
411 /** This mode has only the letters line */
412 public static final int LETTERS_ONLY = 5;
413
414 EditText mLetters;
415 EditText mDigits;
416 EditText mPrimary;
417 EditText mHint;
418 InputFilter mInputFilters[];
419 ImageView mIcon;
420 int mMode;
421 private boolean mIsQwerty;
422}