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
qandroiditemmodelproxy_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 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// Qt-Security score:significant reason:default
4
5#ifndef QANDROIDITEMMODELPROXY_P_H
6#define QANDROIDITEMMODELPROXY_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17
18#include <QtCore/private/qandroidmodelindexproxy_p.h>
19#include <QtCore/private/qandroidtypes_p.h>
20
21#include <QtCore/qabstractitemmodel.h>
22#include <QtCore/qjniobject.h>
23#include <QtCore/qjnienvironment.h>
24#include <QtCore/qjnitypes.h>
25#include <QtCore/qthread.h>
26#include <QtCore/qmutex.h>
27
29
30class Q_CORE_EXPORT QAndroidItemModelProxy : public QAbstractItemModel
31{
32 Q_OBJECT
33
34public:
35 explicit QAndroidItemModelProxy(QtJniTypes::JQtAbstractItemModel jInstance)
36 : jInstance(jInstance)
37 {
38 }
39
40 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
41 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
42 QModelIndex index(int row, int column,
43 const QModelIndex &parent = QModelIndex()) const override;
44 QModelIndex parent(const QModelIndex &index) const override;
45 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
46
47 bool canFetchMore(const QModelIndex &parent) const override;
48 bool canFetchMoreDefault(const QModelIndex &parent) const;
49 QHash<int, QByteArray> roleNames() const override;
50 QHash<int, QByteArray> defaultRoleNames() const;
51 void fetchMore(const QModelIndex &parent) override;
52 void fetchMoreDefault(const QModelIndex &parent);
53 bool hasChildren(const QModelIndex &parent) const override;
54 bool hasChildrenDefault(const QModelIndex &parent) const;
55 QModelIndex sibling(int row, int column, const QModelIndex &parent) const override;
56 QModelIndex siblingDefault(int row, int column, const QModelIndex &parent);
57 bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
58 bool setDataDefault(const QModelIndex &index, const QVariant &value, int role);
59
60 Q_REQUIRED_RESULT static QAbstractItemModel *
61 nativeInstance(QtJniTypes::JQtAbstractItemModel itemModel);
62 Q_REQUIRED_RESULT static QAbstractItemModel *createNativeProxy(QJniObject itemModel);
63 static QJniObject createProxy(QAbstractItemModel *abstractClass);
64
65 template <typename Func, typename... Args>
66 static auto invokeNativeProxyMethod(JNIEnv * /*env*/, jobject jvmObject, Func &&func,
67 Args &&...args)
68 {
69 Q_ASSERT(jvmObject);
70 auto model = qobject_cast<QAndroidItemModelProxy *>(nativeInstance(jvmObject));
71 Q_ASSERT(model);
72 const QMutexLocker<QRecursiveMutex> lock = getMutexLocker(model);
73 return std::invoke(std::forward<Func>(func), model, std::forward<Args>(args)...);
74 }
75
76 template <typename Func, typename... Args>
77 static auto invokeNativeMethod(JNIEnv * /*env*/, jobject jvmObject, Func &&func, Args &&...args)
78 {
79 Q_ASSERT(jvmObject);
80 auto model = nativeInstance(jvmObject);
81 Q_ASSERT(model);
82 const QMutexLocker<QRecursiveMutex> lock = getMutexLocker(model);
83 return std::invoke(std::forward<Func>(func), model, std::forward<Args>(args)...);
84 }
85
86 template <typename Func1, typename Func2, typename... Args>
87 static auto invokeNativeImpl(JNIEnv * /*env*/, jobject jvmObject, Func1 &&defaultFunc,
88 Func2 &&func, Args &&...args)
89 {
90 Q_ASSERT(jvmObject);
91 auto nativeModel = nativeInstance(jvmObject);
92 auto nativeProxyModel = qobject_cast<QAndroidItemModelProxy *>(nativeModel);
93 const QMutexLocker<QRecursiveMutex> lock = getMutexLocker(nativeModel);
94 if (nativeProxyModel)
95 return std::invoke(std::forward<Func1>(defaultFunc), nativeProxyModel,
96 std::forward<Args>(args)...);
97 else
98
99 return std::invoke(std::forward<Func2>(func), nativeModel, std::forward<Args>(args)...);
100 }
101
102 static jint jni_columnCount(JNIEnv *env, jobject object, JQtModelIndex parent);
103 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_columnCount)
104
105 static jobject jni_data(JNIEnv *env, jobject object, JQtModelIndex index, jint role);
106 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_data)
107
108 static jobject jni_index(JNIEnv *env, jobject object, jint row, jint column,
109 JQtModelIndex parent);
110 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_index)
111
112 static jobject jni_parent(JNIEnv *env, jobject object, JQtModelIndex index);
113 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_parent)
114
115 static jint jni_rowCount(JNIEnv *env, jobject object, JQtModelIndex parent);
116 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_rowCount)
117
118 static jboolean jni_canFetchMore(JNIEnv *env, jobject object, JQtModelIndex parent);
119 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(jni_canFetchMore, canFetchMore)
120
121 static void jni_fetchMore(JNIEnv *env, jobject object, JQtModelIndex parent);
122 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(jni_fetchMore, fetchMore)
123
124 static jboolean jni_hasChildren(JNIEnv *env, jobject object, JQtModelIndex parent);
125 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(jni_hasChildren, hasChildren)
126
127 static jboolean jni_hasIndex(JNIEnv *env, jobject object, jint row, jint column,
128 JQtModelIndex parent);
129 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(jni_hasIndex, hasIndex)
130
131 static jobject jni_roleNames(JNIEnv *env, jobject object);
132 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_roleNames)
133
134 static void jni_beginInsertColumns(JNIEnv *env, jobject object, JQtModelIndex parent,
135 jint first, jint last);
136 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginInsertColumns)
137
138 static void jni_beginInsertRows(JNIEnv *env, jobject object, JQtModelIndex parent, jint first,
139 jint last);
140 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginInsertRows)
141
142 static jboolean jni_beginMoveColumns(JNIEnv *env, jobject object, JQtModelIndex sourceParent,
143 jint sourceFirst, jint sourceLast,
144 JQtModelIndex destinationParent, jint destinationChild);
145 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginMoveColumns)
146
147 static jboolean jni_beginMoveRows(JNIEnv *env, jobject object, JQtModelIndex sourceParent,
148 jint sourceFirst, jint sourceLast,
149 JQtModelIndex destinationParent, jint destinationChild);
150 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginMoveRows)
151
152 static void jni_beginRemoveColumns(JNIEnv *env, jobject object, JQtModelIndex parent,
153 jint first, jint last);
154 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginRemoveColumns)
155
156 static void jni_beginRemoveRows(JNIEnv *env, jobject object, JQtModelIndex parent, jint first,
157 jint last);
158 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginRemoveRows)
159
160 static void jni_beginResetModel(JNIEnv *env, jobject object);
161 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_beginResetModel)
162
163 static jobject jni_createIndex(JNIEnv *env, jobject object, jint row, jint column, jlong id);
164 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_createIndex)
165
166 static void jni_endInsertColumns(JNIEnv *env, jobject object);
167 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endInsertColumns)
168
169 static void jni_endInsertRows(JNIEnv *env, jobject object);
170 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endInsertRows)
171
172 static void jni_endMoveColumns(JNIEnv *env, jobject object);
173 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endMoveColumns)
174
175 static void jni_endMoveRows(JNIEnv *env, jobject object);
176 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endMoveRows)
177
178 static void jni_endRemoveColumns(JNIEnv *env, jobject object);
179 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endRemoveColumns)
180
181 static void jni_endRemoveRows(JNIEnv *env, jobject object);
182 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endRemoveRows)
183
184 static void jni_endResetModel(JNIEnv *env, jobject object);
185 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_endResetModel)
186
187 static jobject jni_sibling(JNIEnv *env, jobject object, jint row, jint column,
188 JQtModelIndex parent);
189 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_sibling)
190
191 static void jni_dataChanged(JNIEnv *env, jobject object, JQtModelIndex topLeft,
192 JQtModelIndex bottomRight, QJniArray<jint> roles);
193 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_dataChanged)
194
195 static jboolean jni_setData(JNIEnv *env, jobject object, JQtModelIndex index, jobject value,
196 jint role);
197 Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(jni_setData)
198
199 static bool registerAbstractNatives(QJniEnvironment &env);
200 static bool registerProxyNatives(QJniEnvironment &env);
201
202private:
203 static std::map<const QAbstractItemModel *, QRecursiveMutex> s_mutexes;
204
205 Q_REQUIRED_RESULT static QMutexLocker<QRecursiveMutex>
206 getMutexLocker(const QAbstractItemModel *model)
207 {
208 auto [iter, inserted] = s_mutexes.try_emplace(model);
209 if (inserted)
210 QObject::connect(model, &QAbstractItemModel::destroyed, model, [](QObject *model) {
211 s_mutexes.erase(reinterpret_cast<QAbstractItemModel *>(model));
212 });
213 return QMutexLocker(&iter->second);
214 }
215
216 QJniObject jInstance;
217 friend class QAndroidModelIndexProxy;
218};
219
220QT_END_NAMESPACE
221
222#endif // QANDROIDITEMMODELPROXY_P_H