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;
61 static final int CursorHandleNotShown = 0;
62 static final int CursorHandleShowNormal = 1;
63 static final int CursorHandleShowSelection = 2;
64 static final int CursorHandleShowEdit = 0x100;
66 private CursorHandle m_cursorHandle;
67 private CursorHandle m_leftSelectionHandle;
68 private CursorHandle m_rightSelectionHandle;
70 final private EditPopupMenu m_editPopupMenu;
76 setFocusableInTouchMode(
true);
77 m_qtInputConnectionListener = listener;
78 m_editPopupMenu =
new EditPopupMenu(
this);
81 private void setImeOptions(
int imeOptions)
83 if (m_imeOptions == imeOptions)
85 m_imeOptions = imeOptions;
86 m_optionsChanged =
true;
89 private void setInitialCapsMode(
int initialCapsMode)
91 if (m_initialCapsMode == initialCapsMode)
93 m_initialCapsMode = initialCapsMode;
94 m_optionsChanged =
true;
98 private void setInputType(
int inputType)
100 if (m_inputType == inputType)
102 m_inputType = inputType;
103 m_optionsChanged =
true;
107 public InputConnection onCreateInputConnection(EditorInfo outAttrs)
109 outAttrs.inputType = m_inputType;
110 outAttrs.imeOptions = m_imeOptions;
111 outAttrs.initialCapsMode = m_initialCapsMode;
112 m_inputConnection =
new QtInputConnection(
this,m_qtInputConnectionListener);
114 ExtractedText extracted = m_inputConnection.getExtractedText(
new ExtractedTextRequest(), 0);
115 if (extracted !=
null) {
116 outAttrs.initialSelStart = extracted.selectionStart;
117 outAttrs.initialSelEnd = extracted.selectionEnd;
120 return m_inputConnection;
124 public boolean onCheckIsTextEditor ()
130 public boolean onKeyDown (
int keyCode, KeyEvent
event)
132 if (
null != m_inputConnection)
133 m_inputConnection.restartImmInput();
135 return super.onKeyDown(keyCode,
event);
139 protected void onDraw(Canvas canvas) {
142 super.onDraw(canvas);
146 void setEditTextOptions(
int enterKeyType,
int inputHints)
148 int initialCapsMode = 0;
149 int imeOptions = imeOptionsFromEnterKeyType(enterKeyType);
150 int inputType = android.text.InputType.TYPE_CLASS_TEXT;
152 if ((inputHints & (ImhPreferNumbers | ImhDigitsOnly | ImhFormattedNumbersOnly)) != 0) {
153 inputType = android.text.InputType.TYPE_CLASS_NUMBER;
154 if ((inputHints & ImhFormattedNumbersOnly) != 0) {
155 inputType |= (android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL
156 | android.text.InputType.TYPE_NUMBER_FLAG_SIGNED);
159 if ((inputHints & ImhHiddenText) != 0)
160 inputType |= android.text.InputType.TYPE_NUMBER_VARIATION_PASSWORD;
161 }
else if ((inputHints & ImhDecimaNumbersOnly) != 0) {
162 inputType |= android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL;
163 }
else if ((inputHints & ImhDialableCharactersOnly) != 0) {
164 inputType = android.text.InputType.TYPE_CLASS_PHONE;
165 }
else if ((inputHints & (ImhDate | ImhTime)) != 0) {
166 inputType = android.text.InputType.TYPE_CLASS_DATETIME;
167 if ((inputHints & (ImhDate | ImhTime)) != (ImhDate | ImhTime)) {
168 if ((inputHints & ImhDate) != 0)
169 inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_DATE;
171 inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
174 if ((inputHints & ImhHiddenText) != 0) {
175 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
176 }
else if ((inputHints & ImhSensitiveData) != 0 ||
177 isDisablePredictiveTextWorkaround(inputHints)) {
178 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
179 }
else if ((inputHints & ImhUrlCharactersOnly) != 0) {
180 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_URI;
181 if (enterKeyType == 0)
182 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
183 }
else if ((inputHints & ImhEmailCharactersOnly) != 0) {
184 inputType |= android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
187 if ((inputHints & ImhMultiLine) != 0) {
188 inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
191 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
193 if ((inputHints & (ImhNoPredictiveText | ImhSensitiveData | ImhHiddenText)) != 0)
194 inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
196 if ((inputHints & ImhUppercaseOnly) != 0) {
197 initialCapsMode |= android.text.TextUtils.CAP_MODE_CHARACTERS;
198 inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS;
199 }
else if ((inputHints & ImhLowercaseOnly) == 0
200 && (inputHints & ImhNoAutoUppercase) == 0) {
201 initialCapsMode |= android.text.TextUtils.CAP_MODE_SENTENCES;
202 inputType |= android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
206 if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
207 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
209 setInitialCapsMode(initialCapsMode);
210 setImeOptions(imeOptions);
211 setInputType(inputType);
214 private int imeOptionsFromEnterKeyType(
int enterKeyType)
216 int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
219 switch (enterKeyType) {
223 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
228 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
231 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
234 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
237 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
240 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
246 int getSelectionHandleBottom()
248 if (m_cursorHandle !=
null)
249 return m_cursorHandle.bottom();
250 if (m_leftSelectionHandle !=
null && m_rightSelectionHandle !=
null)
251 return Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom());
256 int getSelectionHandleWidth()
258 if (m_leftSelectionHandle !=
null && m_rightSelectionHandle !=
null)
259 return Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
260 if (m_cursorHandle !=
null)
261 return m_cursorHandle.width();
267 int x1,
int y1,
int x2,
int y2,
boolean rtl)
271 case CursorHandleNotShown:
272 if (m_cursorHandle !=
null) {
273 m_cursorHandle.hide();
274 m_cursorHandle =
null;
276 if (m_rightSelectionHandle !=
null) {
277 m_rightSelectionHandle.hide();
278 m_leftSelectionHandle.hide();
279 m_rightSelectionHandle =
null;
280 m_leftSelectionHandle =
null;
283 case CursorHandleShowNormal:
284 if (m_cursorHandle ==
null) {
285 m_cursorHandle =
new CursorHandle((Activity) getContext(),
this,
286 CursorHandle.IdCursorHandle,
287 android.R.attr.textSelectHandle,
false);
289 m_cursorHandle.setPosition(
x1,
y1);
290 if (m_rightSelectionHandle !=
null) {
291 m_rightSelectionHandle.hide();
292 m_leftSelectionHandle.hide();
293 m_rightSelectionHandle =
null;
294 m_leftSelectionHandle =
null;
297 case CursorHandleShowSelection:
298 if (m_rightSelectionHandle ==
null) {
299 m_leftSelectionHandle =
new CursorHandle((Activity) getContext(),
this,
300 CursorHandle.IdLeftHandle,
301 !rtl ? android.R.attr.textSelectHandleLeft :
302 android.R.attr.textSelectHandleRight,
304 m_rightSelectionHandle =
new CursorHandle((Activity) getContext(),
this,
305 CursorHandle.IdRightHandle,
306 !rtl ? android.R.attr.textSelectHandleRight :
307 android.R.attr.textSelectHandleLeft,
310 m_leftSelectionHandle.setPosition(
x1,
y1);
311 m_rightSelectionHandle.setPosition(
x2,
y2);
312 if (m_cursorHandle !=
null) {
313 m_cursorHandle.hide();
314 m_cursorHandle =
null;
316 mode |= CursorHandleShowEdit;
320 if (!QtClipboardManager.hasClipboardText(getContext()))
321 editButtons &= ~EditContextView.PASTE_BUTTON;
323 final boolean setEditPopupPosition = (
mode & QtEditText.CursorHandleShowEdit) ==
324 QtEditText.CursorHandleShowEdit && editButtons != 0;
325 if (setEditPopupPosition)
326 m_editPopupMenu.setPosition(editX, editY, editButtons);
328 m_editPopupMenu.hide();
331 private boolean isDisablePredictiveTextWorkaround(
int inputHints)
333 return (inputHints & ImhNoPredictiveText) != 0 &&
334 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