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
qandroidmodelindexproxy.cpp
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#include <QtCore/private/qandroiditemmodelproxy_p.h>
6#include <QtCore/private/qandroidmodelindexproxy_p.h>
7#include <QtCore/private/qandroidtypeconverter_p.h>
8
9#include <QtCore/qjniarray.h>
10
11QT_BEGIN_NAMESPACE
12
13using namespace QtJniTypes;
14
15QModelIndex QAndroidModelIndexProxy::qInstance(JQtModelIndex jModelIndex)
16{
17 if (!jModelIndex.isValid())
18 return QModelIndex();
19
20 const QJniArray<jlong> jPrivateArray = jModelIndex.getField<jlong[]>("m_privateData");
21 const auto privateData = jPrivateArray.toContainer();
22 // The private data must hold row, column, internalId, and model reference.
23 Q_ASSERT(privateData.size() == 4);
24 if (privateData.size() != 4) {
25 qCritical("QtModelIndex has %lld private data entries, expected 4",
26 qlonglong(privateData.size()));
27 return QModelIndex();
28 }
29
30 const jlong modelReference = privateData[3];
31 if (!modelReference)
32 return QModelIndex();
33
34 const jint row = privateData[0];
35 const jint column = privateData[1];
36 QAbstractItemModel *model = reinterpret_cast<QAbstractItemModel *>(modelReference);
37 QAndroidItemModelProxy *proxyModel = qobject_cast<QAndroidItemModelProxy *>(model);
38
39 // If the native model instance is a proxy we have access to the protected function
40 // createIndex(). Else, if the native instance is not a results Java->Qt proxy, we
41 // use index() to get the QModelIndex.
42 if (proxyModel) {
43 const jint internalId = privateData[2];
44 return proxyModel->createIndex(row, column, internalId);
45 } else {
46 const JQtModelIndex parent = jModelIndex.getField<JQtModelIndex>("m_parent");
47 if (parent.isValid())
48 return model->index(row, column, QAndroidModelIndexProxy::qInstance(parent));
49 }
50 return QModelIndex();
51}
52
53JQtModelIndex QAndroidModelIndexProxy::jInstance(QModelIndex modelIndex)
54{
55 if (!modelIndex.isValid())
56 return JQtModelIndex();
57 bool isModelProxy = qobject_cast<const QAndroidItemModelProxy *>(modelIndex.model());
58 if (isModelProxy)
59 return JQtModelIndex(modelIndex.row(), modelIndex.column(), jlong(modelIndex.internalId()),
60 reinterpret_cast<jlong>(modelIndex.model()));
61 else
62 return JQtModelIndex(modelIndex.row(), modelIndex.column(),
63 QAndroidModelIndexProxy::jInstance(modelIndex.parent()),
64 reinterpret_cast<jlong>(modelIndex.model()));
65}
66
67jobject QAndroidModelIndexProxy::data(JNIEnv *env, jobject object, int role)
68{
69 Q_ASSERT(env);
70 Q_ASSERT(object);
71
72 QModelIndex modelIndex = qInstance(object);
73 if (!modelIndex.isValid())
74 return nullptr;
75
76 return QAndroidTypeConverter::toJavaObject(modelIndex.model()->data(modelIndex, role), env);
77}
78
79jlong QAndroidModelIndexProxy::internalId(JNIEnv *env, jobject object)
80{
81 Q_ASSERT(env);
82 Q_ASSERT(object);
83 return qInstance(object).internalId();
84};
85
86jboolean QAndroidModelIndexProxy::isValid(JNIEnv *env, jobject object)
87{
88 Q_ASSERT(env);
89 Q_ASSERT(object);
90 return qInstance(object).isValid();
91}
92
93JQtModelIndex QAndroidModelIndexProxy::parent(JNIEnv *env, jobject object)
94{
95 Q_ASSERT(env);
96 Q_ASSERT(object);
97 return jInstance(qInstance(object).parent());
98};
99
100bool QAndroidModelIndexProxy::registerNatives(QJniEnvironment &env)
101{
102 return env.registerNativeMethods(
103 Traits<JQtModelIndex>::className(),
104 { Q_JNI_NATIVE_SCOPED_METHOD(data, QAndroidModelIndexProxy),
105 Q_JNI_NATIVE_SCOPED_METHOD(internalId, QAndroidModelIndexProxy),
106 Q_JNI_NATIVE_SCOPED_METHOD(isValid, QAndroidModelIndexProxy),
107 Q_JNI_NATIVE_SCOPED_METHOD(parent, QAndroidModelIndexProxy) });
108}
109
110QT_END_NAMESPACE