BaseInputConnection.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view.inputmethod; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.NoCopySpan; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Selection; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spannable; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.SpannableStringBuilder; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spanned; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.method.MetaKeyKeyListener; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyCharacterMap; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewRoot; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ComposingText implements NoCopySpan { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Base class for implementors of the InputConnection interface, taking care 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of most of the common behavior for providing a connection to an Editable. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementors of this class will want to be sure to implement 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getEditable} to provide access to their own editable object. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BaseInputConnection implements InputConnection { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG = false; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "BaseInputConnection"; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final Object COMPOSING = new ComposingText(); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputMethodManager mIMM; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Handler mH; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View mTargetView; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean mDummyMode; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object[] mDefaultComposingSpans; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Editable mEditable; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyCharacterMap mKeyCharacterMap; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BaseInputConnection(InputMethodManager mgr, boolean dummyMode) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM = mgr; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTargetView = null; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mH = null; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDummyMode = dummyMode; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BaseInputConnection(View targetView, boolean dummyMode) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM = (InputMethodManager)targetView.getContext().getSystemService( 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context.INPUT_METHOD_SERVICE); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mH = targetView.getHandler(); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTargetView = targetView; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDummyMode = dummyMode; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void removeComposingSpans(Spannable text) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(COMPOSING); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] sps = text.getSpans(0, text.length(), Object.class); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sps != null) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=sps.length-1; i>=0; i--) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object o = sps[i]; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((text.getSpanFlags(o)&Spanned.SPAN_COMPOSING) != 0) { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(o); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setComposingSpans(Spannable text) { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object[] sps = text.getSpans(0, text.length(), Object.class); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sps != null) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=sps.length-1; i>=0; i--) { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object o = sps[i]; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (o == COMPOSING) { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(o); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fl = text.getSpanFlags(o); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((fl&(Spanned.SPAN_COMPOSING|Spanned.SPAN_POINT_MARK_MASK)) 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != (Spanned.SPAN_COMPOSING|Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)) { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.setSpan(o, text.getSpanStart(o), text.getSpanEnd(o), 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (fl&Spanned.SPAN_POINT_MARK_MASK) 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | Spanned.SPAN_COMPOSING 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.setSpan(COMPOSING, 0, text.length(), 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getComposingSpanStart(Spannable text) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return text.getSpanStart(COMPOSING); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getComposingSpanEnd(Spannable text) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return text.getSpanEnd(COMPOSING); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the target of edit operations. The default implementation 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns its own fake editable that is just used for composing text; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * subclasses that are real text editors should override this and 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * supply their own. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Editable getEditable() { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEditable == null) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEditable = Editable.Factory.getInstance().newEditable(""); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(mEditable, 0); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEditable; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation does nothing. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean beginBatchEdit() { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation does nothing. 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean endBatchEdit() { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation uses 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link MetaKeyKeyListener#clearMetaKeyState(long, int) 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MetaKeyKeyListener.clearMetaKeyState(long, int)} to clear the state. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean clearMetaKeyStates(int states) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MetaKeyKeyListener.clearMetaKeyState(content, states); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation does nothing. 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitCompletion(CompletionInfo text) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation replaces any existing composing text with 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given text. In addition, only if dummy mode, a key event is 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitText(CharSequence text, int newCursorPosition) { 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "commitText " + text); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, false); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation performs the deletion around the current 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection position of the editable text. 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean deleteSurroundingText(int leftLength, int rightLength) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "deleteSurroundingText " + leftLength 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " / " + rightLength); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore the composing text. 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ca = getComposingSpanStart(content); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cb = getComposingSpanEnd(content); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb < ca) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = ca; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ca = cb; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cb = tmp; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca != -1 && cb != -1) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca < a) a = ca; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb > b) b = cb; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deleted = 0; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftLength > 0) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int start = a - leftLength; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start < 0) start = 0; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(start, a); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deleted = a - start; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rightLength > 0) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = b - deleted; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int end = b + rightLength; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (end > content.length()) end = content.length(); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(b, end); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation removes the composing state from the 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. In addition, only if dummy mode, a key event is 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean finishComposingText() { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "finishComposingText"); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation uses TextUtils.getCapsMode to get the 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor caps mode for the current selection position in the editable 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * text, unless in dummy mode in which case 0 is always returned. 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCursorCapsMode(int reqModes) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDummyMode) return 0; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return 0; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.getCapsMode(content, a, reqModes); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation always returns null. 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextBeforeCursor(int length, int flags) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length > a) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = a; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(a - length, a); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, a - length, a); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextAfterCursor(int length, int flags) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b + length > content.length()) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = content.length() - b; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(b, b + length); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, b, b + length); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performEditorAction(int actionCode) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performContextMenuAction(int id) { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performPrivateCommand(String action, Bundle data) { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation places the given text into the editable, 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replacing any existing composing text. The new text is marked as 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in a composing state with the composing style. 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setComposingText(CharSequence text, int newCursorPosition) { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setComposingText " + text); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, true); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation changes the selection position in the 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setSelection(int start, int end) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = content.length(); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start > len || end > len) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the given selection is out of bounds, just ignore it. 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Most likely the text was changed out from under the IME, 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the the IME is going to have to update all of its state 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anyway. 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(content, start, end); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Provides standard implementation for sending a key event to the window 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attached to the input connection's view. 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendKeyEvent(KeyEvent event) { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mIMM.mH) { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler h = mH; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (h == null) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIMM.mServedView != null) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h = mIMM.mServedView.getHandler(); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (h != null) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h.sendMessage(h.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME, 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event)); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates InputMethodManager with the current fullscreen mode. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean reportFullscreenMode(boolean enabled) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM.setFullscreenMode(enabled); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendCurrentText() { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDummyMode) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Editable content = getEditable(); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = content.length(); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 0) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 1) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it's 1 character, we have a chance of being 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // able to generate normal key events... 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mKeyCharacterMap == null) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeyCharacterMap = KeyCharacterMap.load( 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyCharacterMap.BUILT_IN_KEYBOARD); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] chars = new char[1]; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getChars(0, 1, chars, 0); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent[] events = mKeyCharacterMap.getEvents(chars); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events != null) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<events.length; i++) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Sending: " + events[i]); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(events[i]); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise, revert to the special key event containing 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the actual characters. 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.toString(), KeyCharacterMap.BUILT_IN_KEYBOARD, 0); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(event); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void replaceText(CharSequence text, int newCursorPosition, 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean composing) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // delete composing text set previously. 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = getComposingSpanStart(content); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = getComposingSpanEnd(content); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Composing span: " + a + " to " + b); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b < a) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a != -1 && b != -1) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = Selection.getSelectionStart(content); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = Selection.getSelectionEnd(content); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a >=0 && b>= 0 && a != b) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b < a) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (composing) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spannable sp = null; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(text instanceof Spannable)) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = new SpannableStringBuilder(text); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text = sp; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDefaultComposingSpans == null) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context context; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTargetView != null) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context = mTargetView.getContext(); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mIMM.mServedView != null) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context = mIMM.mServedView.getContext(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context = null; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (context != null) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray ta = context.getTheme() 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .obtainStyledAttributes(new int[] { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.candidatesTextStyleSpans 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence style = ta.getText(0); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ta.recycle(); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (style != null && style instanceof Spanned) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultComposingSpans = ((Spanned)style).getSpans( 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, style.length(), Object.class); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDefaultComposingSpans != null) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < mDefaultComposingSpans.length; ++i) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp.setSpan(mDefaultComposingSpans[i], 0, sp.length(), 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = (Spannable)text; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setComposingSpans(sp); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Replacing from " + a + " to " + b + " with \"" 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + text + "\", composing=" + composing 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", type=" + text.getClass().getCanonicalName()); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Current text:"); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Composing text:"); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(text, lp, " "); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Position the cursor appropriately, so that after replacing the 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // desired range of text it will be located in the correct spot. 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This allows us to deal with filters performing edits on the text 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are providing here. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > 0) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += b - 1; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += a; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition < 0) newCursorPosition = 0; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > content.length()) 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition = content.length(); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(content, newCursorPosition); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.replace(a, b, text); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Final text:"); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 572