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