6#include <private/qqmlanybinding_p.h>
7#include <private/qqmlbinding_p.h>
8#include <private/qqmlcomponent_p.h>
9#include <private/qqmlmetatype_p.h>
10#include <private/qqmlnullablevalue_p.h>
11#include <private/qqmlproperty_p.h>
12#include <private/qqmlvmemetaobject_p.h>
13#include <private/qv4persistent_p.h>
14#include <private/qv4qmlcontext_p.h>
15#include <private/qv4resolvedtypereference_p.h>
17#include <QtQml/qqmlcontext.h>
18#include <QtQml/qqmlengine.h>
19#include <QtQml/qqmlinfo.h>
20#include <QtQml/qqmlproperty.h>
21#include <QtQml/qqmlpropertymap.h>
23#include <QtCore/private/qobject_p.h>
25#include <QtCore/qdebug.h>
26#include <QtCore/qfile.h>
27#include <QtCore/qloggingcategory.h>
28#include <QtCore/qpointer.h>
29#include <QtCore/qtimer.h>
58 silentDestroy(oldKind);
78 silentDestroy(oldKind);
115 silentDestroy(oldKind);
122 silentDestroy(oldKind);
129 silentDestroy(oldKind);
425 if (
v &&
d->componentComplete)
461 if (
d->obj &&
d->when) {
474 if (
auto abstractBinding = potentialWhenBinding.asAbstractBinding()) {
477 const auto boolType = QMetaType::fromType<bool>();
484 if (
d->componentComplete) {
531 if (!
d->propName.isEmpty() &&
d->when) {
539 if (
d->componentComplete) {
559 if (!
d->lastIsTarget)
562 return d->entries.last().current.variant;
612 if (!
d->componentComplete)
615 d->delayedValues.reset();
617 QVarLengthArray<QQmlBindEntry, 1> oldEntries = std::move(
d->entries);
619 d->buildBindEntries(
this,
nullptr);
621 if (
d->lastIsTarget) {
622 d->entries.append(std::move(oldEntries.last()));
623 oldEntries.pop_back();
630 std::move(oldEntry.previous), oldEntry.previousKind, newEntry.previousKind);
666 if (
d->restoreBinding)
684 d->targetEntry()->setTarget(
this,
p);
689 if (
Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) {
692 if (metaProp.hasNotifySignal()) {
695 q,
SLOT(targetValueChanged()));
698 p.connectNotifySignal(
q,
SLOT(targetValueChanged()));
707 d->componentComplete =
false;
712 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
713 const QQmlRefPointer<QQmlContextData> &contextData,
716 switch (binding->
type()) {
724 prop, compilationUnit->bindingValueAsString(binding), scopeObject,
725 contextData, compilationUnit->finalUrlString(), binding->
location.
line());
727 QV4::Scope scope(contextData->engine()->handle());
732 prop, compilationUnit->runtimeFunctions.at(
id), scopeObject, contextData,
743 const QQmlRefPointer<QQmlContextData> &contextData,
746 if (!immediateState->hasCreator()) {
747 immediateState->setCompletePending(
true);
748 immediateState->initCreator(
751 immediateState->creator()->beginPopulateDeferred(deferredData->
context);
761 const QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit
764 const QString propertyName = propertyPrefix + propertySuffix;
766 switch (binding->
type()) {
768 if (propertyPrefix.isEmpty()) {
775 Q_ASSERT(compilationUnit->stringAt(compilationUnit->objectAt(binding->
value.objectIndex)
776 ->inheritedTypeNameIndex).isEmpty());
781 QQmlType attachedType = typeReference->type();
783 if (
QQmlTypeLoader *typeLoader = compilationUnit->engine->typeLoader()) {
788 <<
"Unknown name " << propertySuffix <<
". The binding is ignored.";
791 attachedType =
result.type;
800 qmlWarning(
q).nospace() <<
"Could not create attached properties object '"
806 immediateState->creator()->populateDeferredInstance(
813 const QString pre = propertyName + u
'.';
815 = compilationUnit->objectAt(binding->
value.objectIndex);
817 for (
quint32 i = 0;
i < subObj->nBindings; ++
i, ++subBinding)
830 if (!
entry.prop.isValid()) {
839 initCreator(deferredData, contextData, immediateState);
840 immediateState->creator()->populateDeferredBinding(
843 qmlWarning(
q).nospace() <<
"Unknown name " << propertyName
844 <<
". The binding is ignored.";
857 switch (binding->
type()) {
873 bindingTarget, binding, compilationUnit, contextData,
q);
874 anyBinding.installOn(bindingTarget);
880 setVariant(compilationUnit->bindingValueAsString(binding));
883 setVariant(compilationUnit->bindingValueAsNumber(binding));
906 onDelayedValueChanged(std::move(delayedName));
919 else if (
pending.contains(delayedName))
922 pending.append(std::move(delayedName));
923 (*delayedValues)[pendingName].setValue(std::move(
pending));
935 const int delayedIndex = delayedName.toInt(&
ok);
940 (*delayedValues)[pendingName].setValue(
QStringList());
946 if (
data && !
data->deferredData.isEmpty()) {
949 QMultiHash<int, const QV4::CompiledData::Binding *> *bindings = &deferredData->bindings;
952 for (
auto it = bindings->cbegin();
it != bindings->cend(); ++
it)
956 if (constructionState.hasCreator()) {
958 constructionState.creator()->finalizePopulateDeferred();
959 constructionState.appendCreatorErrors();
960 deferredState->push_back(std::move(constructionState));
963 for (
auto it = bindings->cbegin();
it != bindings->cend(); ++
it)
969 data->releaseDeferredData();
970 if (!deferredState->empty())
980 d->buildBindEntries(
this, &deferredState);
981 d->componentComplete =
true;
982 if (!
d->propName.isEmpty() ||
d->obj) {
984 if (!
target->prop.isValid())
992void QQmlBind::prepareEval()
998 d->pendingEval =
true;
1009void QQmlBind::eval()
1012 d->pendingEval =
false;
1013 if (!
d->componentComplete)
1022 switch (
entry.previousKind) {
1024 if (
d->restoreBinding) {
1031 if (
d->restoreValue) {
1036 vmemo->setVMEProperty(propPriv->core.coreIndex(),
1037 *
entry.previous.v4Value.valueRef());
1042 if (
d->restoreValue) {
1059 entry.previousKind =
entry.previous.set(std::move(prevBind),
entry.previousKind);
1063 auto propData = propPriv->core;
1064 if (!propPriv->valueTypeData.isValid() && propData.isVarProperty()) {
1067 auto retVal = vmemo->vmeProperty(propData.coreIndex());
1085 d->writingProperty =
true;
1088 if (!
entry.prop.isValid())
1090 switch (
entry.currentKind) {
1101 propPriv->core.coreIndex(), *
entry.current.v4Value.valueRef());
1108 d->writingProperty =
false;
1111void QQmlBind::targetValueChanged()
1114 if (
d->writingProperty)
1124 if (ddata && ddata->outerContext) {
1125 url = ddata->outerContext->
url();
1126 line = ddata->lineNumber;
1130 "The target property of the Binding element created at %s:%d was changed from "
1131 "elsewhere. This does not overwrite the binding. The target property will still be "
1132 "updated when the value of the Binding element changes.",
1138#include "moc_qqmlbind_p.cpp"
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
QQmlAnyBinding is an abstraction over the various bindings in QML.
static QQmlAnyBinding createFromCodeString(const QQmlProperty &prop, const QString &code, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, const QString &url, quint16 lineNumber)
static void removeBindingFrom(QQmlProperty &prop)
static QQmlAnyBinding createTranslationBinding(const QQmlProperty &prop, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QV4::CompiledData::Binding *translationBinding, QObject *scopeObject=nullptr, QQmlRefPointer< QQmlContextData > context={})
static QQmlAnyBinding takeFrom(const QQmlProperty &prop)
Removes the binding from the property prop, and returns it as a QQmlAnyBinding if there was any.
~QQmlAnyBinding() noexcept
static QQmlAnyBinding ofProperty(const QQmlProperty &prop)
static QQmlAnyBinding createFromFunction(const QQmlProperty &prop, QV4::Function *function, QObject *obj, const QQmlRefPointer< QQmlContextData > &ctxt, QV4::ExecutionContext *scope)
void validate(QQmlBind *binding) const
std::unique_ptr< QQmlPropertyMap > delayedValues
QVarLengthArray< QQmlBindEntry, 1 > entries
QQmlBindEntry * targetEntry()
void onDelayedValueChanged(QString delayedName)
void decodeBinding(QQmlBind *q, const QString &propertyPrefix, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding, QQmlComponentPrivate::ConstructionState *immediateState)
void buildBindEntries(QQmlBind *q, QQmlComponentPrivate::DeferredState *deferredState)
void createDelayedValues()
void setRestoreMode(RestorationMode)
void classBegin() override
Invoked after class creation, but before any properties have been set.
RestorationMode restoreMode
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setTarget(const QQmlProperty &) override
Set the target property for the value source.
QQmlBind(QObject *parent=nullptr)
QObject * object()
\qmlproperty QtObject QtQml::Binding::target
void setValue(const QVariant &)
void setObject(QObject *)
void setProperty(const QString &)
void restoreModeChanged()
std::vector< ConstructionState > DeferredState
static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState)
QQmlRefPointer< QQmlTypeNameCache > imports() const
static QQmlRefPointer< QQmlContextData > get(QQmlContext *context)
QQmlRefPointer< QQmlContextData > parent() const
The QQmlContext class defines a context within a QML engine.
static QQmlData * get(QObjectPrivate *priv, bool create)
static QQmlEnginePrivate * get(QQmlEngine *e)
bool hasValidContext() const
void valueChanged(const QString &key, const QVariant &value)
This signal is emitted whenever one of the values in the map is changed.
static QQmlProperty create(QObject *target, const QString &propertyName, const QQmlRefPointer< QQmlContextData > &context, QQmlPropertyPrivate::InitFlags flags)
static void removeBinding(const QQmlProperty &that)
static QQmlPropertyPrivate * get(const QQmlProperty &p)
The QQmlProperty class abstracts accessing properties on objects created from QML.
bool isValid() const
Returns true if the QQmlProperty refers to a valid property, otherwise false.
int index() const
Return the Qt metaobject index of the property.
QML_ANONYMOUSQObject * object
bool isWritable() const
Returns true if the property is writable, otherwise false.
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
Result query(const QHashedStringRef &key, QQmlTypeLoader *typeLoader) const
QQmlAttachedPropertiesFunc attachedPropertiesFunction(QQmlEnginePrivate *engine) const
QByteArray typeName() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool singleShot
whether the timer is a single-shot timer
QString url(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
constexpr size_type size() const noexcept
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
~QVariant()
Destroys the QVariant and the contained object.
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QList< QString > QStringList
Constructs a string list that contains the given string, str.
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 return DBusPendingCall * pending
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCInfo(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLsizei const GLfloat * v
[13]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
QQmlContext * qmlContext(const QObject *obj)
QObject * qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc func, bool create)
static void initCreator(QQmlData::DeferredData *deferredData, const QQmlRefPointer< QQmlContextData > &contextData, QQmlComponentPrivate::ConstructionState *immediateState)
static QQmlAnyBinding createBinding(const QQmlProperty &prop, const QV4::CompiledData::Binding *binding, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &compilationUnit, const QQmlRefPointer< QQmlContextData > &contextData, QObject *scopeObject)
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static QQuickAttachedPropertyPropagator * attachedObject(const QMetaObject *type, QObject *object, bool create=false)
#define qPrintable(string)
#define QStringLiteral(str)
QUrl url("example.com")
[constructor-url-reference]
QQmlBindEntryKind previousKind
QQmlBindEntry(const QQmlBindEntry &other)
QQmlBindEntry & operator=(QQmlBindEntry &&other) noexcept
void setTarget(QQmlBind *q, const QQmlProperty &p)
QQmlBindEntryKind currentKind
QQmlBindEntry & operator=(const QQmlBindEntry &other)
QQmlBindEntryContent current
QQmlBindEntryContent previous
void validate(QQmlBind *q) const
QQmlBindEntry(QQmlBindEntry &&other) noexcept
QQmlRefPointer< QQmlContextData > context
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
quint32_le propertyNameIndex
bool valueAsBoolean() const
union QV4::CompiledData::Binding::@545 value
ExecutionContext * rootContext() const
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)
QQmlBindEntryKind set(const QQmlBindEntryContent &other, QQmlBindEntryKind newKind, QQmlBindEntryKind oldKind)
QQmlBindEntryKind set(QQmlAnyBinding v, QQmlBindEntryKind oldKind)
QV4::PersistentValue v4Value
QQmlBindEntryKind set(QV4::PersistentValue v, QQmlBindEntryKind oldKind)
QQmlBindEntryKind set(QVariant v, QQmlBindEntryKind oldKind)
QQmlBindEntryKind set(QQmlBindEntryContent &&other, QQmlBindEntryKind newKind, QQmlBindEntryKind oldKind)
QQmlBindEntryKind destroy(QQmlBindEntryKind kind)