1616
1717package rkr .simplekeyboard .inputmethod .latin ;
1818
19- import android .inputmethodservice .InputMethodService ;
2019import android .os .Build ;
21- import android .os .SystemClock ;
22- import android .text .TextUtils ;
2320import android .util .Log ;
2421import android .view .KeyEvent ;
2522import android .view .inputmethod .InputConnection ;
@@ -269,6 +266,22 @@ public CharSequence getTextAfterCursor(final int n) {
269266 }
270267
271268 public void replaceText (final int startPosition , final int endPosition , CharSequence text ) {
269+ if (mExpectedSelStart != mExpectedSelEnd ) {
270+ Log .e (TAG , "replaceText called with text range selected" );
271+ return ;
272+ }
273+ if (mExpectedSelStart != startPosition ) {
274+ Log .e (TAG , "replaceText called with range not starting with current cursor position" );
275+ return ;
276+ }
277+
278+ final String textAfterCursor = mTextAfterCursor ;
279+ if (textAfterCursor .length () < endPosition - startPosition ) {
280+ Log .e (TAG , "replaceText called with range longer than current text" );
281+ return ;
282+ }
283+ mTextAfterCursor = text + textAfterCursor .substring (endPosition - startPosition );
284+
272285 RichInputMethodManager .getInstance ().resetSubtypeCycleOrder ();
273286 mIC .setComposingRegion (startPosition , endPosition );
274287 mIC .setComposingText (text , startPosition );
@@ -300,15 +313,19 @@ public void sendKeyEvent(final KeyEvent keyEvent) {
300313 }
301314 break ;
302315 case KeyEvent .KEYCODE_DEL :
303- if (!mTextBeforeCursor .isEmpty ()) {
304- mTextBeforeCursor = mTextBeforeCursor .substring (0 , mTextBeforeCursor .length () - 1 );
305- }
306-
307- if (mExpectedSelStart > 0 && mExpectedSelStart == mExpectedSelEnd ) {
308- // TODO: Handle surrogate pairs.
309- mExpectedSelStart -= 1 ;
316+ if (hasSelection ()) {
317+ mTextSelection = "" ;
318+ mExpectedSelEnd = mExpectedSelStart ;
319+ } else {
320+ final int steps = getUnicodeSteps (-1 , false );
321+ String textBeforeCursor = mTextBeforeCursor ;
322+ if (!textBeforeCursor .isEmpty ()) {
323+ mTextBeforeCursor = textBeforeCursor .substring (0 , textBeforeCursor .length () + steps );
324+ }
325+ if (mExpectedSelStart > 0 ) {
326+ mExpectedSelStart += steps ;
327+ }
310328 }
311- mExpectedSelEnd = mExpectedSelStart ;
312329 break ;
313330 case KeyEvent .KEYCODE_UNKNOWN :
314331 if (null != keyEvent .getCharacters ()) {
@@ -341,7 +358,6 @@ public void sendKeyEvent(final KeyEvent keyEvent) {
341358 *
342359 * @param start the character index where the selection should start.
343360 * @param end the character index where the selection should end.
344- * @return Returns true on success, false on failure: either the input connection is no longer
345361 * valid when setting the selection or when retrieving the text cache at that point, or
346362 * invalid arguments were passed.
347363 */
@@ -354,15 +370,17 @@ public void setSelection(int start, int end) {
354370 }
355371 RichInputMethodManager .getInstance ().resetSubtypeCycleOrder ();
356372
373+ final int textStart = mExpectedSelStart - mTextBeforeCursor .length ();
374+ final String textRange = mTextBeforeCursor + mTextSelection + mTextAfterCursor ;
375+ mTextBeforeCursor = textRange .substring (0 , start - textStart );
376+ mTextSelection = textRange .substring (start - textStart , end - textStart );
377+ mTextAfterCursor = textRange .substring (end - textStart );
378+
357379 mExpectedSelStart = start ;
358380 mExpectedSelEnd = end ;
359381 if (isConnected ()) {
360- final boolean isIcValid = mIC .setSelection (start , end );
361- if (!isIcValid ) {
362- return ;
363- }
382+ mIC .setSelection (start , end );
364383 }
365- reloadTextCache ();
366384 }
367385
368386 public int getExpectedSelectionStart () {
@@ -393,24 +411,26 @@ public int getUnicodeSteps(int chars, boolean rightSidePointer) {
393411 CharSequence charsBeforeCursor = rightSidePointer && hasSelection () ?
394412 getSelectedText () :
395413 getTextBeforeCursor (-chars * 2 );
396- if (charsBeforeCursor != null ) {
397- for (int i = charsBeforeCursor .length () - 1 ; i >= 0 && chars < 0 ; i --, chars ++, steps --) {
398- if (Character .isSurrogate (charsBeforeCursor .charAt (i ))) {
399- steps --;
400- i --;
401- }
414+ if (charsBeforeCursor == null || charsBeforeCursor == "" ) {
415+ return chars ;
416+ }
417+ for (int i = charsBeforeCursor .length () - 1 ; i >= 0 && chars < 0 ; i --, chars ++, steps --) {
418+ if (Character .isSurrogate (charsBeforeCursor .charAt (i ))) {
419+ steps --;
420+ i --;
402421 }
403422 }
404423 } else if (chars > 0 ) {
405424 CharSequence charsAfterCursor = !rightSidePointer && hasSelection () ?
406425 getSelectedText () :
407426 getTextAfterCursor (chars * 2 );
408- if (charsAfterCursor != null ) {
409- for (int i = 0 ; i < charsAfterCursor .length () && chars > 0 ; i ++, chars --, steps ++) {
410- if (Character .isSurrogate (charsAfterCursor .charAt (i ))) {
411- steps ++;
412- i ++;
413- }
427+ if (charsAfterCursor == null || charsAfterCursor == "" ) {
428+ return chars ;
429+ }
430+ for (int i = 0 ; i < charsAfterCursor .length () && chars > 0 ; i ++, chars --, steps ++) {
431+ if (Character .isSurrogate (charsAfterCursor .charAt (i ))) {
432+ steps ++;
433+ i ++;
414434 }
415435 }
416436 }
0 commit comments