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
qandroidplatformclipboard.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 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:significant reason:default
5
7
8#include <QtCore/QUrl>
9#include <QtCore/QMetaObject>
10#include <QtCore/QJniEnvironment>
11#include <QtCore/QJniObject>
12#include <QtCore/private/qjnihelpers_p.h>
13#include <QtGui/QGuiApplication>
14#include <QtGui/private/qinternalmimedata_p.h>
15
16#ifndef QT_NO_CLIPBOARD
17
18using namespace QtJniTypes;
19using namespace Qt::StringLiterals;
20
21QT_BEGIN_NAMESPACE
22
23class QAndroidPlatformMimeData : public QInternalMimeData
24{
25public:
26 explicit QAndroidPlatformMimeData(const QtClipboardManager *clipboardManager)
27 : m_clipboardManager(clipboardManager)
28 {
29 if (m_clipboardManager->callMethod<jboolean>("hasClipboardText"))
30 m_formats.append("text/plain"_L1);
31 if (m_clipboardManager->callMethod<jboolean>("hasClipboardHtml"))
32 m_formats.append("text/html"_L1);
33 if (m_clipboardManager->callMethod<jboolean>("hasClipboardUri"))
34 m_formats.append("text/uri-list"_L1);
35 }
36
37protected:
38 bool hasFormat_sys(const QString &mimeType) const override
39 {
40 return m_formats.contains(mimeType);
41 }
42
43 QStringList formats_sys() const override
44 {
45 return m_formats;
46 }
47
48 QVariant retrieveData_sys(const QString &mimeType, QMetaType) const override
49 {
50 if (mimeType == "text/plain"_L1)
51 return m_clipboardManager->callMethod<QString>("getClipboardText").toUtf8();
52 if (mimeType == "text/html"_L1)
53 return m_clipboardManager->callMethod<QString>("getClipboardHtml").toUtf8();
54 if (mimeType == "text/uri-list"_L1) {
55 QByteArray result;
56 const auto uris = m_clipboardManager->callMethod<QString[]>("getClipboardUris");
57 if (!uris.isValid())
58 return result;
59 for (const QString &uri : uris) {
60 result += QUrl(uri).toEncoded();
61 result += "\r\n";
62 }
63 return result;
64 }
65 return {};
66 }
67
68private:
69 const QtClipboardManager *const m_clipboardManager;
70 QStringList m_formats;
71};
72
73void QAndroidPlatformClipboard::onClipboardDataChanged(JNIEnv *env, jobject obj, jlong nativePointer)
74{
75 Q_UNUSED(env)
76 Q_UNUSED(obj)
77
78 auto *clipboardManager = reinterpret_cast<QAndroidPlatformClipboard *>(nativePointer);
79 if (clipboardManager)
80 QMetaObject::invokeMethod(QGuiApplication::clipboard(), [] {
81 QClipboard *clipboard = QGuiApplication::clipboard();
82 emit clipboard->dataChanged();
83 emit clipboard->changed(QClipboard::Clipboard);
84 }, Qt::QueuedConnection);
85}
86
88{
89 m_clipboardManager = QtClipboardManager::construct(QtAndroidPrivate::context(),
90 reinterpret_cast<jlong>(this));
91}
92
94{
95 if (data)
96 delete data;
97}
98
99QMimeData *QAndroidPlatformClipboard::getClipboardMimeData()
100{
101 return new QAndroidPlatformMimeData(&m_clipboardManager);
102}
103
105{
106 Q_UNUSED(mode);
107 Q_ASSERT(supportsMode(mode));
108 if (data)
109 data->deleteLater();
110 data = getClipboardMimeData();
111 return data;
112}
113
114void QAndroidPlatformClipboard::clearClipboardData()
115{
116 m_clipboardManager.callMethod<void>("clearClipData");
117}
118
119void QAndroidPlatformClipboard::setClipboardMimeData(QMimeData *data)
120{
121 clearClipboardData();
122 auto context = QtAndroidPrivate::context();
123 if (data->hasUrls()) {
124 QList<QUrl> urls = data->urls();
125 for (const auto &u : std::as_const(urls))
126 m_clipboardManager.callMethod<void>("setClipboardUri", context,
127 u.toString(QUrl::FullyEncoded));
128 } else if (data->hasHtml()) { // html can contain text
129 m_clipboardManager.callMethod<void>("setClipboardHtml",
130 context, data->text(), data->html());
131 } else if (data->hasText()) { // hasText must be the last (the order matter here)
132 m_clipboardManager.callMethod<void>("setClipboardText", context, data->text());
133 }
134}
135
136void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
137{
138 if (!data) {
139 clearClipboardData();
140 return;
141 }
142 if (data && supportsMode(mode))
143 setClipboardMimeData(data);
144 if (data != 0)
145 data->deleteLater();
146}
147
148bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const
149{
150 return QClipboard::Clipboard == mode;
151}
152
153bool QAndroidPlatformClipboard::registerNatives(QJniEnvironment &env)
154{
155 bool success = env.registerNativeMethods(Traits<QtClipboardManager>::className(),
156 { Q_JNI_NATIVE_SCOPED_METHOD(onClipboardDataChanged, QAndroidPlatformClipboard) });
157 if (!success) {
158 qCritical() << "QtClipboardManager: registerNativeMethods() failed";
159 return false;
160 }
161
162 return true;
163}
164
165QT_END_NAMESPACE
166
167#endif // QT_NO_CLIPBOARD
void setMimeData(QMimeData *data, QClipboard::Mode mode=QClipboard::Clipboard) override
QMimeData * mimeData(QClipboard::Mode mode=QClipboard::Clipboard) override
bool supportsMode(QClipboard::Mode mode) const override