BaseInputConnection.java revision e811de2d6cd736b36a2a2ff552e6893a4a021045
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.SystemClock; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.NoCopySpan; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Selection; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spannable; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.SpannableStringBuilder; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spanned; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.method.MetaKeyKeyListener; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyCharacterMap; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 366dd005b48138708762bfade0081d031a2a4a3822Dianne Hackbornimport android.view.ViewRootImpl; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ComposingText implements NoCopySpan { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Base class for implementors of the InputConnection interface, taking care 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of most of the common behavior for providing a connection to an Editable. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementors of this class will want to be sure to implement 45e811de2d6cd736b36a2a2ff552e6893a4a021045Jean Chalard * {@link #getEditable} to provide access to their own editable object, and 46e811de2d6cd736b36a2a2ff552e6893a4a021045Jean Chalard * to refer to the documentation in {@link InputConnection}. 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(); 52f9f01008624e2d28c15a90d942fa36f98c8c967dsatok 53f9f01008624e2d28c15a90d942fa36f98c8c967dsatok /** @hide */ 54f9f01008624e2d28c15a90d942fa36f98c8c967dsatok protected final InputMethodManager mIMM; 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 631bf5e22da72b477c8b7a45ed85a4dba94be39db5Dianne Hackborn BaseInputConnection(InputMethodManager mgr, boolean fullEditor) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM = mgr; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTargetView = null; 661bf5e22da72b477c8b7a45ed85a4dba94be39db5Dianne Hackborn mDummyMode = !fullEditor; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 691bf5e22da72b477c8b7a45ed85a4dba94be39db5Dianne Hackborn public BaseInputConnection(View targetView, boolean fullEditor) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM = (InputMethodManager)targetView.getContext().getSystemService( 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context.INPUT_METHOD_SERVICE); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTargetView = targetView; 731bf5e22da72b477c8b7a45ed85a4dba94be39db5Dianne Hackborn mDummyMode = !fullEditor; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void removeComposingSpans(Spannable text) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(COMPOSING); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] sps = text.getSpans(0, text.length(), Object.class); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sps != null) { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=sps.length-1; i>=0; i--) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object o = sps[i]; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((text.getSpanFlags(o)&Spanned.SPAN_COMPOSING) != 0) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(o); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 88a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void setComposingSpans(Spannable text) { 90a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani setComposingSpans(text, 0, text.length()); 91a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 92a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 93a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani /** @hide */ 94a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani public static void setComposingSpans(Spannable text, int start, int end) { 95a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani final Object[] sps = text.getSpans(start, end, Object.class); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sps != null) { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=sps.length-1; i>=0; i--) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object o = sps[i]; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (o == COMPOSING) { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.removeSpan(o); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 103a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fl = text.getSpanFlags(o); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((fl&(Spanned.SPAN_COMPOSING|Spanned.SPAN_POINT_MARK_MASK)) 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != (Spanned.SPAN_COMPOSING|Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.setSpan(o, text.getSpanStart(o), text.getSpanEnd(o), 108a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani (fl & ~Spanned.SPAN_POINT_MARK_MASK) 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | Spanned.SPAN_COMPOSING 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 115a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani text.setSpan(COMPOSING, start, end, 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getComposingSpanStart(Spannable text) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return text.getSpanStart(COMPOSING); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getComposingSpanEnd(Spannable text) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return text.getSpanEnd(COMPOSING); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the target of edit operations. The default implementation 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns its own fake editable that is just used for composing text; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * subclasses that are real text editors should override this and 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * supply their own. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Editable getEditable() { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEditable == null) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEditable = Editable.Factory.getInstance().newEditable(""); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(mEditable, 0); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEditable; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation does nothing. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean beginBatchEdit() { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation does nothing. 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean endBatchEdit() { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1569d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne * Called when this InputConnection is no longer used by the InputMethodManager. 1579d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne * 1589d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne * @hide 1599d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne */ 1609d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne protected void reportFinish() { 1619d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne // Intentionaly empty 1629d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne } 1639d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne 1649d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation uses 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link MetaKeyKeyListener#clearMetaKeyState(long, int) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MetaKeyKeyListener.clearMetaKeyState(long, int)} to clear the state. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean clearMetaKeyStates(int states) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MetaKeyKeyListener.clearMetaKeyState(content, states); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 177cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne * Default implementation does nothing and returns false. 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitCompletion(CompletionInfo text) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 184cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne * Default implementation does nothing and returns false. 185cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne */ 186cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne public boolean commitCorrection(CorrectionInfo correctionInfo) { 187cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne return false; 188cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne } 189cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne 190cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne /** 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation replaces any existing composing text with 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given text. In addition, only if dummy mode, a key event is 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitText(CharSequence text, int newCursorPosition) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "commitText " + text); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, false); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation performs the deletion around the current 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection position of the editable text. 2050c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio * @param beforeLength 2060c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio * @param afterLength 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2080c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio public boolean deleteSurroundingText(int beforeLength, int afterLength) { 2090c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio if (DEBUG) Log.v(TAG, "deleteSurroundingText " + beforeLength 2100c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio + " / " + afterLength); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore the composing text. 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ca = getComposingSpanStart(content); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cb = getComposingSpanEnd(content); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb < ca) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = ca; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ca = cb; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cb = tmp; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca != -1 && cb != -1) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca < a) a = ca; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb > b) b = cb; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deleted = 0; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2400c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio if (beforeLength > 0) { 2410c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio int start = a - beforeLength; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start < 0) start = 0; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(start, a); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deleted = a - start; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2470c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio if (afterLength > 0) { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = b - deleted; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2500c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio int end = b + afterLength; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (end > content.length()) end = content.length(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(b, end); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation removes the composing state from the 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. In addition, only if dummy mode, a key event is 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean finishComposingText() { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "finishComposingText"); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation uses TextUtils.getCapsMode to get the 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor caps mode for the current selection position in the editable 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * text, unless in dummy mode in which case 0 is always returned. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCursorCapsMode(int reqModes) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDummyMode) return 0; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return 0; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.getCapsMode(content, a, reqModes); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation always returns null. 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextBeforeCursor(int length, int flags) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 325a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (a <= 0) { 326a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn return ""; 327a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn } 328a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length > a) { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = a; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(a - length, a); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, a - length, a); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 340a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani * The default implementation returns the text currently selected, or null if none is 341a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani * selected. 342a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani */ 343a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani public CharSequence getSelectedText(int flags) { 344a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani final Editable content = getEditable(); 345a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (content == null) return null; 346a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 347a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int a = Selection.getSelectionStart(content); 348a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int b = Selection.getSelectionEnd(content); 349a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 350a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a > b) { 351a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int tmp = a; 352a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani a = b; 353a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani b = tmp; 354a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 355a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 356a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a == b) return null; 357a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 358a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if ((flags&GET_TEXT_WITH_STYLES) != 0) { 359a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return content.subSequence(a, b); 360a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 361a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return TextUtils.substring(content, a, b); 362a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 363a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 364a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani /** 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextAfterCursor(int length, int flags) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3811127895fd42111f95fdc5049141c512e60198292Eric Fischer // Guard against the case where the cursor has not been positioned yet. 3821127895fd42111f95fdc5049141c512e60198292Eric Fischer if (b < 0) { 3831127895fd42111f95fdc5049141c512e60198292Eric Fischer b = 0; 3841127895fd42111f95fdc5049141c512e60198292Eric Fischer } 3851127895fd42111f95fdc5049141c512e60198292Eric Fischer 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b + length > content.length()) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = content.length() - b; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(b, b + length); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, b, b + length); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 39886d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn * The default implementation turns this into the enter key. 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performEditorAction(int actionCode) { 40186d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn long eventTime = SystemClock.uptimeMillis(); 40286d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn sendKeyEvent(new KeyEvent(eventTime, eventTime, 4036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0, 4046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 40586d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 40686d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn | KeyEvent.FLAG_EDITOR_ACTION)); 40786d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, 4086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0, 4096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 41086d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 41186d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn | KeyEvent.FLAG_EDITOR_ACTION)); 41286d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn return true; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performContextMenuAction(int id) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performPrivateCommand(String action, Bundle data) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation places the given text into the editable, 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replacing any existing composing text. The new text is marked as 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in a composing state with the composing style. 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setComposingText(CharSequence text, int newCursorPosition) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setComposingText " + text); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, true); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 440a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani public boolean setComposingRegion(int start, int end) { 441a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani final Editable content = getEditable(); 442a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (content != null) { 443a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani beginBatchEdit(); 444a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani removeComposingSpans(content); 445a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int a = start; 446a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int b = end; 447a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a > b) { 448a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int tmp = a; 449a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani a = b; 450a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani b = tmp; 451a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 4524198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani // Clip the end points to be within the content bounds. 4534198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani final int length = content.length(); 454a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a < 0) a = 0; 4554198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (b < 0) b = 0; 4564198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (a > length) a = length; 4574198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (b > length) b = length; 458a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 459a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ensureDefaultComposingSpans(); 460a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mDefaultComposingSpans != null) { 461a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani for (int i = 0; i < mDefaultComposingSpans.length; ++i) { 462a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani content.setSpan(mDefaultComposingSpans[i], a, b, 463a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 464a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 465a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 466a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 467a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani content.setSpan(COMPOSING, a, b, 468a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 469a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 470a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani endBatchEdit(); 471a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani sendCurrentText(); 472a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 473a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return true; 474a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 475a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation changes the selection position in the 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setSelection(int start, int end) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = content.length(); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start > len || end > len) { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the given selection is out of bounds, just ignore it. 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Most likely the text was changed out from under the IME, 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the the IME is going to have to update all of its state 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anyway. 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 492b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (start == end && MetaKeyKeyListener.getMetaState(content, 493b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project MetaKeyKeyListener.META_SELECTING) != 0) { 494b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // If we are in selection mode, then we want to extend the 495b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // selection instead of replacing it. 496b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project Selection.extendSelection(content, start); 497b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } else { 498b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project Selection.setSelection(content, start, end); 499b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Provides standard implementation for sending a key event to the window 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attached to the input connection's view. 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendKeyEvent(KeyEvent event) { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mIMM.mH) { 509a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown ViewRootImpl viewRootImpl = mTargetView != null ? mTargetView.getViewRootImpl() : null; 510a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown if (viewRootImpl == null) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIMM.mServedView != null) { 512a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown viewRootImpl = mIMM.mServedView.getViewRootImpl(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 515a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown if (viewRootImpl != null) { 516a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown viewRootImpl.dispatchKeyFromIme(event); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates InputMethodManager with the current fullscreen mode. 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean reportFullscreenMode(boolean enabled) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM.setFullscreenMode(enabled); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendCurrentText() { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDummyMode) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Editable content = getEditable(); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = content.length(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 0) { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 1) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it's 1 character, we have a chance of being 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // able to generate normal key events... 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mKeyCharacterMap == null) { 5456b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] chars = new char[1]; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getChars(0, 1, chars, 0); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent[] events = mKeyCharacterMap.getEvents(chars); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events != null) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<events.length; i++) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Sending: " + events[i]); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(events[i]); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise, revert to the special key event containing 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the actual characters. 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), 5636b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown content.toString(), KeyCharacterMap.VIRTUAL_KEYBOARD, 0); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(event); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 568a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 569a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani private void ensureDefaultComposingSpans() { 570a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mDefaultComposingSpans == null) { 571a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Context context; 572a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mTargetView != null) { 573a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = mTargetView.getContext(); 574a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } else if (mIMM.mServedView != null) { 575a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = mIMM.mServedView.getContext(); 576a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } else { 577a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = null; 578a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 579a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (context != null) { 580a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani TypedArray ta = context.getTheme() 581a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani .obtainStyledAttributes(new int[] { 582a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani com.android.internal.R.attr.candidatesTextStyleSpans 583a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani }); 584a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani CharSequence style = ta.getText(0); 585a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ta.recycle(); 586a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (style != null && style instanceof Spanned) { 587a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani mDefaultComposingSpans = ((Spanned)style).getSpans( 588a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 0, style.length(), Object.class); 589a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 590a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 591a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 592a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 593a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void replaceText(CharSequence text, int newCursorPosition, 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean composing) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // delete composing text set previously. 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = getComposingSpanStart(content); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = getComposingSpanEnd(content); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Composing span: " + a + " to " + b); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b < a) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a != -1 && b != -1) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = Selection.getSelectionStart(content); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = Selection.getSelectionEnd(content); 620a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (a < 0) a = 0; 621a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (b < 0) b = 0; 622a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (b < a) { 623a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn int tmp = a; 624a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn a = b; 625a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn b = tmp; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (composing) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spannable sp = null; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(text instanceof Spannable)) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = new SpannableStringBuilder(text); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text = sp; 634a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ensureDefaultComposingSpans(); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDefaultComposingSpans != null) { 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < mDefaultComposingSpans.length; ++i) { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp.setSpan(mDefaultComposingSpans[i], 0, sp.length(), 638a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = (Spannable)text; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setComposingSpans(sp); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Replacing from " + a + " to " + b + " with \"" 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + text + "\", composing=" + composing 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", type=" + text.getClass().getCanonicalName()); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Current text:"); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Composing text:"); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(text, lp, " "); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 658e3797a15fbf769a0abcbe121cfd33b4b658aea1esatok 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Position the cursor appropriately, so that after replacing the 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // desired range of text it will be located in the correct spot. 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This allows us to deal with filters performing edits on the text 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are providing here. 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > 0) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += b - 1; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += a; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition < 0) newCursorPosition = 0; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > content.length()) 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition = content.length(); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(content, newCursorPosition); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.replace(a, b, text); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Final text:"); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 684