blob: 23ae21b2a2d83efd2fe8ef3425f1a04232ba38f5 [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package android.inputmethodservice;
18
19import android.content.Context;
20import android.util.AttributeSet;
21import android.view.inputmethod.ExtractedText;
satoka67a3cf2011-09-07 17:14:03 +090022import android.view.inputmethod.InputMethodManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.widget.EditText;
24
25/***
26 * Specialization of {@link EditText} for showing and interacting with the
27 * extracted text in a full-screen input method.
28 */
29public class ExtractEditText extends EditText {
30 private InputMethodService mIME;
31 private int mSettingExtractedText;
32
33 public ExtractEditText(Context context) {
34 super(context, null);
35 }
36
37 public ExtractEditText(Context context, AttributeSet attrs) {
38 super(context, attrs, com.android.internal.R.attr.editTextStyle);
39 }
40
41 public ExtractEditText(Context context, AttributeSet attrs, int defStyle) {
42 super(context, attrs, defStyle);
43 }
44
45 void setIME(InputMethodService ime) {
46 mIME = ime;
47 }
48
49 /**
50 * Start making changes that will not be reported to the client. That
51 * is, {@link #onSelectionChanged(int, int)} will not result in sending
52 * the new selection to the client
53 */
54 public void startInternalChanges() {
55 mSettingExtractedText += 1;
56 }
57
58 /**
59 * Finish making changes that will not be reported to the client. That
60 * is, {@link #onSelectionChanged(int, int)} will not result in sending
61 * the new selection to the client
62 */
63 public void finishInternalChanges() {
64 mSettingExtractedText -= 1;
65 }
66
67 /**
68 * Implement just to keep track of when we are setting text from the
69 * client (vs. seeing changes in ourself from the user).
70 */
71 @Override public void setExtractedText(ExtractedText text) {
72 try {
73 mSettingExtractedText++;
74 super.setExtractedText(text);
75 } finally {
76 mSettingExtractedText--;
77 }
78 }
79
80 /**
81 * Report to the underlying text editor about selection changes.
82 */
83 @Override protected void onSelectionChanged(int selStart, int selEnd) {
84 if (mSettingExtractedText == 0 && mIME != null && selStart >= 0 && selEnd >= 0) {
85 mIME.onExtractedSelectionChanged(selStart, selEnd);
86 }
87 }
88
89 /**
90 * Redirect clicks to the IME for handling there. First allows any
91 * on click handler to run, though.
92 */
93 @Override public boolean performClick() {
94 if (!super.performClick() && mIME != null) {
95 mIME.onExtractedTextClicked();
96 return true;
97 }
98 return false;
99 }
100
101 @Override public boolean onTextContextMenuItem(int id) {
Gilles Debunne459ac632011-07-12 16:36:33 -0700102 if (mIME != null && mIME.onExtractTextContextMenuItem(id)) {
Gilles Debunne14568c32012-01-13 15:26:05 -0800103 // Mode was started on Extracted, needs to be stopped here.
104 // Cut and paste will change the text, which stops selection mode.
105 if (id == android.R.id.copy) stopSelectionActionMode();
Gilles Debunne459ac632011-07-12 16:36:33 -0700106 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 }
108 return super.onTextContextMenuItem(id);
109 }
110
111 /**
112 * We are always considered to be an input method target.
113 */
Gilles Debunnee67b58a2010-08-31 15:55:31 -0700114 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 public boolean isInputMethodTarget() {
116 return true;
117 }
118
119 /**
120 * Return true if the edit text is currently showing a scroll bar.
121 */
122 public boolean hasVerticalScrollBar() {
123 return computeVerticalScrollRange() > computeVerticalScrollExtent();
124 }
125
126 /**
127 * Pretend like the window this view is in always has focus, so its
128 * highlight and cursor will be displayed.
129 */
130 @Override public boolean hasWindowFocus() {
Gilles Debunnee67b58a2010-08-31 15:55:31 -0700131 return this.isEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 }
133
134 /**
135 * Pretend like this view always has focus, so its
136 * highlight and cursor will be displayed.
137 */
138 @Override public boolean isFocused() {
Gilles Debunnee67b58a2010-08-31 15:55:31 -0700139 return this.isEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 }
141
142 /**
143 * Pretend like this view always has focus, so its
144 * highlight and cursor will be displayed.
145 */
146 @Override public boolean hasFocus() {
Gilles Debunnee67b58a2010-08-31 15:55:31 -0700147 return this.isEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 }
satoka67a3cf2011-09-07 17:14:03 +0900149
150 /**
151 * @hide
152 */
153 @Override protected void viewClicked(InputMethodManager imm) {
154 // As an instance of this class is supposed to be owned by IMS,
155 // and it has a reference to the IMS (the current IME),
156 // we just need to call back its onViewClicked() here.
157 // It should be good to avoid unnecessary IPCs by doing this as well.
158 if (mIME != null) {
159 mIME.onViewClicked(false);
160 }
161 }
Gilles Debunne39ba6d92011-11-09 05:26:26 +0100162
163 /**
Gilles Debunnee300be92011-12-06 10:15:56 -0800164 * {@inheritDoc}
Gilles Debunne39ba6d92011-11-09 05:26:26 +0100165 * @hide
166 */
167 @Override
168 protected void deleteText_internal(int start, int end) {
Gilles Debunnee300be92011-12-06 10:15:56 -0800169 // Do not call the super method.
170 // This will change the source TextView instead, which will update the ExtractTextView.
Gilles Debunne39ba6d92011-11-09 05:26:26 +0100171 mIME.onExtractedDeleteText(start, end);
172 }
173
174 /**
Gilles Debunnee300be92011-12-06 10:15:56 -0800175 * {@inheritDoc}
Gilles Debunne39ba6d92011-11-09 05:26:26 +0100176 * @hide
177 */
178 @Override
179 protected void replaceText_internal(int start, int end, CharSequence text) {
Gilles Debunnee300be92011-12-06 10:15:56 -0800180 // Do not call the super method.
181 // This will change the source TextView instead, which will update the ExtractTextView.
Gilles Debunne39ba6d92011-11-09 05:26:26 +0100182 mIME.onExtractedReplaceText(start, end, text);
183 }
184
Gilles Debunnee300be92011-12-06 10:15:56 -0800185 /**
186 * {@inheritDoc}
187 * @hide
188 */
189 @Override
190 protected void setSpan_internal(Object span, int start, int end, int flags) {
191 // Do not call the super method.
192 // This will change the source TextView instead, which will update the ExtractTextView.
193 mIME.onExtractedSetSpan(span, start, end, flags);
194 }
195
196 /**
197 * {@inheritDoc}
198 * @hide
199 */
200 @Override
201 protected void setCursorPosition_internal(int start, int end) {
202 // Do not call the super method.
203 // This will change the source TextView instead, which will update the ExtractTextView.
204 mIME.onExtractedSelectionChanged(start, end);
205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206}