diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-08-10 13:13:38 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-08-10 13:51:02 +0200 |
commit | d1a43e4a37cb6bbe0dfcbacd4ce975b0ce0090f0 (patch) | |
tree | 567a010c0947f8668d7b3b0977c16621f846b4b5 /src/quick/util | |
parent | 02caa659dad5e28b95029e28a40912cabeaf6a9b (diff) |
Quick: Make sure the module initialization runs in static builds
We need to keep a reference to the module initialization function
somewhere in order to prevent the linker from removing it. In order to
avoid further littering of the namespace, the QQuick_initializeProviders
function is transformed to cover all of the initialization.
Task-number: QTBUG-85693
Change-Id: Ie93e5abd1dfb5a425b87c70d8ec6327bb68880cb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/util')
-rw-r--r-- | src/quick/util/qquickglobal.cpp | 143 |
1 files changed, 142 insertions, 1 deletions
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 9d97280061..817977eb3b 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -40,12 +40,19 @@ #include <QtQuick/private/qquickvaluetypes_p.h> #include <QtQuick/private/qquickapplication_p.h> +#include <QtQuick/private/qquickstate_p.h> +#include <QtQuick/private/qquickpropertychanges_p.h> +#include <QtQuick/private/qquickitemsmodule_p.h> +#include <QtQuick/private/qquickaccessiblefactory_p.h> #include <QtGui/QGuiApplication> #include <QtGui/qdesktopservices.h> #include <QtGui/qfontdatabase.h> #include <QtGui/qstylehints.h> +#include <QtQml/private/qqmlbinding_p.h> +#include <QtQml/private/qqmldebugserviceinterfaces_p.h> +#include <QtQml/private/qqmldebugstatesdelegate_p.h> #include <QtQml/private/qqmlglobal_p.h> #include <QtQml/private/qv4engine_p.h> #include <QtQml/private/qv4object_p.h> @@ -57,6 +64,128 @@ QT_BEGIN_NAMESPACE +#if QT_CONFIG(qml_debug) + +class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate +{ +public: + QQmlQtQuick2DebugStatesDelegate(); + ~QQmlQtQuick2DebugStatesDelegate(); + void buildStatesList(bool cleanList, const QList<QPointer<QObject> > &instances) override; + void updateBinding(QQmlContext *context, + const QQmlProperty &property, + const QVariant &expression, bool isLiteralValue, + const QString &fileName, int line, int column, + bool *isBaseState) override; + bool setBindingForInvalidProperty(QObject *object, + const QString &propertyName, + const QVariant &expression, + bool isLiteralValue) override; + void resetBindingForInvalidProperty(QObject *object, + const QString &propertyName) override; + +private: + void buildStatesList(QObject *obj); + + QList<QPointer<QQuickState> > m_allStates; +}; + +QQmlQtQuick2DebugStatesDelegate::QQmlQtQuick2DebugStatesDelegate() +{ +} + +QQmlQtQuick2DebugStatesDelegate::~QQmlQtQuick2DebugStatesDelegate() +{ +} + +void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList, + const QList<QPointer<QObject> > &instances) +{ + if (cleanList) + m_allStates.clear(); + + //only root context has all instances + for (int ii = 0; ii < instances.count(); ++ii) { + buildStatesList(instances.at(ii)); + } +} + +void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QObject *obj) +{ + if (QQuickState *state = qobject_cast<QQuickState *>(obj)) { + m_allStates.append(state); + } + + QObjectList children = obj->children(); + for (int ii = 0; ii < children.count(); ++ii) { + buildStatesList(children.at(ii)); + } +} + +void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, + const QQmlProperty &property, + const QVariant &expression, bool isLiteralValue, + const QString &fileName, int line, int column, + bool *inBaseState) +{ + Q_UNUSED(column); + typedef QPointer<QQuickState> QuickStatePointer; + QObject *object = property.object(); + QString propertyName = property.name(); + for (const QuickStatePointer& statePointer : qAsConst(m_allStates)) { + if (QQuickState *state = statePointer.data()) { + // here we assume that the revert list on itself defines the base state + if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { + *inBaseState = false; + + QQmlBinding *newBinding = nullptr; + if (!isLiteralValue) { + newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, + expression.toString(), object, + QQmlContextData::get(context), fileName, + line); + newBinding->setTarget(property); + } + + state->changeBindingInRevertList(object, propertyName, newBinding); + + if (isLiteralValue) + state->changeValueInRevertList(object, propertyName, expression); + } + } + } +} + +bool QQmlQtQuick2DebugStatesDelegate::setBindingForInvalidProperty(QObject *object, + const QString &propertyName, + const QVariant &expression, + bool isLiteralValue) +{ + if (QQuickPropertyChanges *propertyChanges = qobject_cast<QQuickPropertyChanges *>(object)) { + if (isLiteralValue) + propertyChanges->changeValue(propertyName, expression); + else + propertyChanges->changeExpression(propertyName, expression.toString()); + return true; + } else { + return false; + } +} + +void QQmlQtQuick2DebugStatesDelegate::resetBindingForInvalidProperty(QObject *object, const QString &propertyName) +{ + if (QQuickPropertyChanges *propertyChanges = qobject_cast<QQuickPropertyChanges *>(object)) { + propertyChanges->removeProperty(propertyName); + } +} + +static QQmlDebugStatesDelegate *statesDelegateFactory() +{ + return new QQmlQtQuick2DebugStatesDelegate; +} + +#endif // QT_CONFIG(qml_debug) + class QQuickColorProvider : public QQmlColorProvider { public: @@ -919,11 +1048,23 @@ static QQuickGuiProvider *getGuiProvider() return &guiProvider; } -void QQuick_initializeProviders() +void QQuick_initializeModule() { QQml_addValueTypeProvider(getValueTypeProvider()); QQml_setColorProvider(getColorProvider()); QQml_setGuiProvider(getGuiProvider()); + + QQuickItemsModule::defineModule(); + +#if QT_CONFIG(accessibility) + QAccessible::installFactory(&qQuickAccessibleFactory); +#endif + +#if QT_CONFIG(qml_debug) + QQmlEngineDebugService::setStatesDelegateFactory(statesDelegateFactory); +#endif } +Q_CONSTRUCTOR_FUNCTION(QQuick_initializeModule) + QT_END_NAMESPACE |