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