Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmlcontext.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmlcontext_p.h"
6
7#include "qqmlcomponent_p.h"
8#include "qqmlexpression_p.h"
9#include "qqmlengine_p.h"
10#include "qqmlengine.h"
11#include "qqmlinfo.h"
13
14#include <qjsengine.h>
15#include <QtCore/qvarlengtharray.h>
16#include <private/qmetaobject_p.h>
17#include <QtCore/qdebug.h>
18
20
91{
92}
93
104
110 : QObject(*(new QQmlContextPrivate(this, parentContext
111 ? QQmlContextData::get(parentContext)
112 : QQmlRefPointer<QQmlContextData>())), parent)
113{
114}
115
120 : QObject(dd, parent)
121{
122}
123
132{
133 Q_D(QQmlContext);
134 d->m_data->clearPublicContext();
135}
136
144{
145 Q_D(const QQmlContext);
146 return d->m_data->isValid();
147}
148
154{
155 Q_D(const QQmlContext);
156 return d->m_data->engine();
157}
158
164{
165 Q_D(const QQmlContext);
166
167 if (QQmlRefPointer<QQmlContextData> parent = d->m_data->parent())
168 return parent->asQQmlContext();
169 return nullptr;
170}
171
176{
177 Q_D(const QQmlContext);
178 return d->m_data->contextObject();
179}
180
188{
189 Q_D(QQmlContext);
190
191 QQmlRefPointer<QQmlContextData> data = d->m_data;
192
193 if (data->isInternal()) {
194 qWarning("QQmlContext: Cannot set context object for internal context.");
195 return;
196 }
197
198 if (!data->isValid()) {
199 qWarning("QQmlContext: Cannot set context object on invalid context.");
200 return;
201 }
202
203 data->setContextObject(object);
204 data->refreshExpressions();
205}
206
214{
215 Q_D(QQmlContext);
216 if (d->notifyIndex() == -1)
217 d->setNotifyIndex(QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject));
218
219 QQmlRefPointer<QQmlContextData> data = d->m_data;
220
221 if (data->isInternal()) {
222 qWarning("QQmlContext: Cannot set property on internal context.");
223 return;
224 }
225
226 if (!data->isValid()) {
227 qWarning("QQmlContext: Cannot set property on invalid context.");
228 return;
229 }
230
231 if (bool isNumber = false; name.toUInt(&isNumber), isNumber) {
232 qWarning("QQmlContext: Using numbers as context properties will be disallowed in a future Qt version.");
233 QT7_ONLY(return;)
234 }
235
236 int idx = data->propertyIndex(name);
237 if (idx == -1) {
238 data->addPropertyNameAndIndex(name, data->numIdValues() + d->numPropertyValues());
239 d->appendPropertyValue(value);
240 data->refreshExpressions();
241 } else {
242 d->setPropertyValue(idx, value);
243 QMetaObject::activate(this, d->notifyIndex(), idx, nullptr);
244 }
245
246 if (auto *obj = qvariant_cast<QObject *>(value)) {
248 d->dropDestroyedQObject(name, destroyed);
249 });
250 }
251}
252
265
280void QQmlContext::setContextProperties(const QList<PropertyPair> &properties)
281{
282 Q_D(const QQmlContext);
283
284 QQmlRefPointer<QQmlContextData> data = d->m_data;
285 QQmlJavaScriptExpression *expressions = data->takeExpressions();
286 QQmlRefPointer<QQmlContextData> childContexts = data->takeChildContexts();
287
288 for (const auto &property : properties)
290
291 data->setExpressions(expressions);
292 data->setChildContexts(childContexts);
293 data->refreshExpressions();
294}
295
309 const QQmlRefPointer<QQmlContextData> &data, QObject *object, const QString &name,
311{
312 QQmlPropertyData local;
313 if (const QQmlPropertyData *property = QQmlPropertyCache::property(object, name, data, &local)) {
314 *target = object->metaObject()->property(property->coreIndex()).read(object);
315 return true;
316 }
317 return false;
318}
319
332{
333 Q_D(const QQmlContext);
334
335 const QQmlRefPointer<QQmlContextData> data = d->m_data;
336
337 const int idx = data->propertyIndex(name);
338 if (idx == -1) {
339 if (QObject *obj = data->contextObject()) {
342 return value;
343 }
344
345 if (parentContext())
347 } else {
348 if (idx >= d->numPropertyValues())
349 return QVariant::fromValue(data->idValue(idx - d->numPropertyValues()));
350 else
351 return d->propertyValue(idx);
352 }
353
354 return QVariant();
355}
356
372{
373 Q_D(const QQmlContext);
374
375 return d->m_data->findObjectId(object);
376}
377
392{
393 Q_D(const QQmlContext);
394
395 QQmlRefPointer<QQmlContextData> data = d->m_data;
396 if (const int propertyIndex = data->propertyIndex(name); propertyIndex >= 0) {
397 const int numPropertyValues = d->numPropertyValues();
398 if (propertyIndex < numPropertyValues)
399 return qvariant_cast<QObject *>(d->propertyValue(propertyIndex));
400 return data->idValue(propertyIndex - numPropertyValues);
401 }
402
403 if (QObject *obj = data->contextObject()) {
406 return qvariant_cast<QObject *>(result);
407 }
408
409 return nullptr;
410}
411
419{
420 Q_D(const QQmlContext);
421 return d->m_data->resolvedUrl(src);
422}
423
433{
434 Q_D(QQmlContext);
435 d->m_data->setBaseUrl(baseUrl);
436 d->m_data->setBaseUrlString(baseUrl.toString());
437}
438
444{
445 Q_D(const QQmlContext);
446 return d->m_data->baseUrl();
447}
448
453{
454 Q_D(const QQmlContext);
455
456 QQmlTypeNameCache::Result r = d->m_data->imports()->query(name, QQmlTypeLoader::get(engine()));
457 QV4::Scope scope(engine()->handle());
458 QV4::ScopedObject scripts(scope, d->m_data->importedScripts().valueRef());
459 return scripts ? QJSValuePrivate::fromReturnedValue(scripts->get(r.scriptIndex))
461}
462
463qsizetype QQmlContextPrivate::context_count(QQmlListProperty<QObject> *prop)
464{
465 QQmlContext *context = static_cast<QQmlContext*>(prop->object);
467 int contextProperty = (int)(quintptr)prop->data;
468
469 if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
470 return 0;
471 else
472 return ((const QList<QObject> *)d->propertyValue(contextProperty).constData())->size();
473}
474
475QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, qsizetype index)
476{
477 QQmlContext *context = static_cast<QQmlContext*>(prop->object);
479 int contextProperty = (int)(quintptr)prop->data;
480
481 if (d->propertyValue(contextProperty).userType() != qMetaTypeId<QList<QObject*> >())
482 return nullptr;
483 else
484 return ((const QList<QObject*> *)d->propertyValue(contextProperty).constData())->at(index);
485}
486
488{
489 if (!m_data->isValid())
490 return;
491
492 const int idx = m_data->propertyIndex(name);
493 Q_ASSERT(idx >= 0);
494 if (qvariant_cast<QObject *>(propertyValue(idx)) != destroyed)
495 return;
496
497 setPropertyValue(idx, QVariant::fromValue<QObject *>(nullptr));
498 QMetaObject::activate(q_func(), notifyIndex(), idx, nullptr);
499}
500
505
506// m_data is owned by the public context. When the public context is reset to nullptr, it will be
507// deref'd. It's OK to pass a half-created publicContext here. We will not dereference it during
508// construction.
509QQmlContextPrivate::QQmlContextPrivate(
510 QQmlContext *publicContext, const QQmlRefPointer<QQmlContextData> &parent,
512 m_data(new QQmlContextData(QQmlContextData::OwnedByPublicContext, publicContext,
513 parent, engine))
514{
515 Q_ASSERT(publicContext != nullptr);
516}
517
519
520#include "moc_qqmlcontext.cpp"
NSData * m_data
static QJSValue fromReturnedValue(QV4::ReturnedValue d)
Definition qjsvalue_p.h:197
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
@ UndefinedValue
Definition qjsvalue.h:35
QVariant read(const QObject *obj) const
Reads the property's value from the given object.
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
int propertyIndex(const QString &name) const
bool isValid() const
void dropDestroyedQObject(const QString &name, QObject *destroyed)
static qsizetype context_count(QQmlListProperty< QObject > *)
void setPropertyValue(int index, const QVariant &value)
int notifyIndex() const
static QQmlContextPrivate * get(QQmlContext *context)
QVariant propertyValue(int index) const
static QObject * context_at(QQmlListProperty< QObject > *, qsizetype)
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
QString nameForObject(const QObject *) const
Returns the name of object in this context, or an empty string if object is not named in the context.
bool isValid() const
Returns whether the context is valid.
void setBaseUrl(const QUrl &)
Explicitly sets the url resolvedUrl() will use for relative references to baseUrl.
QUrl baseUrl() const
Returns the base url of the component, or the containing component if none is set.
QQmlContext(QQmlEngine *parent, QObject *objParent=nullptr)
Create a new QQmlContext as a child of engine's root context, and the QObject parent.
QUrl resolvedUrl(const QUrl &) const
Resolves the URL src relative to the URL of the containing component.
QVariant contextProperty(const QString &) const
Returns the value of the name property for this context as a QVariant.
QJSValue importedScript(const QString &name) const
QQmlContext * parentContext() const
Return the context's parent QQmlContext, or \nullptr if this context has no parent or if the parent h...
QObject * objectForName(const QString &) const
QObject * contextObject() const
Return the context object, or \nullptr if there is no context object.
void setContextProperty(const QString &, QObject *)
Set the value of the name property on this context.
void setContextObject(QObject *)
Set the context object.
QQmlEngine * engine() const
Return the context's QQmlEngine, or \nullptr if the context has no QQmlEngine or the QQmlEngine was d...
~QQmlContext() override
Destroys the QQmlContext.
void setContextProperties(const QList< PropertyPair > &properties)
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
const QQmlPropertyData * property(const K &key, QObject *object, const QQmlRefPointer< QQmlContextData > &context) const
const QMetaObject * metaObject() const
static QQmlTypeLoader * get(Engine *engine)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qurl.h:94
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
\inmodule QtCore
Definition qvariant.h:65
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 >
Definition qvariant.h:536
#define this
Definition dialogs.cpp:9
Combined button and popup list for selecting options.
static void * context
static const QCssKnownValue properties[NumProperties - 1]
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
static bool isNumber(char s)
GLuint64 GLenum void * handle
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLenum target
GLuint name
GLhandleARB obj
[2]
GLuint64EXT * result
[6]
static bool readObjectProperty(const QQmlRefPointer< QQmlContextData > &data, QObject *object, const QString &name, QVariant *target)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
const char property[13]
Definition qwizard.cpp:101
QUrl baseUrl
QAction * at
QJSEngine engine
[0]
static Q_CORE_EXPORT int absoluteSignalCount(const QMetaObject *m)
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
static void activate(QObject *sender, int signal_index, void **argv)
Definition qobject.cpp:4193
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const