1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.inputmethodservice; 18 19 import android.content.Context; 20 import android.util.AttributeSet; 21 import android.view.inputmethod.ExtractedText; 22 import android.widget.EditText; 23 24 /*** 25 * Specialization of {@link EditText} for showing and interacting with the 26 * extracted text in a full-screen input method. 27 */ 28 public class ExtractEditText extends EditText { 29 private InputMethodService mIME; 30 private int mSettingExtractedText; 31 32 public ExtractEditText(Context context) { 33 super(context, null); 34 } 35 36 public ExtractEditText(Context context, AttributeSet attrs) { 37 super(context, attrs, com.android.internal.R.attr.editTextStyle); 38 } 39 40 public ExtractEditText(Context context, AttributeSet attrs, int defStyle) { 41 super(context, attrs, defStyle); 42 } 43 44 void setIME(InputMethodService ime) { 45 mIME = ime; 46 } 47 48 /** 49 * Start making changes that will not be reported to the client. That 50 * is, {@link #onSelectionChanged(int, int)} will not result in sending 51 * the new selection to the client 52 */ 53 public void startInternalChanges() { 54 mSettingExtractedText += 1; 55 } 56 57 /** 58 * Finish making changes that will not be reported to the client. That 59 * is, {@link #onSelectionChanged(int, int)} will not result in sending 60 * the new selection to the client 61 */ 62 public void finishInternalChanges() { 63 mSettingExtractedText -= 1; 64 } 65 66 /** 67 * Implement just to keep track of when we are setting text from the 68 * client (vs. seeing changes in ourself from the user). 69 */ 70 @Override public void setExtractedText(ExtractedText text) { 71 try { 72 mSettingExtractedText++; 73 super.setExtractedText(text); 74 } finally { 75 mSettingExtractedText--; 76 } 77 } 78 79 /** 80 * Report to the underlying text editor about selection changes. 81 */ 82 @Override protected void onSelectionChanged(int selStart, int selEnd) { 83 if (mSettingExtractedText == 0 && mIME != null && selStart >= 0 && selEnd >= 0) { 84 mIME.onExtractedSelectionChanged(selStart, selEnd); 85 } 86 } 87 88 /** 89 * Redirect clicks to the IME for handling there. First allows any 90 * on click handler to run, though. 91 */ 92 @Override public boolean performClick() { 93 if (!super.performClick() && mIME != null) { 94 mIME.onExtractedTextClicked(); 95 return true; 96 } 97 return false; 98 } 99 100 @Override public boolean onTextContextMenuItem(int id) { 101 // Horrible hack: select word option has to be handled by original view to work. 102 if (mIME != null && id != android.R.id.startSelectingText) { 103 if (mIME.onExtractTextContextMenuItem(id)) { 104 return true; 105 } 106 } 107 return super.onTextContextMenuItem(id); 108 } 109 110 /** 111 * We are always considered to be an input method target. 112 */ 113 @Override 114 public boolean isInputMethodTarget() { 115 return true; 116 } 117 118 /** 119 * Return true if the edit text is currently showing a scroll bar. 120 */ 121 public boolean hasVerticalScrollBar() { 122 return computeVerticalScrollRange() > computeVerticalScrollExtent(); 123 } 124 125 /** 126 * Pretend like the window this view is in always has focus, so its 127 * highlight and cursor will be displayed. 128 */ 129 @Override public boolean hasWindowFocus() { 130 return this.isEnabled(); 131 } 132 133 /** 134 * Pretend like this view always has focus, so its 135 * highlight and cursor will be displayed. 136 */ 137 @Override public boolean isFocused() { 138 return this.isEnabled(); 139 } 140 141 /** 142 * Pretend like this view always has focus, so its 143 * highlight and cursor will be displayed. 144 */ 145 @Override public boolean hasFocus() { 146 return this.isEnabled(); 147 } 148 } 149