Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
QtNative.java
Go to the documentation of this file.
1// Copyright (C) 2016 BogDan Vatra <bogdan@kde.org>
2// Copyright (C) 2016 The Qt Company Ltd.
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 java.io.File;
8import java.io.FileDescriptor;
9import java.io.FileNotFoundException;
10import java.util.ArrayList;
11import java.util.Arrays;
12import java.util.Objects;
13import java.util.concurrent.Semaphore;
14
15import android.app.Activity;
16import android.app.Service;
17import android.content.Context;
18import android.content.ContentResolver;
19import android.content.Intent;
20import android.content.pm.PackageManager;
21import android.content.pm.ApplicationInfo;
22import android.content.UriPermission;
23import android.net.Uri;
24import android.os.Build;
25import android.os.Handler;
26import android.os.IBinder;
27import android.os.Looper;
28import android.system.Os;
29import android.content.ClipboardManager;
30import android.content.ClipData;
31import android.content.ClipDescription;
32import android.os.ParcelFileDescriptor;
33import android.util.Log;
34import android.view.ContextMenu;
35import android.view.KeyEvent;
36import android.view.Menu;
37import android.view.MotionEvent;
38import android.view.View;
39import android.view.InputDevice;
40import android.view.Display;
41import android.hardware.display.DisplayManager;
42import android.database.Cursor;
43import android.provider.DocumentsContract;
44
45import java.lang.reflect.Method;
46import java.security.KeyStore;
47import java.security.cert.X509Certificate;
48import java.util.Iterator;
49import java.util.List;
50import javax.net.ssl.TrustManagerFactory;
51import javax.net.ssl.TrustManager;
52import javax.net.ssl.X509TrustManager;
53
54import android.util.Size;
55import android.util.DisplayMetrics;
56import android.view.WindowManager;
57import android.view.WindowMetrics;
58import android.graphics.Rect;
59
60public class QtNative
61{
62 private static Activity m_activity = null;
63 private static boolean m_activityPaused = false;
64 private static Service m_service = null;
65 private static QtActivityDelegate m_activityDelegate = null;
66 private static QtServiceDelegate m_serviceDelegate = null;
67 public static Object m_mainActivityMutex = new Object(); // mutex used to synchronize runnable operations
68
69 public static final String QtTAG = "Qt JAVA"; // string used for Log.x
70 private static ArrayList<Runnable> m_lostActions = new ArrayList<Runnable>(); // a list containing all actions which could not be performed (e.g. the main activity is destroyed, etc.)
71 private static boolean m_started = false;
72 private static boolean m_isKeyboardHiding = false;
73 private static int m_displayMetricsScreenWidthPixels = 0;
74 private static int m_displayMetricsScreenHeightPixels = 0;
75 private static int m_displayMetricsAvailableLeftPixels = 0;
76 private static int m_displayMetricsAvailableTopPixels = 0;
77 private static int m_displayMetricsAvailableWidthPixels = 0;
78 private static int m_displayMetricsAvailableHeightPixels = 0;
79 private static float m_displayMetricsRefreshRate = 60;
80 private static double m_displayMetricsXDpi = .0;
81 private static double m_displayMetricsYDpi = .0;
82 private static double m_displayMetricsScaledDensity = 1.0;
83 private static double m_displayMetricsDensity = 1.0;
84 private static int m_oldx, m_oldy;
85 private static final int m_moveThreshold = 0;
86 private static ClipboardManager m_clipboardManager = null;
87 private static Method m_checkSelfPermissionMethod = null;
88 private static Boolean m_tabletEventSupported = null;
89 private static boolean m_usePrimaryClip = false;
90 public static QtThread m_qtThread = new QtThread();
91 private static final int KEYBOARD_HEIGHT_THRESHOLD = 100;
92
93 private static final String INVALID_OR_NULL_URI_ERROR_MESSAGE = "Received invalid/null Uri";
94
95 private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
96 @Override
97 public void run() {
99 }
100 };
101
102 public static boolean isStarted()
103 {
104 boolean hasActivity = m_activity != null && m_activityDelegate != null;
105 boolean hasService = m_service != null && m_serviceDelegate != null;
106 return m_started && (hasActivity || hasService);
107 }
108
109 private static ClassLoader m_classLoader = null;
110 public static ClassLoader classLoader()
111 {
112 return m_classLoader;
113 }
114
115 public static void setClassLoader(ClassLoader classLoader)
116 {
117 m_classLoader = classLoader;
118 }
119
120 public static Activity activity()
121 {
122 synchronized (m_mainActivityMutex) {
123 return m_activity;
124 }
125 }
126
127 public static Service service()
128 {
129 synchronized (m_mainActivityMutex) {
130 return m_service;
131 }
132 }
133
134
136 {
137 synchronized (m_mainActivityMutex) {
138 return m_activityDelegate;
139 }
140 }
141
143 {
144 synchronized (m_mainActivityMutex) {
145 return m_serviceDelegate;
146 }
147 }
148
149 public static String[] getStringArray(String joinedString)
150 {
151 return joinedString.split(",");
152 }
153
154 private static String getCurrentMethodNameLog()
155 {
156 return new Exception().getStackTrace()[1].getMethodName() + ": ";
157 }
158
159 private static Uri getUriWithValidPermission(Context context, String uri, String openMode)
160 {
161 Uri parsedUri;
162 try {
163 parsedUri = Uri.parse(uri);
164 } catch (NullPointerException e) {
165 e.printStackTrace();
166 return null;
167 }
168
169 try {
170 String scheme = parsedUri.getScheme();
171
172 // We only want to check permissions for content Uris
173 if (scheme.compareTo("content") != 0)
174 return parsedUri;
175
176 List<UriPermission> permissions = context.getContentResolver().getPersistedUriPermissions();
177 String uriStr = parsedUri.getPath();
178
179 for (int i = 0; i < permissions.size(); ++i) {
180 Uri iterUri = permissions.get(i).getUri();
181 boolean isRequestPermission = permissions.get(i).isReadPermission();
182
183 if (!openMode.equals("r"))
184 isRequestPermission = permissions.get(i).isWritePermission();
185
186 if (iterUri.getPath().equals(uriStr) && isRequestPermission)
187 return iterUri;
188 }
189
190 // if we only have transient permissions on uri all the above will fail,
191 // but we will be able to read the file anyway, so continue with uri here anyway
192 // and check for SecurityExceptions later
193 return parsedUri;
194 } catch (SecurityException e) {
195 Log.e(QtTAG, getCurrentMethodNameLog() + e.toString());
196 return parsedUri;
197 }
198 }
199
200 public static boolean openURL(Context context, String url, String mime)
201 {
202 final Uri uri = getUriWithValidPermission(context, url, "r");
203 if (uri == null) {
204 Log.e(QtTAG, getCurrentMethodNameLog() + INVALID_OR_NULL_URI_ERROR_MESSAGE);
205 return false;
206 }
207
208 try {
209 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
210 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
211 if (!mime.isEmpty())
212 intent.setDataAndType(uri, mime);
213
214 activity().startActivity(intent);
215
216 return true;
217 } catch (Exception e) {
218 Log.e(QtTAG, getCurrentMethodNameLog() + e.toString());
219 return false;
220 }
221 }
222
223 // this method loads full path libs
224 public static void loadQtLibraries(final ArrayList<String> libraries)
225 {
226 m_qtThread.run(new Runnable() {
227 @Override
228 public void run() {
229 if (libraries == null)
230 return;
231 for (String libName : libraries) {
232 try {
233 File f = new File(libName);
234 if (f.exists())
235 System.load(libName);
236 else
237 Log.i(QtTAG, "Can't find '" + libName + "'");
238 } catch (SecurityException e) {
239 Log.i(QtTAG, "Can't load '" + libName + "'", e);
240 } catch (Exception e) {
241 Log.i(QtTAG, "Can't load '" + libName + "'", e);
242 }
243 }
244 }
245 });
246 }
247
248 // this method loads bundled libs by name.
249 public static void loadBundledLibraries(final ArrayList<String> libraries, final String nativeLibraryDir)
250 {
251 m_qtThread.run(new Runnable() {
252 @Override
253 public void run() {
254 if (libraries == null)
255 return;
256
257 for (String libName : libraries) {
258 try {
259 String libNameTemplate = "lib" + libName + ".so";
260 File f = new File(nativeLibraryDir + libNameTemplate);
261 if (!f.exists()) {
262 Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
263 try {
264 ApplicationInfo info = getContext().getApplicationContext().getPackageManager()
265 .getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
266 String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir;
267 if (info.metaData.containsKey("android.app.system_libs_prefix"))
268 systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix");
269 f = new File(systemLibraryDir + libNameTemplate);
270 } catch (Exception e) {
271 e.printStackTrace();
272 }
273 }
274 if (f.exists())
275 System.load(f.getAbsolutePath());
276 else
277 Log.i(QtTAG, "Can't find '" + f.getAbsolutePath());
278 } catch (Exception e) {
279 Log.i(QtTAG, "Can't load '" + libName + "'", e);
280 }
281 }
282 }
283 });
284 }
285
286 public static String loadMainLibrary(final String mainLibrary, final String nativeLibraryDir)
287 {
288 final String[] res = new String[1];
289 res[0] = null;
290 m_qtThread.run(new Runnable() {
291 @Override
292 public void run() {
293 try {
294 String mainLibNameTemplate = "lib" + mainLibrary + ".so";
295 File f = new File(nativeLibraryDir + mainLibNameTemplate);
296 if (!f.exists()) {
297 try {
298 ApplicationInfo info = getContext().getApplicationContext().getPackageManager()
299 .getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
300 String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir;
301 if (info.metaData.containsKey("android.app.system_libs_prefix"))
302 systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix");
303 f = new File(systemLibraryDir + mainLibNameTemplate);
304 } catch (Exception e) {
305 e.printStackTrace();
306 return;
307 }
308 }
309 if (!f.exists())
310 return;
311 System.load(f.getAbsolutePath());
312 res[0] = f.getAbsolutePath();
313 } catch (Exception e) {
314 Log.e(QtTAG, "Can't load '" + mainLibrary + "'", e);
315 }
316 }
317 });
318 return res[0];
319 }
320
321 public static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate)
322 {
323 synchronized (m_mainActivityMutex) {
324 m_activity = qtMainActivity;
325 m_activityDelegate = qtActivityDelegate;
326 }
327 }
328
329 public static void setService(Service qtMainService, QtServiceDelegate qtServiceDelegate)
330 {
331 synchronized (m_mainActivityMutex) {
332 m_service = qtMainService;
333 m_serviceDelegate = qtServiceDelegate;
334 }
335 }
336
337 public static void setApplicationState(int state)
338 {
339 synchronized (m_mainActivityMutex) {
340 switch (state) {
342 m_activityPaused = false;
343 Iterator<Runnable> itr = m_lostActions.iterator();
344 while (itr.hasNext())
345 runAction(itr.next());
346 m_lostActions.clear();
347 break;
348 default:
349 m_activityPaused = true;
350 break;
351 }
352 }
354 }
355
356 private static void runAction(Runnable action)
357 {
358 synchronized (m_mainActivityMutex) {
359 final Looper mainLooper = Looper.getMainLooper();
360 final Handler handler = new Handler(mainLooper);
361 final boolean active = (m_activity != null && !m_activityPaused) || m_service != null;
362 if (!active || mainLooper == null || !handler.post(action))
363 m_lostActions.add(action);
364 }
365 }
366
367 private static void runPendingCppRunnablesOnAndroidThread()
368 {
369 synchronized (m_mainActivityMutex) {
370 if (m_activity != null) {
371 if (!m_activityPaused)
372 m_activity.runOnUiThread(runPendingCppRunnablesRunnable);
373 else
374 runAction(runPendingCppRunnablesRunnable);
375 } else {
376 final Looper mainLooper = Looper.getMainLooper();
377 final Thread looperThread = mainLooper.getThread();
378 if (looperThread.equals(Thread.currentThread())) {
379 runPendingCppRunnablesRunnable.run();
380 } else {
381 final Handler handler = new Handler(mainLooper);
382 handler.post(runPendingCppRunnablesRunnable);
383 }
384 }
385 }
386 }
387
388 private static void setViewVisibility(final View view, final boolean visible)
389 {
390 runAction(new Runnable() {
391 @Override
392 public void run() {
393 view.setVisibility(visible ? View.VISIBLE : View.GONE);
394 }
395 });
396 }
397
398 public static Display getDisplay(int displayId)
399 {
400 Context context = getContext();
401 DisplayManager displayManager =
402 (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
403 if (displayManager != null) {
404 return displayManager.getDisplay(displayId);
405 }
406 return null;
407 }
408
409 public static List<Display> getAvailableDisplays()
410 {
411 Context context = getContext();
412 DisplayManager displayManager =
413 (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
414 if (displayManager != null) {
415 Display[] displays = displayManager.getDisplays();
416 return Arrays.asList(displays);
417 }
418 return new ArrayList<Display>();
419 }
420
421 public static Size getDisplaySize(Context displayContext, Display display)
422 {
423 if (Build.VERSION.SDK_INT < 31) {
424 DisplayMetrics realMetrics = new DisplayMetrics();
425 display.getRealMetrics(realMetrics);
426 return new Size(realMetrics.widthPixels, realMetrics.heightPixels);
427 }
428
429 Context windowsContext = displayContext.createWindowContext(
430 WindowManager.LayoutParams.TYPE_APPLICATION, null);
431 WindowManager displayMgr =
432 (WindowManager) windowsContext.getSystemService(Context.WINDOW_SERVICE);
433 WindowMetrics windowsMetrics = displayMgr.getCurrentWindowMetrics();
434 Rect bounds = windowsMetrics.getBounds();
435 return new Size(bounds.width(), bounds.height());
436 }
437
438 public static boolean startApplication(String params, String mainLib) throws Exception
439 {
440 if (params == null)
441 params = "-platform\tandroid";
442
443 final boolean[] res = new boolean[1];
444 res[0] = false;
445 synchronized (m_mainActivityMutex) {
446 if (params.length() > 0 && !params.startsWith("\t"))
447 params = "\t" + params;
448 final String qtParams = mainLib + params;
449 m_qtThread.run(new Runnable() {
450 @Override
451 public void run() {
452 res[0] = startQtAndroidPlugin(qtParams);
454 m_displayMetricsScreenWidthPixels, m_displayMetricsScreenHeightPixels,
455 m_displayMetricsAvailableLeftPixels, m_displayMetricsAvailableTopPixels,
456 m_displayMetricsAvailableWidthPixels,
457 m_displayMetricsAvailableHeightPixels, m_displayMetricsXDpi,
458 m_displayMetricsYDpi, m_displayMetricsScaledDensity,
459 m_displayMetricsDensity, m_displayMetricsRefreshRate);
460 }
461 });
462 m_qtThread.post(new Runnable() {
463 @Override
464 public void run() {
466 }
467 });
469 m_started = true;
470 }
471 return res[0];
472 }
473
474 public static void setApplicationDisplayMetrics(int screenWidthPixels, int screenHeightPixels,
475 int availableLeftPixels, int availableTopPixels,
476 int availableWidthPixels,
477 int availableHeightPixels, double XDpi,
478 double YDpi, double scaledDensity,
479 double density, float refreshRate)
480 {
481 /* Fix buggy dpi report */
482 if (XDpi < android.util.DisplayMetrics.DENSITY_LOW)
483 XDpi = android.util.DisplayMetrics.DENSITY_LOW;
484 if (YDpi < android.util.DisplayMetrics.DENSITY_LOW)
485 YDpi = android.util.DisplayMetrics.DENSITY_LOW;
486
487 synchronized (m_mainActivityMutex) {
488 if (m_started) {
489 setDisplayMetrics(screenWidthPixels, screenHeightPixels, availableLeftPixels,
490 availableTopPixels, availableWidthPixels, availableHeightPixels,
491 XDpi, YDpi, scaledDensity, density, refreshRate);
492 } else {
493 m_displayMetricsScreenWidthPixels = screenWidthPixels;
494 m_displayMetricsScreenHeightPixels = screenHeightPixels;
495 m_displayMetricsAvailableLeftPixels = availableLeftPixels;
496 m_displayMetricsAvailableTopPixels = availableTopPixels;
497 m_displayMetricsAvailableWidthPixels = availableWidthPixels;
498 m_displayMetricsAvailableHeightPixels = availableHeightPixels;
499 m_displayMetricsXDpi = XDpi;
500 m_displayMetricsYDpi = YDpi;
501 m_displayMetricsScaledDensity = scaledDensity;
502 m_displayMetricsDensity = density;
503 m_displayMetricsRefreshRate = refreshRate;
504 }
505 }
506 }
507
508
509
510 // application methods
511 public static native boolean startQtAndroidPlugin(String params);
512 public static native void startQtApplication();
513 public static native void waitForServiceSetup();
514 public static native void quitQtCoreApplication();
515 public static native void quitQtAndroidPlugin();
516 public static native void terminateQt();
517 public static native boolean updateNativeActivity();
518 // application methods
519
520 public static void quitApp()
521 {
522 runAction(new Runnable() {
523 @Override
524 public void run() {
526 if (m_activity != null)
527 m_activity.finish();
528 if (m_service != null)
529 m_service.stopSelf();
530
531 m_started = false;
532 }
533 });
534 }
535
536 //@ANDROID-9
537 static private int getAction(int index, MotionEvent event)
538 {
539 int action = event.getActionMasked();
540 if (action == MotionEvent.ACTION_MOVE) {
541 int hsz = event.getHistorySize();
542 if (hsz > 0) {
543 float x = event.getX(index);
544 float y = event.getY(index);
545 for (int h = 0; h < hsz; ++h) {
546 if ( event.getHistoricalX(index, h) != x ||
547 event.getHistoricalY(index, h) != y )
548 return 1;
549 }
550 return 2;
551 }
552 return 1;
553 }
554 if (action == MotionEvent.ACTION_DOWN
555 || action == MotionEvent.ACTION_POINTER_DOWN && index == event.getActionIndex()) {
556 return 0;
557 } else if (action == MotionEvent.ACTION_UP
558 || action == MotionEvent.ACTION_POINTER_UP && index == event.getActionIndex()) {
559 return 3;
560 }
561 return 2;
562 }
563 //@ANDROID-9
564
565 static public void sendTouchEvent(MotionEvent event, int id)
566 {
567 int pointerType = 0;
568
569 if (m_tabletEventSupported == null)
570 m_tabletEventSupported = isTabletEventSupported();
571
572 switch (event.getToolType(0)) {
573 case MotionEvent.TOOL_TYPE_STYLUS:
574 pointerType = 1; // QTabletEvent::Pen
575 break;
576 case MotionEvent.TOOL_TYPE_ERASER:
577 pointerType = 3; // QTabletEvent::Eraser
578 break;
579 }
580
581 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
583 } else if (m_tabletEventSupported && pointerType != 0) {
584 tabletEvent(id, event.getDeviceId(), event.getEventTime(), event.getAction(), pointerType,
585 event.getButtonState(), event.getX(), event.getY(), event.getPressure());
586 } else {
587 touchBegin(id);
588 for (int i = 0; i < event.getPointerCount(); ++i) {
589 touchAdd(id,
590 event.getPointerId(i),
591 getAction(i, event),
592 i == 0,
593 (int)event.getX(i),
594 (int)event.getY(i),
595 event.getTouchMajor(i),
596 event.getTouchMinor(i),
597 event.getOrientation(i),
598 event.getPressure(i));
599 }
600
601 switch (event.getAction()) {
602 case MotionEvent.ACTION_DOWN:
603 touchEnd(id, 0);
604 break;
605
606 case MotionEvent.ACTION_UP:
607 touchEnd(id, 2);
608 break;
609
610 case MotionEvent.ACTION_CANCEL:
611 touchCancel(id);
612 break;
613
614 default:
615 touchEnd(id, 1);
616 }
617 }
618 }
619
620 static public void sendTrackballEvent(MotionEvent event, int id)
621 {
623 }
624
625 static public boolean sendGenericMotionEvent(MotionEvent event, int id)
626 {
627 if (((event.getAction() & (MotionEvent.ACTION_SCROLL | MotionEvent.ACTION_HOVER_MOVE)) == 0)
628 || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) {
629 return false;
630 }
631
632 return sendMouseEvent(event, id);
633 }
634
635 static public boolean sendMouseEvent(MotionEvent event, int id)
636 {
637 switch (event.getActionMasked()) {
638 case MotionEvent.ACTION_UP:
639 mouseUp(id, (int) event.getX(), (int) event.getY());
640 break;
641
642 case MotionEvent.ACTION_DOWN:
643 mouseDown(id, (int) event.getX(), (int) event.getY());
644 m_oldx = (int) event.getX();
645 m_oldy = (int) event.getY();
646 break;
647 case MotionEvent.ACTION_HOVER_MOVE:
648 case MotionEvent.ACTION_MOVE:
649 if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
650 mouseMove(id, (int) event.getX(), (int) event.getY());
651 } else {
652 int dx = (int) (event.getX() - m_oldx);
653 int dy = (int) (event.getY() - m_oldy);
654 if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
655 mouseMove(id, (int) event.getX(), (int) event.getY());
656 m_oldx = (int) event.getX();
657 m_oldy = (int) event.getY();
658 }
659 }
660 break;
661 case MotionEvent.ACTION_SCROLL:
662 mouseWheel(id, (int) event.getX(), (int) event.getY(),
663 event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL));
664 break;
665 default:
666 return false;
667 }
668 return true;
669 }
670
671 public static Context getContext() {
672 if (m_activity != null)
673 return m_activity;
674 return m_service;
675 }
676
677 public static int checkSelfPermission(String permission)
678 {
679 int perm = PackageManager.PERMISSION_DENIED;
680 synchronized (m_mainActivityMutex) {
681 Context context = getContext();
682 PackageManager pm = context.getPackageManager();
683 perm = pm.checkPermission(permission, context.getPackageName());
684 }
685
686 return perm;
687 }
688
689 private static void updateSelection(final int selStart,
690 final int selEnd,
691 final int candidatesStart,
692 final int candidatesEnd)
693 {
694 runAction(new Runnable() {
695 @Override
696 public void run() {
697 if (m_activityDelegate != null)
698 m_activityDelegate.updateSelection(selStart, selEnd, candidatesStart, candidatesEnd);
699 }
700 });
701 }
702
703 private static int getSelectHandleWidth()
704 {
705 return m_activityDelegate.getSelectHandleWidth();
706 }
707
708 private static void updateHandles(final int mode,
709 final int editX,
710 final int editY,
711 final int editButtons,
712 final int x1,
713 final int y1,
714 final int x2,
715 final int y2,
716 final boolean rtl)
717 {
718 runAction(new Runnable() {
719 @Override
720 public void run() {
721 m_activityDelegate.updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl);
722 }
723 });
724 }
725
726 private static void showSoftwareKeyboard(final int x,
727 final int y,
728 final int width,
729 final int height,
730 final int inputHints,
731 final int enterKeyType)
732 {
733 runAction(new Runnable() {
734 @Override
735 public void run() {
736 if (m_activityDelegate != null)
737 m_activityDelegate.showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType);
738 }
739 });
740 }
741
742 private static void resetSoftwareKeyboard()
743 {
744 runAction(new Runnable() {
745 @Override
746 public void run() {
747 if (m_activityDelegate != null)
748 m_activityDelegate.resetSoftwareKeyboard();
749 }
750 });
751 }
752
753 private static void hideSoftwareKeyboard()
754 {
755 m_isKeyboardHiding = true;
756 runAction(new Runnable() {
757 @Override
758 public void run() {
759 if (m_activityDelegate != null)
760 m_activityDelegate.hideSoftwareKeyboard();
761 }
762 });
763 }
764
765 private static void setSystemUiVisibility(final int systemUiVisibility)
766 {
767 runAction(new Runnable() {
768 @Override
769 public void run() {
770 if (m_activityDelegate != null) {
771 m_activityDelegate.setSystemUiVisibility(systemUiVisibility);
772 }
773 updateWindow();
774 }
775 });
776 }
777
778 public static boolean isSoftwareKeyboardVisible()
779 {
780 return m_activityDelegate.isKeyboardVisible() && !m_isKeyboardHiding;
781 }
782
783 private static void notifyAccessibilityLocationChange(final int viewId)
784 {
785 runAction(new Runnable() {
786 @Override
787 public void run() {
788 if (m_activityDelegate != null) {
789 m_activityDelegate.notifyAccessibilityLocationChange(viewId);
790 }
791 }
792 });
793 }
794
795 private static void notifyObjectHide(final int viewId, final int parentId)
796 {
797 runAction(new Runnable() {
798 @Override
799 public void run() {
800 if (m_activityDelegate != null) {
801 m_activityDelegate.notifyObjectHide(viewId, parentId);
802 }
803 }
804 });
805 }
806
807 private static void notifyObjectFocus(final int viewId)
808 {
809 runAction(new Runnable() {
810 @Override
811 public void run() {
812 if (m_activityDelegate != null) {
813 m_activityDelegate.notifyObjectFocus(viewId);
814 }
815 }
816 });
817 }
818
819 private static void notifyValueChanged(int viewId, String value)
820 {
821 runAction(new Runnable() {
822 @Override
823 public void run() {
824 if (m_activityDelegate != null) {
825 m_activityDelegate.notifyValueChanged(viewId, value);
826 }
827 }
828 });
829 }
830
831 private static void notifyScrolledEvent(final int viewId)
832 {
833 runAction(new Runnable() {
834 @Override
835 public void run() {
836 if (m_activityDelegate != null) {
837 m_activityDelegate.notifyScrolledEvent(viewId);
838 }
839 }
840 });
841 }
842
843 public static void notifyQtAndroidPluginRunning(final boolean running)
844 {
845 m_activityDelegate.notifyQtAndroidPluginRunning(running);
846 }
847
848 private static void registerClipboardManager()
849 {
850 if (m_service == null || m_activity != null) { // Avoid freezing if only service
851 final Semaphore semaphore = new Semaphore(0);
852 runAction(new Runnable() {
853 @Override
854 public void run() {
855 if (m_activity != null)
856 m_clipboardManager = (android.content.ClipboardManager) m_activity.getSystemService(Context.CLIPBOARD_SERVICE);
857 if (m_clipboardManager != null) {
858 m_clipboardManager.addPrimaryClipChangedListener(new ClipboardManager.OnPrimaryClipChangedListener() {
859 public void onPrimaryClipChanged() {
861 }
862 });
863 }
864 semaphore.release();
865 }
866 });
867 try {
868 semaphore.acquire();
869 } catch (Exception e) {
870 e.printStackTrace();
871 }
872 }
873 }
874
875 private static void clearClipData()
876 {
877 if (m_clipboardManager != null) {
878 if (Build.VERSION.SDK_INT >= 28) {
879 m_clipboardManager.clearPrimaryClip();
880 } else {
881 String[] mimeTypes = { ClipDescription.MIMETYPE_UNKNOWN };
882 ClipData data = new ClipData("", mimeTypes, new ClipData.Item(new Intent()));
883 m_clipboardManager.setPrimaryClip(data);
884 }
885 }
886 m_usePrimaryClip = false;
887 }
888 private static void setClipboardText(String text)
889 {
890 if (m_clipboardManager != null) {
891 ClipData clipData = ClipData.newPlainText("text/plain", text);
892 updatePrimaryClip(clipData);
893 }
894 }
895
896 public static boolean hasClipboardText()
897 {
898 return hasClipboardMimeType("text/plain");
899 }
900
901 private static String getClipboardText()
902 {
903 try {
904 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
905 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
906 for (int i = 0; i < primaryClip.getItemCount(); ++i)
907 if (primaryClip.getItemAt(i).getText() != null)
908 return primaryClip.getItemAt(i).getText().toString();
909 }
910 } catch (Exception e) {
911 Log.e(QtTAG, "Failed to get clipboard data", e);
912 }
913 return "";
914 }
915
916 private static void updatePrimaryClip(ClipData clipData)
917 {
918 try {
919 if (m_usePrimaryClip) {
920 ClipData clip = m_clipboardManager.getPrimaryClip();
921 if (Build.VERSION.SDK_INT >= 26) {
922 Objects.requireNonNull(clip).addItem(m_activity.getContentResolver(), clipData.getItemAt(0));
923 } else {
924 Objects.requireNonNull(clip).addItem(clipData.getItemAt(0));
925 }
926 m_clipboardManager.setPrimaryClip(clip);
927 } else {
928 m_clipboardManager.setPrimaryClip(clipData);
929 m_usePrimaryClip = true;
930 }
931 } catch (Exception e) {
932 Log.e(QtTAG, "Failed to set clipboard data", e);
933 }
934 }
935
936 private static void setClipboardHtml(String text, String html)
937 {
938 if (m_clipboardManager != null) {
939 ClipData clipData = ClipData.newHtmlText("text/html", text, html);
940 updatePrimaryClip(clipData);
941 }
942 }
943
944 private static boolean hasClipboardMimeType(String mimeType)
945 {
946 if (m_clipboardManager == null)
947 return false;
948
949 ClipDescription description = m_clipboardManager.getPrimaryClipDescription();
950 // getPrimaryClipDescription can fail if the app does not have input focus
951 if (description == null)
952 return false;
953
954 for (int i = 0; i < description.getMimeTypeCount(); ++i) {
955 String itemMimeType = description.getMimeType(i);
956 if (itemMimeType.equals(mimeType))
957 return true;
958 }
959 return false;
960 }
961
962 public static boolean hasClipboardHtml()
963 {
964 return hasClipboardMimeType("text/html");
965 }
966
967 private static String getClipboardHtml()
968 {
969 try {
970 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
971 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
972 for (int i = 0; i < primaryClip.getItemCount(); ++i)
973 if (primaryClip.getItemAt(i).getHtmlText() != null)
974 return primaryClip.getItemAt(i).getHtmlText().toString();
975 }
976 } catch (Exception e) {
977 Log.e(QtTAG, "Failed to get clipboard data", e);
978 }
979 return "";
980 }
981
982 private static void setClipboardUri(String uriString)
983 {
984 if (m_clipboardManager != null) {
985 ClipData clipData = ClipData.newUri(m_activity.getContentResolver(), "text/uri-list",
986 Uri.parse(uriString));
987 updatePrimaryClip(clipData);
988 }
989 }
990
991 public static boolean hasClipboardUri()
992 {
993 return hasClipboardMimeType("text/uri-list");
994 }
995
996 private static String[] getClipboardUris()
997 {
998 ArrayList<String> uris = new ArrayList<String>();
999 try {
1000 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
1001 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
1002 for (int i = 0; i < primaryClip.getItemCount(); ++i)
1003 if (primaryClip.getItemAt(i).getUri() != null)
1004 uris.add(primaryClip.getItemAt(i).getUri().toString());
1005 }
1006 } catch (Exception e) {
1007 Log.e(QtTAG, "Failed to get clipboard data", e);
1008 }
1009 String[] strings = new String[uris.size()];
1010 strings = uris.toArray(strings);
1011 return strings;
1012 }
1013
1014 private static void openContextMenu(final int x, final int y, final int w, final int h)
1015 {
1016 runAction(new Runnable() {
1017 @Override
1018 public void run() {
1019 if (m_activityDelegate != null)
1020 m_activityDelegate.openContextMenu(x, y, w, h);
1021 }
1022 });
1023 }
1024
1025 private static void closeContextMenu()
1026 {
1027 runAction(new Runnable() {
1028 @Override
1029 public void run() {
1030 if (m_activityDelegate != null)
1031 m_activityDelegate.closeContextMenu();
1032 }
1033 });
1034 }
1035
1036 private static void resetOptionsMenu()
1037 {
1038 runAction(new Runnable() {
1039 @Override
1040 public void run() {
1041 if (m_activityDelegate != null)
1042 m_activityDelegate.resetOptionsMenu();
1043 }
1044 });
1045 }
1046
1047 private static void openOptionsMenu()
1048 {
1049 runAction(new Runnable() {
1050 @Override
1051 public void run() {
1052 if (m_activity != null)
1053 m_activity.openOptionsMenu();
1054 }
1055 });
1056 }
1057
1058 private static byte[][] getSSLCertificates()
1059 {
1060 ArrayList<byte[]> certificateList = new ArrayList<byte[]>();
1061
1062 try {
1063 TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
1064 factory.init((KeyStore) null);
1065
1066 for (TrustManager manager : factory.getTrustManagers()) {
1067 if (manager instanceof X509TrustManager) {
1068 X509TrustManager trustManager = (X509TrustManager) manager;
1069
1070 for (X509Certificate certificate : trustManager.getAcceptedIssuers()) {
1071 byte buffer[] = certificate.getEncoded();
1072 certificateList.add(buffer);
1073 }
1074 }
1075 }
1076 } catch (Exception e) {
1077 Log.e(QtTAG, "Failed to get certificates", e);
1078 }
1079
1080 byte[][] certificateArray = new byte[certificateList.size()][];
1081 certificateArray = certificateList.toArray(certificateArray);
1082 return certificateArray;
1083 }
1084
1085 private static void createSurface(final int id, final boolean onTop, final int x, final int y, final int w, final int h, final int imageDepth)
1086 {
1087 runAction(new Runnable() {
1088 @Override
1089 public void run() {
1090 if (m_activityDelegate != null)
1091 m_activityDelegate.createSurface(id, onTop, x, y, w, h, imageDepth);
1092 }
1093 });
1094 }
1095
1096 private static void insertNativeView(final int id, final View view, final int x, final int y, final int w, final int h)
1097 {
1098 runAction(new Runnable() {
1099 @Override
1100 public void run() {
1101 if (m_activityDelegate != null)
1102 m_activityDelegate.insertNativeView(id, view, x, y, w, h);
1103 }
1104 });
1105 }
1106
1107 private static void setSurfaceGeometry(final int id, final int x, final int y, final int w, final int h)
1108 {
1109 runAction(new Runnable() {
1110 @Override
1111 public void run() {
1112 if (m_activityDelegate != null)
1113 m_activityDelegate.setSurfaceGeometry(id, x, y, w, h);
1114 }
1115 });
1116 }
1117
1118 private static void bringChildToFront(final int id)
1119 {
1120 runAction(new Runnable() {
1121 @Override
1122 public void run() {
1123 if (m_activityDelegate != null)
1124 m_activityDelegate.bringChildToFront(id);
1125 }
1126 });
1127 }
1128
1129 private static void bringChildToBack(final int id)
1130 {
1131 runAction(new Runnable() {
1132 @Override
1133 public void run() {
1134 if (m_activityDelegate != null)
1135 m_activityDelegate.bringChildToBack(id);
1136 }
1137 });
1138 }
1139
1140 private static void destroySurface(final int id)
1141 {
1142 runAction(new Runnable() {
1143 @Override
1144 public void run() {
1145 if (m_activityDelegate != null)
1146 m_activityDelegate.destroySurface(id);
1147 }
1148 });
1149 }
1150
1151 private static void initializeAccessibility()
1152 {
1153 runAction(new Runnable() {
1154 @Override
1155 public void run() {
1156 m_activityDelegate.initializeAccessibility();
1157 }
1158 });
1159 }
1160
1161 private static void hideSplashScreen(final int duration)
1162 {
1163 runAction(new Runnable() {
1164 @Override
1165 public void run() {
1166 if (m_activityDelegate != null)
1167 m_activityDelegate.hideSplashScreen(duration);
1168 }
1169 });
1170 }
1171
1172 public static void keyboardVisibilityUpdated(boolean visibility)
1173 {
1174 m_isKeyboardHiding = false;
1175 keyboardVisibilityChanged(visibility);
1176 }
1177
1178 private static String[] listAssetContent(android.content.res.AssetManager asset, String path) {
1179 String [] list;
1180 ArrayList<String> res = new ArrayList<String>();
1181 try {
1182 list = asset.list(path);
1183 if (list.length > 0) {
1184 for (String file : list) {
1185 try {
1186 String[] isDir = asset.list(path.length() > 0 ? path + "/" + file : file);
1187 if (isDir != null && isDir.length > 0)
1188 file += "/";
1189 res.add(file);
1190 } catch (Exception e) {
1191 e.printStackTrace();
1192 }
1193 }
1194 }
1195 } catch (Exception e) {
1196 e.printStackTrace();
1197 }
1198 return res.toArray(new String[res.size()]);
1199 }
1200
1207 public static void setEnvironmentVariable(String key, String value)
1208 {
1209 try {
1210 android.system.Os.setenv(key, value, true);
1211 } catch (Exception e) {
1212 Log.e(QtNative.QtTAG, "Could not set environment variable:" + key + "=" + value);
1213 e.printStackTrace();
1214 }
1215 }
1216
1224 public static void setEnvironmentVariables(String environmentVariables)
1225 {
1226 for (String variable : environmentVariables.split("\t")) {
1227 String[] keyvalue = variable.split("=", 2);
1228 if (keyvalue.length < 2 || keyvalue[0].isEmpty())
1229 continue;
1230
1231 setEnvironmentVariable(keyvalue[0], keyvalue[1]);
1232 }
1233 }
1234
1235 // screen methods
1236 public static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels,
1237 int availableLeftPixels, int availableTopPixels,
1238 int availableWidthPixels, int availableHeightPixels,
1239 double XDpi, double YDpi, double scaledDensity,
1240 double density, float refreshRate);
1241 public static native void handleOrientationChanged(int newRotation, int nativeOrientation);
1242 public static native void handleRefreshRateChanged(float refreshRate);
1243 public static native void handleScreenAdded(int displayId);
1244 public static native void handleScreenChanged(int displayId);
1245 public static native void handleScreenRemoved(int displayId);
1246 // screen methods
1247 public static native void handleUiDarkModeChanged(int newUiMode);
1248
1249 // pointer methods
1250 public static native void mouseDown(int winId, int x, int y);
1251 public static native void mouseUp(int winId, int x, int y);
1252 public static native void mouseMove(int winId, int x, int y);
1253 public static native void mouseWheel(int winId, int x, int y, float hdelta, float vdelta);
1254 public static native void touchBegin(int winId);
1255 public static native void touchAdd(int winId, int pointerId, int action, boolean primary, int x, int y, float major, float minor, float rotation, float pressure);
1256 public static native void touchEnd(int winId, int action);
1257 public static native void touchCancel(int winId);
1258 public static native void longPress(int winId, int x, int y);
1259 // pointer methods
1260
1261 // tablet methods
1262 public static native boolean isTabletEventSupported();
1263 public static native void tabletEvent(int winId, int deviceId, long time, int action, int pointerType, int buttonState, float x, float y, float pressure);
1264 // tablet methods
1265
1266 // keyboard methods
1267 public static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat);
1268 public static native void keyUp(int key, int unicode, int modifier, boolean autoRepeat);
1269 public static native void keyboardVisibilityChanged(boolean visibility);
1270 public static native void keyboardGeometryChanged(int x, int y, int width, int height);
1271 // keyboard methods
1272
1273 // handle methods
1274 public static final int IdCursorHandle = 1;
1275 public static final int IdLeftHandle = 2;
1276 public static final int IdRightHandle = 3;
1277 public static native void handleLocationChanged(int id, int x, int y);
1278 // handle methods
1279
1280 // dispatch events methods
1281 public static native boolean dispatchGenericMotionEvent(MotionEvent ev);
1282 public static native boolean dispatchKeyEvent(KeyEvent event);
1283 // dispatch events methods
1284
1285 // surface methods
1286 public static native void setSurface(int id, Object surface, int w, int h);
1287 // surface methods
1288
1289 // window methods
1290 public static native void updateWindow();
1291 // window methods
1292
1293 // application methods
1294 public static native void updateApplicationState(int state);
1295
1296 // menu methods
1297 public static native boolean onPrepareOptionsMenu(Menu menu);
1298 public static native boolean onOptionsItemSelected(int itemId, boolean checked);
1299 public static native void onOptionsMenuClosed(Menu menu);
1300
1301 public static native void onCreateContextMenu(ContextMenu menu);
1302 public static native void fillContextMenu(Menu menu);
1303 public static native boolean onContextItemSelected(int itemId, boolean checked);
1304 public static native void onContextMenuClosed(Menu menu);
1305 // menu methods
1306
1307 // clipboard methods
1308 public static native void onClipboardDataChanged();
1309 // clipboard methods
1310
1311 // activity methods
1312 public static native void onActivityResult(int requestCode, int resultCode, Intent data);
1313 public static native void onNewIntent(Intent data);
1314
1315 public static native void runPendingCppRunnables();
1316
1317 public static native void sendRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
1318 // activity methods
1319
1320 // service methods
1321 public static native IBinder onBind(Intent intent);
1322 // service methods
1323}
Definition main.cpp:8
qsizetype length() const noexcept
Definition qlist.h:388
void insertNativeView(int id, View view, int x, int y, int w, int h)
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
void notifyObjectHide(int viewId, int parentId)
void notifyValueChanged(int viewId, String value)
void showSoftwareKeyboard(final int x, final int y, final int width, final int height, final int inputHints, final int enterKeyType)
void createSurface(int id, boolean onTop, int x, int y, int w, int h, int imageDepth)
void setSurfaceGeometry(int id, int x, int y, int w, int h)
void openContextMenu(final int x, final int y, final int w, final int h)
void updateHandles(int mode, int editX, int editY, int editButtons, int x1, int y1, int x2, int y2, boolean rtl)
static boolean startApplication(String params, String mainLib)
static native void quitQtAndroidPlugin()
static native void handleScreenAdded(int displayId)
static native void mouseDown(int winId, int x, int y)
static native void setSurface(int id, Object surface, int w, int h)
static native void keyUp(int key, int unicode, int modifier, boolean autoRepeat)
static native IBinder onBind(Intent intent)
static native void touchEnd(int winId, int action)
static Size getDisplaySize(Context displayContext, Display display)
static native void terminateQt()
static void setEnvironmentVariables(String environmentVariables)
static native void mouseUp(int winId, int x, int y)
static native void runPendingCppRunnables()
static ClassLoader classLoader()
static native void handleScreenRemoved(int displayId)
static native void fillContextMenu(Menu menu)
static native void onActivityResult(int requestCode, int resultCode, Intent data)
static void sendTrackballEvent(MotionEvent event, int id)
static native void tabletEvent(int winId, int deviceId, long time, int action, int pointerType, int buttonState, float x, float y, float pressure)
static native void keyboardGeometryChanged(int x, int y, int width, int height)
static boolean openURL(Context context, String url, String mime)
static void setService(Service qtMainService, QtServiceDelegate qtServiceDelegate)
static native void longPress(int winId, int x, int y)
static native void mouseMove(int winId, int x, int y)
static native void sendRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
static native boolean isTabletEventSupported()
static native boolean dispatchGenericMotionEvent(MotionEvent ev)
static void setApplicationState(int state)
static native void touchAdd(int winId, int pointerId, int action, boolean primary, int x, int y, float major, float minor, float rotation, float pressure)
static void keyboardVisibilityUpdated(boolean visibility)
static native void keyboardVisibilityChanged(boolean visibility)
static native void setDisplayMetrics(int screenWidthPixels, int screenHeightPixels, int availableLeftPixels, int availableTopPixels, int availableWidthPixels, int availableHeightPixels, double XDpi, double YDpi, double scaledDensity, double density, float refreshRate)
static native boolean onPrepareOptionsMenu(Menu menu)
static native boolean onContextItemSelected(int itemId, boolean checked)
static QtActivityDelegate activityDelegate()
static String loadMainLibrary(final String mainLibrary, final String nativeLibraryDir)
static native void onCreateContextMenu(ContextMenu menu)
static List< Display > getAvailableDisplays()
static native void quitQtCoreApplication()
static native boolean startQtAndroidPlugin(String params)
static native boolean onOptionsItemSelected(int itemId, boolean checked)
static native void handleUiDarkModeChanged(int newUiMode)
static void notifyQtAndroidPluginRunning(final boolean running)
static native void handleScreenChanged(int displayId)
static String[] getStringArray(String joinedString)
static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate)
static void loadBundledLibraries(final ArrayList< String > libraries, final String nativeLibraryDir)
static native void waitForServiceSetup()
static void setEnvironmentVariable(String key, String value)
static native void handleOrientationChanged(int newRotation, int nativeOrientation)
static Display getDisplay(int displayId)
static native void onNewIntent(Intent data)
static native void startQtApplication()
static native void updateApplicationState(int state)
static boolean isSoftwareKeyboardVisible()
static native boolean dispatchKeyEvent(KeyEvent event)
static native void onClipboardDataChanged()
static native void onContextMenuClosed(Menu menu)
static boolean sendGenericMotionEvent(MotionEvent event, int id)
static native void updateWindow()
static native void mouseWheel(int winId, int x, int y, float hdelta, float vdelta)
static QtServiceDelegate serviceDelegate()
static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat)
static native void handleRefreshRateChanged(float refreshRate)
static native boolean updateNativeActivity()
static void loadQtLibraries(final ArrayList< String > libraries)
static native void onOptionsMenuClosed(Menu menu)
static boolean sendMouseEvent(MotionEvent event, int id)
static int checkSelfPermission(String permission)
static void setApplicationDisplayMetrics(int screenWidthPixels, int screenHeightPixels, int availableLeftPixels, int availableTopPixels, int availableWidthPixels, int availableHeightPixels, double XDpi, double YDpi, double scaledDensity, double density, float refreshRate)
static void sendTouchEvent(MotionEvent event, int id)
static native void handleLocationChanged(int id, int x, int y)
static native void touchBegin(int winId)
static native void touchCancel(int winId)
static void setClassLoader(ClassLoader classLoader)
void run(final Runnable runnable)
Definition QtThread.java:45
void post(final Runnable runnable)
Definition QtThread.java:38
QString text
double e
else opt state
[0]
struct wl_display * display
Definition linuxdmabuf.h:41
auto run(QThreadPool *pool, Function &&f, Args &&...args)
static void * context
static Q_CONSTINIT QBasicAtomicInt running
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const char * mimeType
#define Size(name)
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint index
[2]
GLuint GLfloat GLfloat GLfloat x1
GLsizei const GLchar ** strings
[1]
GLfloat GLfloat f
GLenum GLuint buffer
GLint GLsizei width
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint y
GLfloat GLfloat GLfloat GLfloat h
void ** params
struct _cl_event * event
GLuint res
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
GLsizei const GLchar *const * path
GLenum GLenum variable
struct _XDisplay Display
static QPointingDevice::PointerType pointerType(unsigned currentCursor)
QList< int > list
[14]
QFile file
[0]
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]
application x qt windows mime
[2]
QItemEditorFactory * factory
QMenu menu
[5]
QNetworkAccessManager manager
QQuickView * view
[0]