blob: 6df6a3ae7ab3b4121b9d30477972a83949e7871a [file] [log] [blame]
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.text.method;
import android.view.KeyEvent;
import android.view.View;
import android.text.*;
import android.text.method.TextKeyListener.Capitalize;
import android.widget.TextView;
public abstract class BaseKeyListener
extends MetaKeyKeyListener
implements KeyListener {
/* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete();
/**
* 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.
*
* @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);
}
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 (result)
adjustMetaAfterKeypress(content);
return result;
}
private boolean altBackspace(View view, Editable content, int keyCode,
KeyEvent event) {
if (getMetaState(content, META_ALT_ON) != 1) {
return false;
}
if (!(view instanceof TextView)) {
return false;
}
Layout layout = ((TextView) view).getLayout();
if (layout == null) {
return false;
}
int l = layout.getLineForOffset(Selection.getSelectionStart(content));
int start = layout.getLineStart(l);
int end = layout.getLineEnd(l);
if (end == start) {
return false;
}
content.delete(start, end);
return true;
}
static int makeTextContentType(Capitalize caps, boolean autoText) {
int contentType = InputType.TYPE_CLASS_TEXT;
switch (caps) {
case CHARACTERS:
contentType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
break;
case WORDS:
contentType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS;
break;
case SENTENCES:
contentType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
break;
}
if (autoText) {
contentType |= InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
}
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;
}
return super.onKeyDown(view, content, keyCode, event);
}
/**
* Base implementation handles ACTION_MULTIPLE KEYCODE_UNKNOWN by inserting
* the event's text into the content.
*/
public boolean onKeyOther(View view, Editable content, KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_MULTIPLE
|| event.getKeyCode() != KeyEvent.KEYCODE_UNKNOWN) {
// 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);
}
CharSequence text = event.getCharacters();
if (text == null) {
return false;
}
content.replace(selStart, selEnd, text);
return true;
}
}