Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
QtInputConnection.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
5package org.qtproject.qt.android;
6
7import android.content.Context;
8import android.os.Build;
9import android.view.WindowMetrics;
10import android.view.inputmethod.BaseInputConnection;
11import android.view.inputmethod.CompletionInfo;
12import android.view.inputmethod.ExtractedText;
13import android.view.inputmethod.ExtractedTextRequest;
14import android.view.inputmethod.InputMethodManager;
15import android.view.KeyEvent;
16import android.graphics.Rect;
17import android.app.Activity;
18import android.util.DisplayMetrics;
19
20class QtExtractedText
21{
22 public int partialEndOffset;
23 public int partialStartOffset;
24 public int selectionEnd;
25 public int selectionStart;
26 public int startOffset;
27 public String text;
28}
29
30class QtNativeInputConnection
31{
32 static native boolean beginBatchEdit();
33 static native boolean endBatchEdit();
34 static native boolean commitText(String text, int newCursorPosition);
35 static native boolean commitCompletion(String text, int position);
36 static native boolean deleteSurroundingText(int leftLength, int rightLength);
37 static native boolean finishComposingText();
38 static native int getCursorCapsMode(int reqModes);
39 static native QtExtractedText getExtractedText(int hintMaxChars, int hintMaxLines, int flags);
40 static native String getSelectedText(int flags);
41 static native String getTextAfterCursor(int length, int flags);
42 static native String getTextBeforeCursor(int length, int flags);
43 static native boolean setComposingText(String text, int newCursorPosition);
44 static native boolean setComposingRegion(int start, int end);
45 static native boolean setSelection(int start, int end);
46 static native boolean selectAll();
47 static native boolean cut();
48 static native boolean copy();
49 static native boolean copyURL();
50 static native boolean paste();
51 static native boolean updateCursorPosition();
52}
53
54class HideKeyboardRunnable implements Runnable {
55 private long m_hideTimeStamp = System.nanoTime();
56
57 @Override
58 public void run() {
59 // Check that the keyboard is really no longer there.
60 Activity activity = QtNative.activity();
61 Rect r = new Rect();
62 activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
63
64 int screenHeight = 0;
65 if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
66 DisplayMetrics metrics = new DisplayMetrics();
67 activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
68 screenHeight = metrics.heightPixels;
69 } else {
70 final WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics();
71 screenHeight = maximumWindowMetrics.getBounds().height();
72 }
73 final int kbHeight = screenHeight - r.bottom;
74 if (kbHeight < 100)
75 QtNative.activityDelegate().setKeyboardVisibility(false, m_hideTimeStamp);
76 }
77}
78
79public class QtInputConnection extends BaseInputConnection
80{
81 private static final int ID_SELECT_ALL = android.R.id.selectAll;
82 private static final int ID_CUT = android.R.id.cut;
83 private static final int ID_COPY = android.R.id.copy;
84 private static final int ID_PASTE = android.R.id.paste;
85 private static final int ID_COPY_URL = android.R.id.copyUrl;
86 private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
87 private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
88
89 private QtEditText m_view = null;
90
91 private void setClosing(boolean closing)
92 {
93 if (closing) {
94 m_view.postDelayed(new HideKeyboardRunnable(), 100);
95 } else {
96 QtNative.activityDelegate().setKeyboardVisibility(true, System.nanoTime());
97 }
98 }
99
100 public QtInputConnection(QtEditText targetView)
101 {
102 super(targetView, true);
103 m_view = targetView;
104 }
105
106 @Override
107 public boolean beginBatchEdit()
108 {
109 setClosing(false);
110 return QtNativeInputConnection.beginBatchEdit();
111 }
112
113 @Override
114 public boolean endBatchEdit()
115 {
116 setClosing(false);
117 return QtNativeInputConnection.endBatchEdit();
118 }
119
120 @Override
121 public boolean commitCompletion(CompletionInfo text)
122 {
123 setClosing(false);
124 return QtNativeInputConnection.commitCompletion(text.getText().toString(), text.getPosition());
125 }
126
127 @Override
128 public boolean commitText(CharSequence text, int newCursorPosition)
129 {
130 setClosing(false);
131 return QtNativeInputConnection.commitText(text.toString(), newCursorPosition);
132 }
133
134 @Override
135 public boolean deleteSurroundingText(int leftLength, int rightLength)
136 {
137 setClosing(false);
138 return QtNativeInputConnection.deleteSurroundingText(leftLength, rightLength);
139 }
140
141 @Override
142 public boolean finishComposingText()
143 {
144 // on some/all android devices hide event is not coming, but instead finishComposingText() is called twice
145 setClosing(true);
146 return QtNativeInputConnection.finishComposingText();
147 }
148
149 @Override
150 public int getCursorCapsMode(int reqModes)
151 {
152 return QtNativeInputConnection.getCursorCapsMode(reqModes);
153 }
154
155 @Override
156 public ExtractedText getExtractedText(ExtractedTextRequest request, int flags)
157 {
158 QtExtractedText qExtractedText = QtNativeInputConnection.getExtractedText(request.hintMaxChars,
159 request.hintMaxLines,
160 flags);
161 if (qExtractedText == null)
162 return null;
163
164 ExtractedText extractedText = new ExtractedText();
165 extractedText.partialEndOffset = qExtractedText.partialEndOffset;
166 extractedText.partialStartOffset = qExtractedText.partialStartOffset;
167 extractedText.selectionEnd = qExtractedText.selectionEnd;
168 extractedText.selectionStart = qExtractedText.selectionStart;
169 extractedText.startOffset = qExtractedText.startOffset;
170 extractedText.text = qExtractedText.text;
171 return extractedText;
172 }
173
174 public CharSequence getSelectedText(int flags)
175 {
176 return QtNativeInputConnection.getSelectedText(flags);
177 }
178
179 @Override
180 public CharSequence getTextAfterCursor(int length, int flags)
181 {
182 return QtNativeInputConnection.getTextAfterCursor(length, flags);
183 }
184
185 @Override
186 public CharSequence getTextBeforeCursor(int length, int flags)
187 {
188 return QtNativeInputConnection.getTextBeforeCursor(length, flags);
189 }
190
191 @Override
192 public boolean performContextMenuAction(int id)
193 {
194 switch (id) {
195 case ID_SELECT_ALL:
196 return QtNativeInputConnection.selectAll();
197 case ID_COPY:
198 return QtNativeInputConnection.copy();
199 case ID_COPY_URL:
200 return QtNativeInputConnection.copyURL();
201 case ID_CUT:
202 return QtNativeInputConnection.cut();
203 case ID_PASTE:
204 return QtNativeInputConnection.paste();
205
206 case ID_SWITCH_INPUT_METHOD:
207 InputMethodManager imm = (InputMethodManager)m_view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
208 if (imm != null)
209 imm.showInputMethodPicker();
210
211 return true;
212
213 case ID_ADD_TO_DICTIONARY:
214// TODO
215// String word = m_editable.subSequence(0, m_editable.length()).toString();
216// if (word != null) {
217// Intent i = new Intent("com.android.settings.USER_DICTIONARY_INSERT");
218// i.putExtra("word", word);
219// i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
220// m_view.getContext().startActivity(i);
221// }
222 return true;
223 }
224 return super.performContextMenuAction(id);
225 }
226
227 @Override
228 public boolean sendKeyEvent(KeyEvent event)
229 {
230 // QTBUG-85715
231 // If the sendKeyEvent was invoked, it means that the button not related with composingText was used
232 // In such case composing text (if it exists) should be finished immediately
234 if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER && m_view != null) {
235 KeyEvent fakeEvent;
236 switch (m_view.m_imeOptions) {
237 case android.view.inputmethod.EditorInfo.IME_ACTION_NEXT:
238 fakeEvent = new KeyEvent(event.getDownTime(),
239 event.getEventTime(),
240 event.getAction(),
241 KeyEvent.KEYCODE_TAB,
242 event.getRepeatCount(),
243 event.getMetaState());
244 return super.sendKeyEvent(fakeEvent);
245
246 case android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS:
247 fakeEvent = new KeyEvent(event.getDownTime(),
248 event.getEventTime(),
249 event.getAction(),
250 KeyEvent.KEYCODE_TAB,
251 event.getRepeatCount(),
252 KeyEvent.META_SHIFT_ON);
253 return super.sendKeyEvent(fakeEvent);
254
255 case android.view.inputmethod.EditorInfo.IME_FLAG_NO_ENTER_ACTION:
256 break;
257
258 default:
260 break;
261 }
262 }
263
264 return super.sendKeyEvent(event);
265 }
266
267 @Override
268 public boolean setComposingText(CharSequence text, int newCursorPosition)
269 {
270 setClosing(false);
271 return QtNativeInputConnection.setComposingText(text.toString(), newCursorPosition);
272 }
273
274 @Override
275 public boolean setComposingRegion(int start, int end)
276 {
277 setClosing(false);
278 return QtNativeInputConnection.setComposingRegion(start, end);
279 }
280
281 @Override
282 public boolean setSelection(int start, int end)
283 {
284 setClosing(false);
285 return QtNativeInputConnection.setSelection(start, end);
286 }
287}
boolean setKeyboardVisibility(boolean visibility, long timeStamp)
CharSequence getTextAfterCursor(int length, int flags)
boolean commitText(CharSequence text, int newCursorPosition)
boolean setComposingText(CharSequence text, int newCursorPosition)
ExtractedText getExtractedText(ExtractedTextRequest request, int flags)
CharSequence getTextBeforeCursor(int length, int flags)
boolean deleteSurroundingText(int leftLength, int rightLength)
static QtActivityDelegate activityDelegate()
QString text
Q_CORE_EXPORT QtJniTypes::Activity activity()
auto run(QThreadPool *pool, Function &&f, Args &&...args)
constexpr OutputIterator copy(InputIterator first, InputIterator last, OutputIterator dest)
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLbitfield flags
GLuint start
struct _cl_event * event
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QNetworkRequest request(url)