6package org.qtproject.qt.android;
8import android.annotation.SuppressLint;
9import android.app.Activity;
10import android.content.Context;
11import android.graphics.Canvas;
12import android.text.InputType;
13import android.view.View;
14import android.view.inputmethod.EditorInfo;
15import android.view.inputmethod.ExtractedText;
16import android.view.inputmethod.ExtractedTextRequest;
17import android.view.inputmethod.InputConnection;
18import android.view.KeyEvent;
20import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
22@SuppressLint(
"ViewConstructor")
23class QtEditText extends View
25 int m_initialCapsMode = 0;
27 int m_inputType = InputType.TYPE_CLASS_TEXT;
28 boolean m_optionsChanged =
false;
29 QtInputConnection m_inputConnection =
null;
40 private final int ImhDate = 0x80;
41 private final int ImhTime = 0x100;
60 static final int CursorHandleNotShown = 0;
61 static final int CursorHandleShowNormal = 1;
62 static final int CursorHandleShowSelection = 2;
63 static final int CursorHandleShowEdit = 0x100;
65 private CursorHandle m_cursorHandle;
66 private CursorHandle m_leftSelectionHandle;
67 private CursorHandle m_rightSelectionHandle;
69 final private EditPopupMenu m_editPopupMenu;
75 setFocusableInTouchMode(
true);
76 m_qtInputConnectionListener = listener;
77 m_editPopupMenu =
new EditPopupMenu(
this);
80 private void setImeOptions(
int imeOptions)
82 if (m_imeOptions == imeOptions)
84 m_imeOptions = imeOptions;
85 m_optionsChanged =
true;
88 private void setInitialCapsMode(
int initialCapsMode)
90 if (m_initialCapsMode == initialCapsMode)
92 m_initialCapsMode = initialCapsMode;
93 m_optionsChanged =
true;
97 private void setInputType(
int inputType)
99 if (m_inputType == inputType)
101 m_inputType = inputType;
102 m_optionsChanged =
true;
106 public InputConnection onCreateInputConnection(EditorInfo outAttrs)
108 outAttrs.inputType = m_inputType;
109 outAttrs.imeOptions = m_imeOptions;
110 outAttrs.initialCapsMode = m_initialCapsMode;
111 m_inputConnection =
new QtInputConnection(
this,m_qtInputConnectionListener);
113 ExtractedText extracted = m_inputConnection.getExtractedText(
new ExtractedTextRequest(), 0);
114 if (extracted !=
null) {
115 outAttrs.initialSelStart = extracted.selectionStart;
116 outAttrs.initialSelEnd = extracted.selectionEnd;
119 return m_inputConnection;
123 public boolean onCheckIsTextEditor ()
129 public boolean onKeyDown (
int keyCode, KeyEvent
event)
131 if (
null != m_inputConnection)
132 m_inputConnection.restartImmInput();
134 return super.onKeyDown(keyCode,
event);
138 protected void onDraw(Canvas canvas) {
141 super.onDraw(canvas);
145 void setEditTextOptions(
int enterKeyType,
int inputHints)
147 int initialCapsMode = 0;
148 int imeOptions = imeOptionsFromEnterKeyType(enterKeyType);
149 int inputType = android.text.InputType.TYPE_CLASS_TEXT;
151 if ((inputHints & (ImhPreferNumbers | ImhDigitsOnly | ImhFormattedNumbersOnly)) != 0) {
152 inputType = android.text.InputType.TYPE_CLASS_NUMBER;
153 if ((inputHints & ImhFormattedNumbersOnly) != 0) {
154 inputType |= (android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL
155 | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED);
158 if ((inputHints & ImhHiddenText) != 0)
159 inputType |= android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD;
160 }
else if ((inputHints & ImhDialableCharactersOnly) != 0) {
161 inputType = android.text.InputType.TYPE_CLASS_PHONE;
162 }
else if ((inputHints & (ImhDate | ImhTime)) != 0) {
163 inputType = android.text.InputType.TYPE_CLASS_DATETIME;
164 if ((inputHints & (ImhDate | ImhTime)) != (ImhDate | ImhTime)) {
165 if ((inputHints & ImhDate) != 0)
166 inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE;
168 inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
171 if ((inputHints & ImhHiddenText) != 0) {
172 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
173 }
else if ((inputHints & ImhSensitiveData) != 0 ||
174 isDisablePredictiveTextWorkaround(inputHints)) {
175 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
176 }
else if ((inputHints & ImhUrlCharactersOnly) != 0) {
177 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
178 if (enterKeyType == 0)
179 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
180 }
else if ((inputHints & ImhEmailCharactersOnly) != 0) {
181 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
184 if ((inputHints & ImhMultiLine) != 0) {
185 inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
188 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
190 if ((inputHints & (ImhNoPredictiveText | ImhSensitiveData | ImhHiddenText)) != 0)
191 inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
193 if ((inputHints & ImhUppercaseOnly) != 0) {
194 initialCapsMode |= android.text.TextUtils.CAP_MODE_CHARACTERS;
195 inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
196 }
else if ((inputHints & ImhLowercaseOnly) == 0
197 && (inputHints & ImhNoAutoUppercase) == 0) {
198 initialCapsMode |= android.text.TextUtils.CAP_MODE_SENTENCES;
199 inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
203 if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
204 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
206 setInitialCapsMode(initialCapsMode);
207 setImeOptions(imeOptions);
208 setInputType(inputType);
211 private int imeOptionsFromEnterKeyType(
int enterKeyType)
213 int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
216 switch (enterKeyType) {
220 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
225 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
228 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
231 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
234 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
237 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
243 int getSelectionHandleBottom()
245 if (m_cursorHandle !=
null)
246 return m_cursorHandle.bottom();
247 if (m_leftSelectionHandle !=
null && m_rightSelectionHandle !=
null)
248 return Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom());
253 int getSelectionHandleWidth()
255 if (m_leftSelectionHandle !=
null && m_rightSelectionHandle !=
null)
256 return Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
257 if (m_cursorHandle !=
null)
258 return m_cursorHandle.width();
264 int x1,
int y1,
int x2,
int y2,
boolean rtl)
268 case CursorHandleNotShown:
269 if (m_cursorHandle !=
null) {
270 m_cursorHandle.hide();
271 m_cursorHandle =
null;
273 if (m_rightSelectionHandle !=
null) {
274 m_rightSelectionHandle.hide();
275 m_leftSelectionHandle.hide();
276 m_rightSelectionHandle =
null;
277 m_leftSelectionHandle =
null;
280 case CursorHandleShowNormal:
281 if (m_cursorHandle ==
null) {
282 m_cursorHandle =
new CursorHandle((Activity) getContext(),
this,
283 CursorHandle.IdCursorHandle,
284 android.R.attr.textSelectHandle,
false);
286 m_cursorHandle.setPosition(
x1,
y1);
287 if (m_rightSelectionHandle !=
null) {
288 m_rightSelectionHandle.hide();
289 m_leftSelectionHandle.hide();
290 m_rightSelectionHandle =
null;
291 m_leftSelectionHandle =
null;
294 case CursorHandleShowSelection:
295 if (m_rightSelectionHandle ==
null) {
296 m_leftSelectionHandle =
new CursorHandle((Activity) getContext(),
this,
297 CursorHandle.IdLeftHandle,
298 !rtl ? android.R.attr.textSelectHandleLeft :
299 android.R.attr.textSelectHandleRight,
301 m_rightSelectionHandle =
new CursorHandle((Activity) getContext(),
this,
302 CursorHandle.IdRightHandle,
303 !rtl ? android.R.attr.textSelectHandleRight :
304 android.R.attr.textSelectHandleLeft,
307 m_leftSelectionHandle.setPosition(
x1,
y1);
308 m_rightSelectionHandle.setPosition(
x2,
y2);
309 if (m_cursorHandle !=
null) {
310 m_cursorHandle.hide();
311 m_cursorHandle =
null;
313 mode |= CursorHandleShowEdit;
317 if (!QtClipboardManager.hasClipboardText(getContext()))
318 editButtons &= ~EditContextView.PASTE_BUTTON;
320 final boolean setEditPopupPosition = (
mode & QtEditText.CursorHandleShowEdit) ==
321 QtEditText.CursorHandleShowEdit && editButtons != 0;
322 if (setEditPopupPosition)
323 m_editPopupMenu.setPosition(editX, editY, editButtons);
325 m_editPopupMenu.hide();
328 private boolean isDisablePredictiveTextWorkaround(
int inputHints)
330 return (inputHints & ImhNoPredictiveText) != 0 &&
331 System.getenv(
"QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT") !=
null;
static const QString context()
@ ImhFormattedNumbersOnly
@ ImhDialableCharactersOnly
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint GLfloat GLfloat GLfloat x1
GLfixed GLfixed GLfixed y2