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