BaseInputConnection.java revision cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view.inputmethod; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.NoCopySpan; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Selection; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spannable; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.SpannableStringBuilder; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spanned; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.method.MetaKeyKeyListener; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.LogPrinter; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyCharacterMap; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewRoot; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ComposingText implements NoCopySpan { 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Base class for implementors of the InputConnection interface, taking care 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of most of the common behavior for providing a connection to an Editable. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementors of this class will want to be sure to implement 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getEditable} to provide access to their own editable object. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BaseInputConnection implements InputConnection { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG = false; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "BaseInputConnection"; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final Object COMPOSING = new ComposingText(); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputMethodManager mIMM; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final 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 /** 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation uses 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link MetaKeyKeyListener#clearMetaKeyState(long, int) 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MetaKeyKeyListener.clearMetaKeyState(long, int)} to clear the state. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean clearMetaKeyStates(int states) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MetaKeyKeyListener.clearMetaKeyState(content, states); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 167cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne * Default implementation does nothing and returns false. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitCompletion(CompletionInfo text) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 174cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne * Default implementation does nothing and returns false. 175cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne */ 176cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne public boolean commitCorrection(CorrectionInfo correctionInfo) { 177cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne return false; 178cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne } 179cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne 180cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne /** 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Default implementation replaces any existing composing text with 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given text. In addition, only if dummy mode, a key event is 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitText(CharSequence text, int newCursorPosition) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "commitText " + text); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, false); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation performs the deletion around the current 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection position of the editable text. 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean deleteSurroundingText(int leftLength, int rightLength) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "deleteSurroundingText " + leftLength 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " / " + rightLength); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore the composing text. 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ca = getComposingSpanStart(content); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cb = getComposingSpanEnd(content); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb < ca) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = ca; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ca = cb; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cb = tmp; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca != -1 && cb != -1) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ca < a) a = ca; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cb > b) b = cb; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deleted = 0; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftLength > 0) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int start = a - leftLength; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start < 0) start = 0; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(start, a); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deleted = a - start; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rightLength > 0) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = b - deleted; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int end = b + rightLength; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (end > content.length()) end = content.length(); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.delete(b, end); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation removes the composing state from the 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. In addition, only if dummy mode, a key event is 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sent for the new text and the current editable buffer cleared. 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean finishComposingText() { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "finishComposingText"); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendCurrentText(); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation uses TextUtils.getCapsMode to get the 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor caps mode for the current selection position in the editable 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * text, unless in dummy mode in which case 0 is always returned. 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCursorCapsMode(int reqModes) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDummyMode) return 0; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return 0; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.getCapsMode(content, a, reqModes); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation always returns null. 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextBeforeCursor(int length, int flags) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 313a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (a <= 0) { 314a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn return ""; 315a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn } 316a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length > a) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = a; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(a - length, a); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, a - length, a); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 328a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani * The default implementation returns the text currently selected, or null if none is 329a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani * selected. 330a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani */ 331a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani public CharSequence getSelectedText(int flags) { 332a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani final Editable content = getEditable(); 333a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (content == null) return null; 334a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 335a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int a = Selection.getSelectionStart(content); 336a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int b = Selection.getSelectionEnd(content); 337a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 338a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a > b) { 339a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int tmp = a; 340a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani a = b; 341a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani b = tmp; 342a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 343a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 344a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a == b) return null; 345a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 346a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if ((flags&GET_TEXT_WITH_STYLES) != 0) { 347a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return content.subSequence(a, b); 348a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 349a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return TextUtils.substring(content, a, b); 350a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 351a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 352a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani /** 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation returns the given amount of text from the 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current cursor position in the buffer. 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence getTextAfterCursor(int length, int flags) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return null; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = Selection.getSelectionStart(content); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = Selection.getSelectionEnd(content); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a > b) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3691127895fd42111f95fdc5049141c512e60198292Eric Fischer // Guard against the case where the cursor has not been positioned yet. 3701127895fd42111f95fdc5049141c512e60198292Eric Fischer if (b < 0) { 3711127895fd42111f95fdc5049141c512e60198292Eric Fischer b = 0; 3721127895fd42111f95fdc5049141c512e60198292Eric Fischer } 3731127895fd42111f95fdc5049141c512e60198292Eric Fischer 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b + length > content.length()) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = content.length() - b; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_TEXT_WITH_STYLES) != 0) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return content.subSequence(b, b + length); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TextUtils.substring(content, b, b + length); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 38686d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn * The default implementation turns this into the enter key. 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performEditorAction(int actionCode) { 38986d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn long eventTime = SystemClock.uptimeMillis(); 39086d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn sendKeyEvent(new KeyEvent(eventTime, eventTime, 3916b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0, 3926b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 39386d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 39486d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn | KeyEvent.FLAG_EDITOR_ACTION)); 39586d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime, 3966b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0, 3976b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 39886d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 39986d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn | KeyEvent.FLAG_EDITOR_ACTION)); 40086d56cca9ce23b0f4814418d7c71ec11ea9fd278Dianne Hackborn return true; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performContextMenuAction(int id) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation does nothing. 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performPrivateCommand(String action, Bundle data) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation places the given text into the editable, 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replacing any existing composing text. The new text is marked as 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in a composing state with the composing style. 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setComposingText(CharSequence text, int newCursorPosition) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setComposingText " + text); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(text, newCursorPosition, true); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 428a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani public boolean setComposingRegion(int start, int end) { 429a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani final Editable content = getEditable(); 430a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (content != null) { 431a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani beginBatchEdit(); 432a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani removeComposingSpans(content); 433a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int a = start; 434a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int b = end; 435a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a > b) { 436a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani int tmp = a; 437a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani a = b; 438a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani b = tmp; 439a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 4404198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani // Clip the end points to be within the content bounds. 4414198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani final int length = content.length(); 442a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (a < 0) a = 0; 4434198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (b < 0) b = 0; 4444198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (a > length) a = length; 4454198918eed8e44723417fad8a986cda664c92d5bAmith Yamasani if (b > length) b = length; 446a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 447a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ensureDefaultComposingSpans(); 448a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mDefaultComposingSpans != null) { 449a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani for (int i = 0; i < mDefaultComposingSpans.length; ++i) { 450a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani content.setSpan(mDefaultComposingSpans[i], a, b, 451a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 452a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 453a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 454a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 455a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani content.setSpan(COMPOSING, a, b, 456a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 457a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 458a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani endBatchEdit(); 459a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani sendCurrentText(); 460a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 461a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani return true; 462a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 463a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default implementation changes the selection position in the 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current editable text. 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setSelection(int start, int end) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = content.length(); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start > len || end > len) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the given selection is out of bounds, just ignore it. 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Most likely the text was changed out from under the IME, 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the the IME is going to have to update all of its state 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anyway. 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 480b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (start == end && MetaKeyKeyListener.getMetaState(content, 481b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project MetaKeyKeyListener.META_SELECTING) != 0) { 482b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // If we are in selection mode, then we want to extend the 483b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // selection instead of replacing it. 484b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project Selection.extendSelection(content, start); 485b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } else { 486b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project Selection.setSelection(content, start, end); 487b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Provides standard implementation for sending a key event to the window 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attached to the input connection's view. 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendKeyEvent(KeyEvent event) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mIMM.mH) { 4971bf5e22da72b477c8b7a45ed85a4dba94be39db5Dianne Hackborn Handler h = mTargetView != null ? mTargetView.getHandler() : null; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (h == null) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIMM.mServedView != null) { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h = mIMM.mServedView.getHandler(); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (h != null) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h.sendMessage(h.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME, 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project event)); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates InputMethodManager with the current fullscreen mode. 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean reportFullscreenMode(boolean enabled) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIMM.setFullscreenMode(enabled); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendCurrentText() { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDummyMode) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Editable content = getEditable(); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content != null) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = content.length(); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 0) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N == 1) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it's 1 character, we have a chance of being 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // able to generate normal key events... 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mKeyCharacterMap == null) { 5346b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char[] chars = new char[1]; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.getChars(0, 1, chars, 0); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent[] events = mKeyCharacterMap.getEvents(chars); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events != null) { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<events.length; i++) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Sending: " + events[i]); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(events[i]); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise, revert to the special key event containing 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the actual characters. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), 5526b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown content.toString(), KeyCharacterMap.VIRTUAL_KEYBOARD, 0); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendKeyEvent(event); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.clear(); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 557a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 558a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani private void ensureDefaultComposingSpans() { 559a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mDefaultComposingSpans == null) { 560a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Context context; 561a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (mTargetView != null) { 562a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = mTargetView.getContext(); 563a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } else if (mIMM.mServedView != null) { 564a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = mIMM.mServedView.getContext(); 565a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } else { 566a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani context = null; 567a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 568a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (context != null) { 569a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani TypedArray ta = context.getTheme() 570a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani .obtainStyledAttributes(new int[] { 571a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani com.android.internal.R.attr.candidatesTextStyleSpans 572a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani }); 573a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani CharSequence style = ta.getText(0); 574a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ta.recycle(); 575a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani if (style != null && style instanceof Spanned) { 576a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani mDefaultComposingSpans = ((Spanned)style).getSpans( 577a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 0, style.length(), Object.class); 578a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 579a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 580a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 581a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani } 582a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void replaceText(CharSequence text, int newCursorPosition, 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean composing) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project beginBatchEdit(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // delete composing text set previously. 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int a = getComposingSpanStart(content); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int b = getComposingSpanEnd(content); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Composing span: " + a + " to " + b); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (b < a) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmp = a; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = b; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = tmp; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a != -1 && b != -1) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeComposingSpans(content); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = Selection.getSelectionStart(content); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = Selection.getSelectionEnd(content); 609a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (a < 0) a = 0; 610a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (b < 0) b = 0; 611a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn if (b < a) { 612a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn int tmp = a; 613a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn a = b; 614a465a170ce5d7155580fd308d1e50092365117e4Dianne Hackborn b = tmp; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (composing) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spannable sp = null; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(text instanceof Spannable)) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = new SpannableStringBuilder(text); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text = sp; 623a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani ensureDefaultComposingSpans(); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDefaultComposingSpans != null) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < mDefaultComposingSpans.length; ++i) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp.setSpan(mDefaultComposingSpans[i], 0, sp.length(), 627a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp = (Spannable)text; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setComposingSpans(sp); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Replacing from " + a + " to " + b + " with \"" 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + text + "\", composing=" + composing 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", type=" + text.getClass().getCanonicalName()); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Current text:"); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Composing text:"); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(text, lp, " "); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Position the cursor appropriately, so that after replacing the 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // desired range of text it will be located in the correct spot. 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This allows us to deal with filters performing edits on the text 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are providing here. 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > 0) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += b - 1; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition += a; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition < 0) newCursorPosition = 0; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newCursorPosition > content.length()) 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newCursorPosition = content.length(); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(content, newCursorPosition); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project content.replace(a, b, text); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.println("Final text:"); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextUtils.dumpSpans(content, lp, " "); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endBatchEdit(); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 673