Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
QtClipboardManager.java
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4package org.qtproject.qt.android;
5
6import android.content.ClipData;
7import android.content.ClipDescription;
8import android.content.ClipboardManager;
9import android.content.Context;
10import android.content.Intent;
11import android.net.Uri;
12import android.os.Build;
13import android.util.Log;
14
15import java.util.ArrayList;
16import java.util.Objects;
17import java.util.concurrent.Semaphore;
18
19class QtClipboardManager
20{
21 public static native void onClipboardDataChanged(long nativePointer);
22
23 private final static String TAG = "QtClipboardManager";
24 private ClipboardManager m_clipboardManager = null;
25 private boolean m_usePrimaryClip = false;
26 private final long m_nativePointer;
27
28 public QtClipboardManager(Context context, long nativePointer)
29 {
30 m_nativePointer = nativePointer;
31 registerClipboardManager(context);
32 }
33
34 private void registerClipboardManager(Context context)
35 {
36 if (context != null) {
37 final Semaphore semaphore = new Semaphore(0);
38 QtNative.runAction(() -> {
39 m_clipboardManager =
40 (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
41 if (m_clipboardManager != null) {
42 m_clipboardManager.addPrimaryClipChangedListener(
43 () -> onClipboardDataChanged(m_nativePointer));
44 }
45 semaphore.release();
46 });
47 try {
48 semaphore.acquire();
49 } catch (Exception e) {
50 e.printStackTrace();
51 }
52 }
53 }
54
55 @UsedFromNativeCode
56 public void clearClipData()
57 {
58 if (m_clipboardManager != null) {
59 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
60 m_clipboardManager.clearPrimaryClip();
61 } else {
62 String[] mimeTypes = { "application/octet-stream" };
63 ClipData data = new ClipData("", mimeTypes, new ClipData.Item(new Intent()));
64 m_clipboardManager.setPrimaryClip(data);
65 }
66 }
67 m_usePrimaryClip = false;
68 }
69
70 @UsedFromNativeCode
71 public void setClipboardText(Context context, String text)
72 {
73 if (m_clipboardManager != null) {
74 ClipData clipData = ClipData.newPlainText("text/plain", text);
75 updatePrimaryClip(clipData, context);
76 }
77 }
78
79 public static boolean hasClipboardText(Context context)
80 {
81 ClipboardManager clipboardManager =
82 (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
83
84 if (clipboardManager == null)
85 return false;
86
87 ClipDescription description = clipboardManager.getPrimaryClipDescription();
88 // getPrimaryClipDescription can fail if the app does not have input focus
89 if (description == null)
90 return false;
91
92 for (int i = 0; i < description.getMimeTypeCount(); ++i) {
93 String itemMimeType = description.getMimeType(i);
94 if (itemMimeType.matches("text/(.*)"))
95 return true;
96 }
97 return false;
98 }
99
100 @UsedFromNativeCode
101 public boolean hasClipboardText()
102 {
103 return hasClipboardMimeType("text/(.*)");
104 }
105
106 @UsedFromNativeCode
107 public String getClipboardText()
108 {
109 try {
110 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
111 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
112 if (primaryClip != null) {
113 for (int i = 0; i < primaryClip.getItemCount(); ++i)
114 if (primaryClip.getItemAt(i).getText() != null)
115 return primaryClip.getItemAt(i).getText().toString();
116 }
117 }
118 } catch (Exception e) {
119 Log.e(TAG, "Failed to get clipboard data", e);
120 }
121 return "";
122 }
123
124 private void updatePrimaryClip(ClipData clipData, Context context)
125 {
126 try {
127 if (m_usePrimaryClip) {
128 ClipData clip = m_clipboardManager.getPrimaryClip();
129 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
130 Objects.requireNonNull(clip).addItem(context.getContentResolver(),
131 clipData.getItemAt(0));
132 } else {
133 Objects.requireNonNull(clip).addItem(clipData.getItemAt(0));
134 }
135 m_clipboardManager.setPrimaryClip(clip);
136 } else {
137 m_clipboardManager.setPrimaryClip(clipData);
138 m_usePrimaryClip = true;
139 }
140 } catch (Exception e) {
141 Log.e(TAG, "Failed to set clipboard data", e);
142 }
143 }
144
145 @UsedFromNativeCode
146 public void setClipboardHtml(Context context, String text, String html)
147 {
148 if (m_clipboardManager != null) {
149 ClipData clipData = ClipData.newHtmlText("text/html", text, html);
150 updatePrimaryClip(clipData, context);
151 }
152 }
153
154 private boolean hasClipboardMimeType(String mimeType)
155 {
156 if (m_clipboardManager == null)
157 return false;
158
159 ClipDescription description = m_clipboardManager.getPrimaryClipDescription();
160 // getPrimaryClipDescription can fail if the app does not have input focus
161 if (description == null)
162 return false;
163
164 for (int i = 0; i < description.getMimeTypeCount(); ++i) {
165 String itemMimeType = description.getMimeType(i);
166 if (itemMimeType.matches(mimeType))
167 return true;
168 }
169 return false;
170 }
171
172 @UsedFromNativeCode
173 public boolean hasClipboardHtml()
174 {
175 return hasClipboardMimeType("text/html");
176 }
177
178 @UsedFromNativeCode
179 public String getClipboardHtml()
180 {
181 try {
182 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
183 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
184 if (primaryClip != null) {
185 for (int i = 0; i < primaryClip.getItemCount(); ++i)
186 if (primaryClip.getItemAt(i).getHtmlText() != null)
187 return primaryClip.getItemAt(i).getHtmlText();
188 }
189 }
190 } catch (Exception e) {
191 Log.e(TAG, "Failed to get clipboard data", e);
192 }
193 return "";
194 }
195
196 @UsedFromNativeCode
197 public void setClipboardUri(Context context, String uriString)
198 {
199 if (m_clipboardManager != null) {
200 ClipData clipData = ClipData.newUri(context.getContentResolver(), "text/uri-list",
201 Uri.parse(uriString));
202 updatePrimaryClip(clipData, context);
203 }
204 }
205
206 @UsedFromNativeCode
207 public boolean hasClipboardUri()
208 {
209 return hasClipboardMimeType("text/uri-list");
210 }
211
212 @UsedFromNativeCode
213 private String[] getClipboardUris()
214 {
215 ArrayList<String> uris = new ArrayList<>();
216 try {
217 if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
218 ClipData primaryClip = m_clipboardManager.getPrimaryClip();
219 if (primaryClip != null) {
220 for (int i = 0; i < primaryClip.getItemCount(); ++i)
221 if (primaryClip.getItemAt(i).getUri() != null)
222 uris.add(primaryClip.getItemAt(i).getUri().toString());
223 }
224 }
225 } catch (Exception e) {
226 Log.e(TAG, "Failed to get clipboard data", e);
227 }
228 String[] strings = new String[uris.size()];
229 strings = uris.toArray(strings);
230 return strings;
231 }
232}
QString text
static void * context
const char * mimeType
GLsizei const GLchar ** strings
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data