4#include <QtQuick/private/qandroidquickviewembedding_p.h>
6#include <QtCore/qcoreapplication.h>
7#include <QtCore/qjnienvironment.h>
8#include <QtCore/qjniobject.h>
9#include <QtCore/qjniarray.h>
10#include <QtCore/qjnitypes.h>
11#include <QtQml/qqmlengine.h>
12#include <QtQuick/qquickitem.h>
32 jlong parentWindowReference, QtJniTypes::StringArray qmlImportPaths)
34 static_assert (
sizeof(jlong) >=
sizeof(
void*),
35 "Insufficient size of Java type to hold the c++ pointer");
39 if (qmlImportPaths.isValid()) {
40 QJniArray<QtJniTypes::String> importPathsArray(qmlImportPaths);
41 importPaths.reserve(importPathsArray.size());
42 for (
int i = 0;
i < importPathsArray.size(); ++
i)
43 importPaths << importPathsArray.at(
i).toString();
47 parentWindowReference,
52 QWindow *parentWindow =
reinterpret_cast<QWindow *
>(parentWindowReference);
58 qtViewObject.callMethod<
void>(
"handleStatusChange", status);
67 const QtJniTypes::QtWindow
window =
reinterpret_cast<jobject
>(
view->winId());
68 qtViewObject.callMethod<
void>(
"addQtWindow",
70 reinterpret_cast<jlong
>(
view),
71 parentWindowReference);
77 jstring propertyName, jobject
value)
84 qWarning() <<
"QtQuickView instance does not own a root object.";
89 const QMetaObject *rootMetaObject = rootObject->metaObject();
91 if (propertyIndex < 0) {
96 QMetaProperty metaProperty = rootMetaObject->property(propertyIndex);
98 const QByteArray valueClassname = propertyValue.className();
100 if (valueClassname == QtJniTypes::Traits<QtJniTypes::String>::className())
101 metaProperty.
write(rootObject, propertyValue.toString());
102 else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Integer>::className())
103 metaProperty.
write(rootObject, propertyValue.callMethod<jint>(
"intValue"));
104 else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Double>::className())
105 metaProperty.
write(rootObject, propertyValue.callMethod<jdouble>(
"doubleValue"));
106 else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Float>::className())
107 metaProperty.
write(rootObject, propertyValue.callMethod<jfloat>(
"floatValue"));
108 else if (valueClassname == QtJniTypes::Traits<QtJniTypes::Boolean>::className())
109 metaProperty.
write(rootObject, propertyValue.callMethod<jboolean>(
"booleanValue"));
111 qWarning(
"Setting the property type of %s is not supported.", valueClassname.data());
115 jstring propertyName)
124 qWarning(
"Cannot read property %s as the QtQuickView instance (%s)"
125 "does not own a root object.",
131 const QMetaObject *rootMetaObject = rootObject->metaObject();
132 int propertyIndex = rootMetaObject->indexOfProperty(
property.toUtf8().constData());
133 if (propertyIndex < 0) {
134 qWarning(
"Cannot read property %s as it does not exist in the root QML object.",
139 QMetaProperty metaProperty = rootMetaObject->property(propertyIndex);
141 const int propertyTypeId = propertyValue.
typeId();
143 switch (propertyTypeId) {
144 case QMetaType::Type::Int:
145 return env->NewLocalRef(
146 QJniObject::construct<QtJniTypes::Integer>(get<int>(std::move(propertyValue)))
148 case QMetaType::Type::Double:
149 return env->NewLocalRef(
150 QJniObject::construct<QtJniTypes::Double>(get<double>(std::move(propertyValue)))
152 case QMetaType::Type::Float:
153 return env->NewLocalRef(
154 QJniObject::construct<QtJniTypes::Float>(get<float>(std::move(propertyValue)))
156 case QMetaType::Type::Bool:
157 return env->NewLocalRef(
158 QJniObject::construct<QtJniTypes::Boolean>(get<bool>(std::move(propertyValue)))
160 case QMetaType::Type::QString:
161 return env->NewLocalRef(
162 QJniObject::fromString(get<QString>(std::move(propertyValue))).
object());
164 qWarning(
"Property %s cannot be converted to a supported Java data type.",
172 jclass argType, jobject listener)
175 static QHash<QByteArray, int> javaToQMetaType = {
176 {
"java/lang/Void", QMetaType::Type::Void },
177 {
"java/lang/String", QMetaType::Type::QString },
178 {
"java/lang/Integer", QMetaType::Type::Int },
179 {
"java/lang/Double", QMetaType::Type::Double },
180 {
"java/lang/Float", QMetaType::Type::Float },
181 {
"java/lang/Boolean", QMetaType::Type::Bool }
186 qWarning() <<
"QtQuickView is not loaded or ready yet.";
191 qWarning() <<
"QtQuickView instance does not own a root object.";
197 const char *qArgName =
198 QMetaType(javaToQMetaType.value(javaArgClass, QMetaType::Type::UnknownType)).
name();
203 int propertyIndex = -1;
218 if (signalSignature == notifyMethod.methodSignature()) {
224 signalSignature = notifyMethod.methodSignature();
234 const QMetaObject *helperMetaObject = signalHelper->metaObject();
235 QByteArray helperSignalSignature = signalSignature;
236 helperSignalSignature.
replace(0, signalSignature.
indexOf(
'('),
"forwardSignal");
237 int helperSlotIndex = helperMetaObject->indexOfSlot(helperSignalSignature.constData());
238 if (helperSlotIndex == -1)
243 if (signalHelper->listenersMap.contains(signalSignature)) {
244 auto listenerInfos = signalHelper->listenersMap.values(signalSignature);
246 return listenerInfo.listener == listenerJniObject;
248 auto iterator = std::find_if(listenerInfos.constBegin(),
249 listenerInfos.constEnd(),
251 if (iterator != listenerInfos.end()) {
252 qWarning(
"Signal listener with the ID of %i is already connected to %s signal.",
260 QMetaMethod signalForwarderMethod = helperMetaObject->method(helperSlotIndex);
261 signalHelper->connectionHandleCounter++;
264 if (signalHelper->listenersMap.contains(signalSignature)) {
266 ->connections[signalHelper->listenersMap.value(signalSignature).id];
271 signalForwarderMethod);
275 listenerInfo.
listener = listenerJniObject;
276 listenerInfo.javaArgType = javaArgClass;
277 listenerInfo.propertyIndex = propertyIndex;
278 listenerInfo.signalSignature = signalSignature;
279 listenerInfo.id = signalHelper->connectionHandleCounter;
281 signalHelper->listenersMap.
insert(signalSignature, listenerInfo);
284 return listenerInfo.id;
288 jint signalListenerId)
293 qWarning() <<
"QtQuickView instance does not own a root object.";
298 if (!signalHelper->connections.contains(signalListenerId))
302 for (
auto listenerInfoIter = signalHelper->listenersMap.begin();
303 listenerInfoIter != signalHelper->listenersMap.end();) {
304 if (listenerInfoIter->id == signalListenerId) {
305 signalSignature = listenerInfoIter->signalSignature;
306 signalHelper->listenersMap.
erase(listenerInfoIter);
314 if (!signalHelper->listenersMap.contains(signalSignature))
315 rootObject->
disconnect(signalHelper->connections.value(signalListenerId));
317 signalHelper->connections.remove(signalListenerId);
353 using namespace QtJniTypes;
358 for (
auto listenerInfoIter =
listenersMap.constFind(signalMethod.methodSignature());
360 listenerInfoIter.key() == signalMethod.methodSignature();
361 ++listenerInfoIter) {
363 const QByteArray javaArgType = listenerInfo.javaArgType;
367 if (listenerInfo.propertyIndex != -1 && javaArgType != Traits<Void>::className())
368 signalValue =
metaObject->property(listenerInfo.propertyIndex).read(
sender);
370 int valueTypeId = signalValue.typeId();
373 switch (valueTypeId) {
374 case QMetaType::Type::UnknownType:
376 case QMetaType::Type::Int:
377 jValue = qVariantToJniObject<Integer,jint>(signalValue);
379 case QMetaType::Type::Double:
380 jValue = qVariantToJniObject<Double,jdouble>(signalValue);
382 case QMetaType::Type::Float:
383 jValue = qVariantToJniObject<Float,jfloat>(signalValue);
385 case QMetaType::Type::Bool:
386 jValue = qVariantToJniObject<Boolean,jboolean>(signalValue);
388 case QMetaType::Type::QString:
389 jValue = QJniObject::fromString(get<QString>(std::move(signalValue)));
392 qWarning(
"Mismatching argument types between QML signal (%s) and the Java function "
393 "(%s). Sending null as argument.",
394 signalMethod.methodSignature().constData(), javaArgType.
constData());
397 QNativeInterface::QAndroidApplication::runOnAndroidMainThread(
398 [listenerInfo, jSignalMethodName, jValue]() {
399 listenerInfo.listener.callMethod<
void, jstring, jobject>(
"onSignalEmitted",
400 jSignalMethodName.object<jstring>(),
407 return env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtQuickView>::className(),
426 static bool initialized =
false;
428 return JNI_VERSION_1_6;
436 return JNI_VERSION_1_6;
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
iterator erase(const_iterator first, const_iterator last)
QByteArray & insert(qsizetype i, QByteArrayView data)
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
The QColor class provides colors based on RGB, HSV or CMYK values.
int senderSignalIndex() const
T findChild(QAnyStringView aName, Qt::FindChildOptions options=Qt::FindChildrenRecursively) const
Returns the child of this object that can be cast into type T and that is called name,...
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
The QQmlEngine class provides an environment for instantiating QML components.
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
The QQuickView class provides a window for displaying a Qt Quick user interface.
QUrl source
The URL of the source of the QML component.
void setResizeMode(ResizeMode)
QQmlEngine * engine() const
Returns a pointer to the QQmlEngine used for instantiating QML Components.
Status
Specifies the loading status of the QQuickView.
void setSource(const QUrl &)
Sets the source to the url, loads the QML component and instantiates it.
QQuickItem * rootObject() const
Returns the view's root \l {QQuickItem} {item}.
void statusChanged(QQuickView::Status)
This signal is emitted when the component's current status changes.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
int typeId() const
Returns the storage type of the value stored in the variant.
void invokeListener(QObject *sender, int senderSignalIndex, QVariant signalValue)
QMultiMap< QByteArray, ListenerInfo > listenersMap
static bool registerNatives()
Combined button and popup list for selecting options.
void setRootObjectProperty(JNIEnv *env, jobject object, jlong windowReference, jstring propertyName, jobject value)
void createQuickView(JNIEnv *, jobject nativeWindow, jstring qmlUri, jint width, jint height, jlong parentWindowReference, QtJniTypes::StringArray qmlImportPaths)
bool removeRootObjectSignalListener(JNIEnv *, jobject, jlong windowReference, jint signalListenerId)
bool registerNatives(QJniEnvironment &env)
jobject getRootObjectProperty(JNIEnv *env, jobject object, jlong windowReference, jstring propertyName)
int addRootObjectSignalListener(JNIEnv *env, jobject, jlong windowReference, jstring signalName, jclass argType, jobject listener)
QT_BEGIN_NAMESPACE Q_DECLARE_JNI_CLASS(QtDelegate, "org/qtproject/qt/android/QtEmbeddedContextDelegate")
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection * connection
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLint GLsizei GLsizei height
GLsizei const GLchar *const * path
#define qPrintable(string)
#define QStringLiteral(str)
static QWindowsDirect2DWindow * nativeWindow(QWindow *window)
obj metaObject() -> className()
char * toString(const MyType &t)
[31]