summaryrefslogtreecommitdiffstats
path: root/src/corelib/platform/android/qandroiditemmodelproxy.cpp
blob: 1ad34baa85d58d874a88595fd6baa0ac7e01a12e (plain)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
// 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/qcoreapplication.h> QT_BEGIN_NAMESPACE using namespace QtJniTypes;std::map<const QAbstractItemModel *, QRecursiveMutex>QAndroidItemModelProxy::s_mutexes =std::map<const QAbstractItemModel *, QRecursiveMutex>{}; jint QAndroidItemModelProxy::columnCount(const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto parentIndex =QAndroidModelIndexProxy::jInstance(parent);return jInstance.callMethod<jint>("columnCount", parentIndex);}boolQAndroidItemModelProxy::canFetchMore(const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto parentIndex =QAndroidModelIndexProxy::jInstance(parent);return jInstance.callMethod<jboolean>("canFetchMore", parentIndex);}boolQAndroidItemModelProxy::canFetchMoreDefault(const QModelIndex &parent)const{returnQAbstractItemModel::canFetchMore(parent);} QVariant QAndroidItemModelProxy::data(const QModelIndex &index,int role)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto jIndex =QAndroidModelIndexProxy::jInstance(index); QJniObject jData = jInstance.callMethod<jobject>("data", jIndex, role);returnQAndroidTypeConverter::toQVariant(jData);} QModelIndex QAndroidItemModelProxy::index(int row,int column,const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this); JQtModelIndex jIndex = jInstance.callMethod<JQtModelIndex>("index", row, column,QAndroidModelIndexProxy::jInstance(parent));returnQAndroidModelIndexProxy::qInstance(jIndex);} QModelIndex QAndroidItemModelProxy::parent(const QModelIndex &index)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto jIndex =QAndroidModelIndexProxy::jInstance(index);returnQAndroidModelIndexProxy::qInstance( jInstance.callMethod<JQtModelIndex>("parent", jIndex));}intQAndroidItemModelProxy::rowCount(const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto parentIndex =QAndroidModelIndexProxy::jInstance(parent);return jInstance.callMethod<int>("rowCount", parentIndex);} QHash<int, QByteArray>QAndroidItemModelProxy::roleNames()const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this); QHash<int, QByteArray> roleNames; HashMap hashMap = jInstance.callMethod<HashMap>("roleNames"); Set set = hashMap.callMethod<Set>("keySet");const QJniArray keyArray = set.callMethod<jobject[]>("toArray");for(constauto&key : keyArray) {const QJniObject roleName = hashMap.callMethod<jobject>("get", key);const int intKey =QJniObject(key).callMethod<jint>("intValue");const QByteArray roleByteArray =String(roleName).toString().toLatin1(); roleNames.insert(intKey, roleByteArray);}return roleNames;} QHash<int, QByteArray>QAndroidItemModelProxy::defaultRoleNames()const{returnQAbstractItemModel::roleNames();}voidQAndroidItemModelProxy::fetchMore(const QModelIndex &parent){Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto parentIndex =QAndroidModelIndexProxy::jInstance(parent); jInstance.callMethod<void>("fetchMore", parentIndex);}voidQAndroidItemModelProxy::fetchMoreDefault(const QModelIndex &parent){QAbstractItemModel::fetchMore(parent);}boolQAndroidItemModelProxy::hasChildren(const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto parentIndex =QAndroidModelIndexProxy::jInstance(parent);return jInstance.callMethod<jboolean>("hasChildren", parentIndex);}boolQAndroidItemModelProxy::hasChildrenDefault(const QModelIndex &parent)const{returnQAbstractItemModel::hasChildren(parent);} QModelIndex QAndroidItemModelProxy::sibling(int row,int column,const QModelIndex &parent)const{Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);returnQAndroidModelIndexProxy::qInstance(jInstance.callMethod<JQtModelIndex>("sibling", row, column,QAndroidModelIndexProxy::jInstance(parent)));} QModelIndex QAndroidItemModelProxy::siblingDefault(int row,int column,const QModelIndex &parent){returnQAbstractItemModel::sibling(row, column, parent);}boolQAndroidItemModelProxy::setData(const QModelIndex &index,const QVariant &value,int role){Q_ASSERT(jInstance.isValid());const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(this);auto jIndex =QAndroidModelIndexProxy::jInstance(index);auto jValue =QAndroidTypeConverter::toJavaObject(value,QJniEnvironment::getJniEnv());return jInstance.callMethod<jboolean>("setData", jIndex, jValue, role);}boolQAndroidItemModelProxy::setDataDefault(const QModelIndex &index,const QVariant &value,int role){returnQAbstractItemModel::setData(index, value, role);} Q_REQUIRED_RESULT QAbstractItemModel *QAndroidItemModelProxy::nativeInstance(JQtAbstractItemModel itemModel){ jlong nativeReference = itemModel.callMethod<jlong>("nativeReference");return reinterpret_cast<QAbstractItemModel *>(nativeReference);} Q_REQUIRED_RESULT QAbstractItemModel *QAndroidItemModelProxy::createNativeProxy(QJniObject itemModel){ QAbstractItemModel *nativeProxy =nativeInstance(itemModel);if(!nativeProxy) {Q_ASSERT(QCoreApplication::instance()); nativeProxy =newQAndroidItemModelProxy(itemModel); QThread *qtMainThread =QCoreApplication::instance()->thread();if(nativeProxy->thread() != qtMainThread) nativeProxy->moveToThread(qtMainThread); itemModel.callMethod<void>("setNativeReference",reinterpret_cast<jlong>(nativeProxy));connect(nativeProxy, &QAndroidItemModelProxy::destroyed, nativeProxy, [](QObject *obj) {auto proxy = qobject_cast<QAndroidItemModelProxy *>(obj);if(proxy) {const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(proxy); proxy->jInstance.callMethod<void>("detachFromNative");}});connect(nativeProxy, &QAndroidItemModelProxy::dataChanged, nativeProxy,[nativeProxy](const QModelIndex &topLeft,const QModelIndex &bottomRight,const QList<int> &roles) {auto proxy = qobject_cast<QAndroidItemModelProxy *>(nativeProxy);if(proxy) { QJniObject jInstance = proxy->jInstance;const QMutexLocker<QRecursiveMutex> lock =getMutexLocker(proxy); jInstance.callMethod<void>("handleDataChanged",QAndroidModelIndexProxy::jInstance(topLeft),QAndroidModelIndexProxy::jInstance(bottomRight), QJniArray<jint>(roles));}});}return nativeProxy;} QJniObject QAndroidItemModelProxy::createProxy(QAbstractItemModel *itemModel){returnJQtAndroidItemModelProxy(reinterpret_cast<jlong>(itemModel));}intQAndroidItemModelProxy::jni_columnCount(JNIEnv *env, jobject object, JQtModelIndex parent){const QModelIndex nativeParent =QAndroidModelIndexProxy::qInstance(parent);returninvokeNativeMethod(env, object, &QAbstractItemModel::columnCount, nativeParent);} jobject QAndroidItemModelProxy::jni_data(JNIEnv *env, jobject object, JQtModelIndex index, jint role){const QModelIndex nativeIndex =QAndroidModelIndexProxy::qInstance(index);const QVariant data =invokeNativeMethod(env, object, &QAbstractItemModel::data, nativeIndex, role);returnQAndroidTypeConverter::toJavaObject(data, env);} jobject QAndroidItemModelProxy::jni_index(JNIEnv *env, jobject object, jint row, jint column, JQtModelIndex parent){auto nativeParent =QAndroidModelIndexProxy::qInstance(parent);const QModelIndex modelIndex =invokeNativeMethod(env, object, &QAbstractItemModel::index, row, column, nativeParent);return env->NewLocalRef(QAndroidModelIndexProxy::jInstance(modelIndex).object());} jobject QAndroidItemModelProxy::jni_parent(JNIEnv *env, jobject object, JQtModelIndex index){const QModelIndex nativeIndex =QAndroidModelIndexProxy::qInstance(index);QModelIndex(QAbstractItemModel::*parentOverloadPtr)(const QModelIndex &)const=&QAbstractItemModel::parent;const QModelIndex parent =invokeNativeMethod(env, object, parentOverloadPtr, nativeIndex);return env->NewLocalRef(QAndroidModelIndexProxy::jInstance(parent).object());} jint QAndroidItemModelProxy::jni_rowCount(JNIEnv *env, jobject object, JQtModelIndex parent){returninvokeNativeMethod(env, object, &QAbstractItemModel::rowCount,QAndroidModelIndexProxy::qInstance(parent));} jobject QAndroidItemModelProxy::jni_roleNames(JNIEnv *env, jobject object){auto roleNames =invokeNativeImpl(env, object, &QAndroidItemModelProxy::defaultRoleNames,&QAbstractItemModel::roleNames); HashMap jRoleNames{};for(auto[role, roleName] : roleNames.asKeyValueRange()) {const Integer jRole(role); jRoleNames.callMethod<jobject>("put", jRole.object(),QString::fromUtf8(roleName));}return env->NewLocalRef(jRoleNames.object());} jobject QAndroidItemModelProxy::jni_createIndex(JNIEnv *env, jobject object, jint row, jint column, jlong id){QModelIndex(QAndroidItemModelProxy::*createIndexPtr)(int,int, quintptr)const=&QAndroidItemModelProxy::createIndex;const QModelIndex index =invokeNativeProxyMethod(env, object, createIndexPtr, row, column,quintptr(id));return env->NewLocalRef(QAndroidModelIndexProxy::jInstance(index).object());} jboolean QAndroidItemModelProxy::jni_canFetchMore(JNIEnv *env, jobject object, JQtModelIndex parent){returninvokeNativeImpl(env, object, &QAndroidItemModelProxy::canFetchMoreDefault,&QAbstractItemModel::canFetchMore,QAndroidModelIndexProxy::qInstance(parent));}voidQAndroidItemModelProxy::jni_fetchMore(JNIEnv *env, jobject object, JQtModelIndex parent){returninvokeNativeImpl(env, object, &QAndroidItemModelProxy::fetchMoreDefault,&QAbstractItemModel::fetchMore,QAndroidModelIndexProxy::qInstance(parent));} jboolean QAndroidItemModelProxy::jni_hasChildren(JNIEnv *env, jobject object, JQtModelIndex parent){returninvokeNativeImpl(env, object, &QAndroidItemModelProxy::hasChildrenDefault,&QAbstractItemModel::hasChildren,QAndroidModelIndexProxy::qInstance(parent));} jboolean QAndroidItemModelProxy::jni_hasIndex(JNIEnv *env, jobject object, jint row, jint column, JQtModelIndex parent){returninvokeNativeMethod(env, object, &QAbstractItemModel::hasIndex, row, column,QAndroidModelIndexProxy::qInstance(parent));}voidQAndroidItemModelProxy::jni_beginInsertColumns(JNIEnv *env, jobject object, JQtModelIndex parent, jint first, jint last){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::beginInsertColumns,QAndroidModelIndexProxy::qInstance(parent), first, last);}voidQAndroidItemModelProxy::jni_beginInsertRows(JNIEnv *env, jobject object, JQtModelIndex parent, jint first, jint last){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::beginInsertRows,QAndroidModelIndexProxy::qInstance(parent), first, last);} jboolean QAndroidItemModelProxy::jni_beginMoveColumns(JNIEnv *env, jobject object, JQtModelIndex sourceParent, jint sourceFirst, jint sourceLast, JQtModelIndex destinationParent, jint destinationChild){returninvokeNativeProxyMethod( env, object, &QAndroidItemModelProxy::beginMoveColumns,QAndroidModelIndexProxy::qInstance(sourceParent), sourceFirst, sourceLast,QAndroidModelIndexProxy::qInstance(destinationParent), destinationChild);} jboolean QAndroidItemModelProxy::jni_beginMoveRows(JNIEnv *env, jobject object, JQtModelIndex sourceParent, jint sourceFirst, jint sourceLast, JQtModelIndex destinationParent, jint destinationChild){returninvokeNativeProxyMethod( env, object, &QAndroidItemModelProxy::beginMoveRows,QAndroidModelIndexProxy::qInstance(sourceParent), sourceFirst, sourceLast,QAndroidModelIndexProxy::qInstance(destinationParent), destinationChild);}voidQAndroidItemModelProxy::jni_beginRemoveColumns(JNIEnv *env, jobject object, JQtModelIndex parent, jint first, jint last){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::beginRemoveColumns,QAndroidModelIndexProxy::qInstance(parent), first, last);}voidQAndroidItemModelProxy::jni_beginRemoveRows(JNIEnv *env, jobject object, JQtModelIndex parent, jint first, jint last){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::beginRemoveRows,QAndroidModelIndexProxy::qInstance(parent), first, last);}voidQAndroidItemModelProxy::jni_beginResetModel(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::beginResetModel);}voidQAndroidItemModelProxy::jni_endInsertColumns(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endInsertColumns);}voidQAndroidItemModelProxy::jni_endInsertRows(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endInsertRows);}voidQAndroidItemModelProxy::jni_endMoveColumns(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endMoveColumns);}voidQAndroidItemModelProxy::jni_endMoveRows(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endMoveRows);}voidQAndroidItemModelProxy::jni_endRemoveColumns(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endRemoveColumns);}voidQAndroidItemModelProxy::jni_endRemoveRows(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endRemoveRows);}voidQAndroidItemModelProxy::jni_endResetModel(JNIEnv *env, jobject object){invokeNativeProxyMethod(env, object, &QAndroidItemModelProxy::endResetModel);} jobject QAndroidItemModelProxy::jni_sibling(JNIEnv *env, jobject object, jint row, jint column, JQtModelIndex parent){const QModelIndex index =invokeNativeImpl(env, object, &QAndroidItemModelProxy::siblingDefault,&QAbstractItemModel::sibling, row, column,QAndroidModelIndexProxy::qInstance(parent));return env->NewLocalRef(QAndroidModelIndexProxy::jInstance(index).object());} jboolean QAndroidItemModelProxy::jni_setData(JNIEnv *env, jobject object, JQtModelIndex index, jobject value, jint role){const QModelIndex nativeIndex =QAndroidModelIndexProxy::qInstance(index);const QVariant qValue =QAndroidTypeConverter::toQVariant(QJniObject(value));returninvokeNativeImpl(env, object, &QAndroidItemModelProxy::setDataDefault,&QAbstractItemModel::setData, nativeIndex, qValue, role);}voidQAndroidItemModelProxy::jni_dataChanged(JNIEnv *env, jobject object, JQtModelIndex topLeft, JQtModelIndex bottomRight, QJniArray<jint> roles){const QModelIndex nativeTopLeft =QAndroidModelIndexProxy::qInstance(topLeft);const QModelIndex nativeBottomRight =QAndroidModelIndexProxy::qInstance(bottomRight);const QList<int> nativeRoles = roles.toContainer();invokeNativeImpl(env, object, &QAndroidItemModelProxy::dataChanged,&QAbstractItemModel::dataChanged, nativeTopLeft, nativeBottomRight, nativeRoles);}boolQAndroidItemModelProxy::registerAbstractNatives(QJniEnvironment &env){return env.registerNativeMethods( Traits<JQtAbstractItemModel>::className(),{Q_JNI_NATIVE_SCOPED_METHOD(jni_roleNames, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_canFetchMore, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_createIndex, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_fetchMore, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_hasChildren, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_hasIndex, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginInsertColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginInsertRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginMoveColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginMoveRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginRemoveColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginRemoveRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_beginResetModel, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endInsertColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endInsertRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endMoveColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endMoveRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endRemoveColumns, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endRemoveRows, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_endResetModel, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_sibling, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_setData, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_dataChanged, QAndroidItemModelProxy) });}boolQAndroidItemModelProxy::registerProxyNatives(QJniEnvironment &env){return env.registerNativeMethods( Traits<JQtAndroidItemModelProxy>::className(),{Q_JNI_NATIVE_SCOPED_METHOD(jni_columnCount, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_data, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_index, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_parent, QAndroidItemModelProxy),Q_JNI_NATIVE_SCOPED_METHOD(jni_rowCount, QAndroidItemModelProxy) });} QT_END_NAMESPACE 
close