// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef TESTCLASSES_H #define TESTCLASSES_H #include #include #include #include #include #include #include #include #include #include // utility class that sets up QQmlContext for passed QObject. can be used as a // base class to ensure that qmlEngine(object) is valid during initializer list // evaluation struct ContextRegistrator { ContextRegistrator(QQmlEngine *engine, QObject *This); static QQmlRefPointer create(QQmlEngine *engine, const QUrl &url, const QQmlRefPointer &parentContext, int index) { // test-specific wrapping that is document-root-agnostic. calls proper // creation for index == 0 and falls back to returning parentContext // otherwise. the qmltc generates exactly that but with an implicit // index check if (index == 0) { auto priv = QQmlEnginePrivate::get(engine); return priv->createInternalContext(priv->compilationUnitFromUrl(url), parentContext, 0, true); } return parentContext; } static void set(QObject *This, const QQmlRefPointer &context, QQmlContextData::QmlObjectKind kind) { QQmlEnginePrivate::setInternalContext(This, context, kind); } }; class HelloWorld : public QObject, public ContextRegistrator { Q_OBJECT QML_NAMED_ELEMENT(HelloWorld); QML_UNCREATABLE("") Q_PROPERTY(QString hello READ getHello WRITE setHello BINDABLE bindableHello) Q_PROPERTY(QString greeting READ getGreeting WRITE setGreeting BINDABLE bindableGreeting) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; HelloWorld(QQmlEngine *e, QObject *parent = nullptr); virtual ~HelloWorld() { } QString getHello() { return hello.value(); } QString getGreeting() { return greeting.value(); } void setHello(const QString &hello_) { hello.setValue(hello_); } void setGreeting(const QString &greeting_) { greeting.setValue(greeting_); } QBindable bindableHello() { return QBindable(&hello); } QBindable bindableGreeting() { return QBindable(&greeting); } Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, hello); Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, greeting); }; class ANON_signalHandlers : public QObject, public ContextRegistrator { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int signal1P READ getSignal1P WRITE setSignal1P BINDABLE bindableSignal1P) Q_PROPERTY(QString signal2P1 READ getSignal2P1 WRITE setSignal2P1 BINDABLE bindableSignal2P1) Q_PROPERTY(int signal2P2 READ getSignal2P2 WRITE setSignal2P2 BINDABLE bindableSignal2P2) Q_PROPERTY(QString signal2P3 READ getSignal2P3 WRITE setSignal2P3 BINDABLE bindableSignal2P3) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_signalHandlers(QQmlEngine *e, QObject *parent = nullptr); int getSignal1P() { return signal1P.value(); } QString getSignal2P1() { return signal2P1.value(); } int getSignal2P2() { return signal2P2.value(); } QString getSignal2P3() { return signal2P3.value(); } void setSignal1P(const int &signal1P_) { signal1P.setValue(signal1P_); } void setSignal2P1(const QString &signal2P1_) { signal2P1.setValue(signal2P1_); } void setSignal2P2(const int &signal2P2_) { signal2P2.setValue(signal2P2_); } void setSignal2P3(const QString &signal2P3_) { signal2P3.setValue(signal2P3_); } QBindable bindableSignal1P() { return QBindable(&signal1P); } QBindable bindableSignal2P1() { return QBindable(&signal2P1); } QBindable bindableSignal2P2() { return QBindable(&signal2P2); } QBindable bindableSignal2P3() { return QBindable(&signal2P3); } Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal1P); Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P1); Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal2P2); Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P3); Q_SIGNALS: void signal1(); void signal2(QString x, int y); public slots: void onSignal1(); void onSignal2(QString x, int y); public: void qmlEmitSignal1(); void qmlEmitSignal2(); void qmlEmitSignal2WithArgs(QString x, int y); }; class ANON_javaScriptFunctions : public QObject, public ContextRegistrator { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int func1P READ getFunc1P WRITE setFunc1P) Q_PROPERTY(QString func2P READ getFunc2P WRITE setFunc2P) Q_PROPERTY(bool func3P READ getFunc3P WRITE setFunc3P) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent = nullptr); int getFunc1P() { return func1P.value(); } QString getFunc2P() { return func2P.value(); } bool getFunc3P() { return func3P.value(); } void setFunc1P(const int &func1P_) { func1P.setValue(func1P_); } void setFunc2P(const QString &func2P_) { func2P.setValue(func2P_); } void setFunc3P(const bool &func3P_) { func3P.setValue(func3P_); } // try if just QProperty works QProperty func1P; QProperty func2P; QProperty func3P; void func1(); void func2(QString x); bool func3(); }; class ANON_changingBindings : public QObject, public ContextRegistrator { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int p1 READ getP1 WRITE setP1 BINDABLE bindableP1) Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; // test util to monitor binding execution int initialBindingCallCount = 0; // test util: allows to set C++ binding multiple times void resetToInitialBinding(); ANON_changingBindings(QQmlEngine *e, QObject *parent = nullptr); int getP1() { return p1.value(); } int getP2() { return p2.value(); } void setP1(int p1_) { p1.setValue(p1_); } void setP2(int p2_) { p2.setValue(p2_); } QBindable bindableP1() { return QBindable(&p1); } QBindable bindableP2() { return QBindable(&p2); } Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p1); Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p2); void resetToConstant(); void resetToNewBinding(); }; class ANON_propertyAlias : public QObject, public ContextRegistrator { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int dummy READ getDummy WRITE setDummy NOTIFY dummyChanged) Q_PROPERTY(int origin READ getOrigin WRITE setOrigin BINDABLE bindableOrigin) Q_PROPERTY(int aliasToOrigin READ getAliasToOrigin WRITE setAliasToOrigin BINDABLE bindableAliasToOrigin) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; // test util: allows to set C++ binding multiple times void resetToInitialBinding(); ANON_propertyAlias(QQmlEngine *e, QObject *parent = nullptr); int getDummy() { return dummy.value(); } int getOrigin() { return origin.value(); } int getAliasToOrigin() { return getOrigin(); } void setDummy(int dummy_) { dummy.setValue(dummy_); // emit is essential for Qt.binding() to work correctly emit dummyChanged(); } void setOrigin(int origin_) { origin.setValue(origin_); } void setAliasToOrigin(int aliasToOrigin_) { setOrigin(aliasToOrigin_); } QBindable bindableOrigin() { return QBindable(&origin); } QBindable bindableAliasToOrigin() { return bindableOrigin(); } QProperty dummy; QProperty origin; void resetAliasToConstant(); void resetOriginToConstant(); void resetAliasToNewBinding(); void resetOriginToNewBinding(); int getAliasValue(); Q_SIGNALS: void dummyChanged(); }; class ANON_propertyChangeHandler : public QObject, public ContextRegistrator { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int dummy READ getDummy WRITE setDummy) Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP) Q_PROPERTY(int watcher READ getWatcher WRITE setWatcher) public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent = nullptr); int getDummy() { return dummy.value(); } int getP() { return p.value(); } int getWatcher() { return watcher.value(); } void setDummy(int dummy_) { dummy.setValue(dummy_); } void setP(int p_) { p.setValue(p_); } void setWatcher(int watcher_) { watcher.setValue(watcher_); } QBindable bindableP() { return QBindable(&p); } QProperty dummy; QProperty p; QProperty watcher; // property change handler: struct ANON_propertyChangeHandler_p_changeHandler { ANON_propertyChangeHandler *This = nullptr; ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj); void operator()(); }; // the handler object has to be alive as long as the object std::unique_ptr> pChangeHandler; }; class LocallyImported : public QObject { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int count READ getCount WRITE setCount BINDABLE bindableCount) protected: LocallyImported(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; LocallyImported(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); Q_INVOKABLE QVariant getMagicValue(); void completedSlot(); int getCount() { return count.value(); } void setCount(int count_) { count.setValue(count_); } QBindable bindableCount() { return QBindable(&count); } QProperty count; }; class ANON_localImport : public LocallyImported { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int p1 READ getP1 WRITE setP1) protected: ANON_localImport(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_localImport(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); int getP1() { return p1.value(); } void setP1(int p1_) { p1.setValue(p1_); } QProperty p1; Q_INVOKABLE QVariant localGetMagicValue(); }; class ANON_neighbors_QtObject : public QObject { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP) Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2) protected: ANON_neighbors_QtObject(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_neighbors_QtObject(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); // called by the document root int getP() { return p.value(); } void setP(int p_) { p.setValue(p_); } QBindable bindableP() { return QBindable(&p); } QProperty p; int getP2() { return p2.value(); } void setP2(int p2_) { p2.setValue(p2_); } QBindable bindableP2() { return QBindable(&p2); } QProperty p2; }; class ANON_neighbors_LocallyImported : public LocallyImported { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP) protected: ANON_neighbors_LocallyImported(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url2; ANON_neighbors_LocallyImported(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); // called by the document root int getP() { return p.value(); } void setP(int p_) { p.setValue(p_); } QBindable bindableP() { return QBindable(&p); } QProperty p; }; class ANON_neighbors : public QQuickItem { Q_OBJECT QML_ANONYMOUS protected: ANON_neighbors(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_neighbors(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); }; class ANON_anchors : public QQuickItem { Q_OBJECT QML_ANONYMOUS Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged) protected: ANON_anchors(QObject *parent = nullptr); public: // test workaround: the url is resolved by the test base class, so use // member variable to store the resolved url used as argument in engine // evaluation of runtime functions static QUrl url; ANON_anchors(QQmlEngine *e, QObject *parent = nullptr); QQmlRefPointer init(QQmlEngine *e, const QQmlRefPointer &parentContext); void finalize(QQmlEngine *e); QProperty value; int getValue() { return value; } void setValue(int v) { value = v; Q_EMIT valueChanged(); } Q_SIGNALS: void valueChanged(); }; #endif // TESTCLASSES_H