Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
QtEditText.java
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:critical reason:password-input-type
5
6package org.qtproject.qt.android;
7
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;
19
20import org.qtproject.qt.android.QtInputConnection.QtInputConnectionListener;
21
22@SuppressLint("ViewConstructor")
23class QtEditText extends View
24{
25 int m_initialCapsMode = 0;
26 int m_imeOptions = 0;
27 int m_inputType = InputType.TYPE_CLASS_TEXT;
28 boolean m_optionsChanged = false;
29 QtInputConnection m_inputConnection = null;
30
31 // input method hints - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h
32 private final int ImhHiddenText = 0x1;
33 private final int ImhSensitiveData = 0x2;
34 private final int ImhNoAutoUppercase = 0x4;
35 private final int ImhPreferNumbers = 0x8;
36 private final int ImhPreferUppercase = 0x10;
37 private final int ImhPreferLowercase = 0x20;
38 private final int ImhNoPredictiveText = 0x40;
39
40 private final int ImhDate = 0x80;
41 private final int ImhTime = 0x100;
42
43 private final int ImhPreferLatin = 0x200;
44
45 private final int ImhMultiLine = 0x400;
46
47 private final int ImhDigitsOnly = 0x10000;
48 private final int ImhFormattedNumbersOnly = 0x20000;
49 private final int ImhUppercaseOnly = 0x40000;
50 private final int ImhLowercaseOnly = 0x80000;
51 private final int ImhDialableCharactersOnly = 0x100000;
52 private final int ImhEmailCharactersOnly = 0x200000;
53 private final int ImhUrlCharactersOnly = 0x400000;
54 private final int ImhLatinOnly = 0x800000;
55 private final int ImhDecimaNumbersOnly = 0x1000000;
56
57 private final QtInputConnectionListener m_qtInputConnectionListener;
58
59
60 // Values coming from QAndroidInputContext::CursorHandleShowMode
61 static final int CursorHandleNotShown = 0;
62 static final int CursorHandleShowNormal = 1;
63 static final int CursorHandleShowSelection = 2;
64 static final int CursorHandleShowEdit = 0x100;
65
66 private CursorHandle m_cursorHandle;
67 private CursorHandle m_leftSelectionHandle;
68 private CursorHandle m_rightSelectionHandle;
69
70 final private EditPopupMenu m_editPopupMenu;
71
72 QtEditText(Context context, QtInputConnectionListener listener)
73 {
74 super(context);
75 setFocusable(true);
76 setFocusableInTouchMode(true);
77 m_qtInputConnectionListener = listener;
78 m_editPopupMenu = new EditPopupMenu(this);
79 }
80
81 private void setImeOptions(int imeOptions)
82 {
83 if (m_imeOptions == imeOptions)
84 return;
85 m_imeOptions = imeOptions;
86 m_optionsChanged = true;
87 }
88
89 private void setInitialCapsMode(int initialCapsMode)
90 {
91 if (m_initialCapsMode == initialCapsMode)
92 return;
93 m_initialCapsMode = initialCapsMode;
94 m_optionsChanged = true;
95 }
96
97
98 private void setInputType(int inputType)
99 {
100 if (m_inputType == inputType)
101 return;
102 m_inputType = inputType;
103 m_optionsChanged = true;
104 }
105
106 @Override
107 public InputConnection onCreateInputConnection(EditorInfo outAttrs)
108 {
109 outAttrs.inputType = m_inputType;
110 outAttrs.imeOptions = m_imeOptions;
111 outAttrs.initialCapsMode = m_initialCapsMode;
112 m_inputConnection = new QtInputConnection(this,m_qtInputConnectionListener);
113
114 ExtractedText extracted = m_inputConnection.getExtractedText(new ExtractedTextRequest(), 0);
115 if (extracted != null) {
116 outAttrs.initialSelStart = extracted.selectionStart;
117 outAttrs.initialSelEnd = extracted.selectionEnd;
118 }
119
120 return m_inputConnection;
121 }
122
123 @Override
124 public boolean onCheckIsTextEditor ()
125 {
126 return true;
127 }
128
129 @Override
130 public boolean onKeyDown (int keyCode, KeyEvent event)
131 {
132 if (null != m_inputConnection)
133 m_inputConnection.restartImmInput();
134
135 return super.onKeyDown(keyCode, event);
136 }
137
138 @Override
139 protected void onDraw(Canvas canvas) {
140 // DEBUG CODE
141 // canvas.drawARGB(127, 255, 0, 255);
142 super.onDraw(canvas);
143 }
144
145
146 void setEditTextOptions(int enterKeyType, int inputHints)
147 {
148 int initialCapsMode = 0;
149 int imeOptions = imeOptionsFromEnterKeyType(enterKeyType);
150 int inputType = android.text.InputType.TYPE_CLASS_TEXT;
151
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);
157 }
158
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;
170 else
171 inputType |= android.text.InputType.TYPE_DATETIME_VARIATION_TIME;
172 } // else { TYPE_DATETIME_VARIATION_NORMAL(0) }
173 } else { // CLASS_TEXT
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) // not explicitly overridden
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;
185 }
186
187 if ((inputHints & ImhMultiLine) != 0) {
188 inputType |= android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE;
189 // Clear imeOptions for Multi-Line Type
190 // User should be able to insert new line in such case
191 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
192 }
193 if ((inputHints & (ImhNoPredictiveText | ImhSensitiveData | ImhHiddenText)) != 0)
194 inputType |= android.text.InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
195
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;
203 }
204 }
205
206 if (enterKeyType == 0 && (inputHints & ImhMultiLine) != 0)
207 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
208
209 setInitialCapsMode(initialCapsMode);
210 setImeOptions(imeOptions);
211 setInputType(inputType);
212 }
213
214 private int imeOptionsFromEnterKeyType(int enterKeyType)
215 {
216 int imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
217
218 // enter key type - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h
219 switch (enterKeyType) {
220 case 0: // EnterKeyDefault
221 break;
222 case 1: // EnterKeyReturn
223 imeOptions = android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION;
224 break;
225 case 2: // EnterKeyDone
226 break;
227 case 3: // EnterKeyGo
228 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_GO;
229 break;
230 case 4: // EnterKeySend
231 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEND;
232 break;
233 case 5: // EnterKeySearch
234 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH;
235 break;
236 case 6: // EnterKeyNext
237 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
238 break;
239 case 7: // EnterKeyPrevious
240 imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
241 break;
242 }
243 return imeOptions;
244 }
245
246 int getSelectionHandleBottom()
247 {
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());
252
253 return 0;
254 }
255
256 int getSelectionHandleWidth()
257 {
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();
262
263 return 0;
264 }
265
266 void updateHandles(int mode, int editX, int editY, int editButtons,
267 int x1, int y1, int x2, int y2, boolean rtl)
268 {
269 switch (mode & 0xff)
270 {
271 case CursorHandleNotShown:
272 if (m_cursorHandle != null) {
273 m_cursorHandle.hide();
274 m_cursorHandle = null;
275 }
276 if (m_rightSelectionHandle != null) {
277 m_rightSelectionHandle.hide();
278 m_leftSelectionHandle.hide();
279 m_rightSelectionHandle = null;
280 m_leftSelectionHandle = null;
281 }
282 break;
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);
288 }
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;
295 }
296 break;
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,
303 rtl);
304 m_rightSelectionHandle = new CursorHandle((Activity) getContext(), this,
305 CursorHandle.IdRightHandle,
306 !rtl ? android.R.attr.textSelectHandleRight :
307 android.R.attr.textSelectHandleLeft,
308 rtl);
309 }
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;
315 }
316 mode |= CursorHandleShowEdit;
317 break;
318 }
319
320 if (!QtClipboardManager.hasClipboardText(getContext()))
321 editButtons &= ~EditContextView.PASTE_BUTTON;
322
323 final boolean setEditPopupPosition = (mode & QtEditText.CursorHandleShowEdit) ==
324 QtEditText.CursorHandleShowEdit && editButtons != 0;
325 if (setEditPopupPosition)
326 m_editPopupMenu.setPosition(editX, editY, editButtons);
327 else
328 m_editPopupMenu.hide();
329 }
330
331 private boolean isDisablePredictiveTextWorkaround(int inputHints)
332 {
333 return (inputHints & ImhNoPredictiveText) != 0 &&
334 System.getenv("QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT") != null;
335 }
336}
QPainter Context
static const QString context()
Definition java.cpp:396
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
@ ImhPreferUppercase
@ ImhPreferLatin
@ ImhUrlCharactersOnly
@ ImhPreferLowercase
@ ImhTime
@ ImhFormattedNumbersOnly
@ ImhMultiLine
@ ImhLatinOnly
@ ImhUppercaseOnly
@ ImhNoPredictiveText
@ ImhDigitsOnly
@ ImhSensitiveData
@ ImhLowercaseOnly
@ ImhEmailCharactersOnly
@ ImhHiddenText
@ ImhDecimaNumbersOnly
@ ImhNoAutoUppercase
@ ImhDialableCharactersOnly
@ ImhDate
@ ImhPreferNumbers
GLenum mode
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint GLfloat GLfloat GLfloat x1
struct _cl_event * event
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2