summaryrefslogtreecommitdiff
path: root/src/declarative/qml/qmlcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qmlcontext.cpp')
-rw-r--r--src/declarative/qml/qmlcontext.cpp574
1 files changed, 0 insertions, 574 deletions
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
deleted file mode 100644
index 17183872bd..0000000000
--- a/src/declarative/qml/qmlcontext.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlcontext.h"
-#include "qmlcontext_p.h"
-
-#include "qmlexpression_p.h"
-#include "qmlengine_p.h"
-#include "qmlengine.h"
-#include "qmlcompiledbindings_p.h"
-#include "qmlinfo.h"
-
-#include <qscriptengine.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qdebug.h>
-
-#include <private/qscriptdeclarativeclass_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QmlContextPrivate::QmlContextPrivate()
-: parent(0), engine(0), isInternal(false), propertyNames(0),
- notifyIndex(-1), highPriorityCount(0), imports(0), expressions(0), contextObjects(0),
- idValues(0), idValueCount(0), optimizedBindings(0)
-{
-}
-
-void QmlContextPrivate::addScript(const QmlParser::Object::ScriptBlock &script, QObject *scopeObject)
-{
- Q_Q(QmlContext);
-
- if (!engine)
- return;
-
- QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
- QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);
-
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
- scriptContext->pushScope(enginePriv->contextClass->newContext(q, scopeObject));
-
- QScriptValue scope = scriptEngine->newObject();
- scriptContext->setActivationObject(scope);
-
- for (int ii = 0; ii < script.codes.count(); ++ii) {
- scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii));
-
- if (scriptEngine->hasUncaughtException()) {
- QmlError error;
- QmlExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
- }
- }
-
- scriptEngine->popContext();
-
- scripts.append(scope);
-}
-
-void QmlContextPrivate::destroyed(ContextGuard *guard)
-{
- Q_Q(QmlContext);
-
- // process of being deleted (which is *probably* why obj has been destroyed
- // anyway), as we're about to get deleted which will invalidate all the
- // expressions that could depend on us
- QObject *parent = q->parent();
- if (parent && QObjectPrivate::get(parent)->wasDeleted)
- return;
-
- while(guard->bindings) {
- QObject *o = guard->bindings->target;
- int mi = guard->bindings->methodIndex;
- guard->bindings->clear();
- if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0);
- }
-
- for (int ii = 0; ii < idValueCount; ++ii) {
- if (&idValues[ii] == guard) {
- QMetaObject::activate(q, ii + notifyIndex, 0);
- return;
- }
- }
-}
-
-void QmlContextPrivate::init()
-{
- Q_Q(QmlContext);
-
- if (parent)
- parent->d_func()->childContexts.insert(q);
-}
-
-/*!
- \class QmlContext
- \since 4.7
- \brief The QmlContext class defines a context within a QML engine.
- \mainclass
-
- Contexts allow data to be exposed to the QML components instantiated by the
- QML engine.
-
- Each QmlContext contains a set of properties, distinct from
- its QObject properties, that allow data to be
- explicitly bound to a context by name. The context properties are defined or
- updated by calling QmlContext::setContextProperty(). The following example shows
- a Qt model being bound to a context and then accessed from a QML file.
-
- \code
- QmlEngine engine;
- QmlContext context(engine.rootContext());
- context.setContextProperty("myModel", modelData);
-
- QmlComponent component(&engine, "ListView { model=myModel }");
- component.create(&context);
- \endcode
-
- To simplify binding and maintaining larger data sets, QObject's can be
- added to a QmlContext. These objects are known as the context's default
- objects. In this case all the properties of the QObject are
- made available by name in the context, as though they were all individually
- added by calling QmlContext::setContextProperty(). Changes to the property's
- values are detected through the property's notify signal. This method is
- also slightly more faster than manually adding property values.
-
- The following example has the same effect as the one above, but it is
- achieved using a default object.
-
- \code
- class MyDataSet : ... {
- ...
- Q_PROPERTY(QAbstractItemModel *myModel READ model NOTIFY modelChanged)
- ...
- };
-
- MyDataSet myDataSet;
- QmlEngine engine;
- QmlContext context(engine.rootContext());
- context.addDefaultObject(&myDataSet);
-
- QmlComponent component(&engine, "ListView { model=myModel }");
- component.create(&context);
- \endcode
-
- Default objects added first take precedence over those added later. All properties
- added explicitly by QmlContext::setContextProperty() take precedence over default
- object properties.
-
- Contexts are hierarchal, with the \l {QmlEngine::rootContext()}{root context}
- being created by the QmlEngine. A component instantiated in a given context
- has access to that context's data, as well as the data defined by its
- ancestor contexts. Data values (including those added implicitly by the
- default objects) in a context override those in ancestor contexts. Data
- that should be available to all components instantiated by the QmlEngine
- should be added to the \l {QmlEngine::rootContext()}{root context}.
-
- In the following example,
-
- \code
- QmlEngine engine;
- QmlContext context1(engine.rootContext());
- QmlContext context2(&context1);
- QmlContext context3(&context2);
-
- context1.setContextProperty("a", 12);
- context2.setContextProperty("b", 13);
- context3.setContextProperty("a", 14);
- context3.setContextProperty("c", 14);
- \endcode
-
- a QML component instantiated in context1 would have access to the "a" data,
- a QML component instantiated in context2 would have access to the "a" and
- "b" data, and a QML component instantiated in context3 would have access to
- the "a", "b" and "c" data - although its "a" data would return 14, unlike
- that in context1 or context2.
-*/
-
-/*! \internal */
-QmlContext::QmlContext(QmlEngine *e, bool)
-: QObject(*(new QmlContextPrivate))
-{
- Q_D(QmlContext);
- d->engine = e;
- d->init();
-}
-
-/*!
- Create a new QmlContext as a child of \a engine's root context, and the
- QObject \a parent.
-*/
-QmlContext::QmlContext(QmlEngine *engine, QObject *parent)
-: QObject(*(new QmlContextPrivate), parent)
-{
- Q_D(QmlContext);
- QmlContext *parentContext = engine?engine->rootContext():0;
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->init();
-}
-
-/*!
- Create a new QmlContext with the given \a parentContext, and the
- QObject \a parent.
-*/
-QmlContext::QmlContext(QmlContext *parentContext, QObject *parent)
-: QObject(*(new QmlContextPrivate), parent)
-{
- Q_D(QmlContext);
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->init();
-}
-
-/*!
- \internal
-*/
-QmlContext::QmlContext(QmlContext *parentContext, QObject *parent, bool)
-: QObject(*(new QmlContextPrivate), parent)
-{
- Q_D(QmlContext);
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->isInternal = true;
- d->init();
-}
-
-/*!
- Destroys the QmlContext.
-
- Any expressions, or sub-contexts dependent on this context will be
- invalidated, but not destroyed (unless they are parented to the QmlContext
- object).
- */
-QmlContext::~QmlContext()
-{
- Q_D(QmlContext);
- if (d->parent)
- d->parent->d_func()->childContexts.remove(this);
-
- for (QSet<QmlContext *>::ConstIterator iter = d->childContexts.begin();
- iter != d->childContexts.end();
- ++iter) {
- (*iter)->d_func()->invalidateEngines();
- (*iter)->d_func()->parent = 0;
- }
-
- QmlAbstractExpression *expression = d->expressions;
- while (expression) {
- QmlAbstractExpression *nextExpression = expression->m_nextExpression;
-
- expression->m_context = 0;
- expression->m_prevExpression = 0;
- expression->m_nextExpression = 0;
-
- expression = nextExpression;
- }
-
- while (d->contextObjects) {
- QmlDeclarativeData *co = d->contextObjects;
- d->contextObjects = d->contextObjects->nextContextObject;
-
- co->context = 0;
- co->nextContextObject = 0;
- co->prevContextObject = 0;
- }
-
- if (d->propertyNames)
- d->propertyNames->release();
-
- if (d->imports)
- d->imports->release();
-
- if (d->optimizedBindings)
- d->optimizedBindings->release();
-
- delete [] d->idValues;
-}
-
-void QmlContextPrivate::invalidateEngines()
-{
- if (!engine)
- return;
- engine = 0;
- for (QSet<QmlContext *>::ConstIterator iter = childContexts.begin();
- iter != childContexts.end();
- ++iter) {
- (*iter)->d_func()->invalidateEngines();
- }
-}
-
-/*
-Refreshes all expressions that could possibly depend on this context.
-Refreshing flushes all context-tree dependent caches in the expressions, and should occur every
-time the context tree *structure* (not values) changes.
-*/
-void QmlContextPrivate::refreshExpressions()
-{
- for (QSet<QmlContext *>::ConstIterator iter = childContexts.begin();
- iter != childContexts.end();
- ++iter) {
- (*iter)->d_func()->refreshExpressions();
- }
-
- QmlAbstractExpression *expression = expressions;
- while (expression) {
- expression->refresh();
- expression = expression->m_nextExpression;
- }
-}
-
-/*!
- Return the context's QmlEngine, or 0 if the context has no QmlEngine or the
- QmlEngine was destroyed.
-*/
-QmlEngine *QmlContext::engine() const
-{
- Q_D(const QmlContext);
- return d->engine;
-}
-
-/*!
- Return the context's parent QmlContext, or 0 if this context has no
- parent or if the parent has been destroyed.
-*/
-QmlContext *QmlContext::parentContext() const
-{
- Q_D(const QmlContext);
- return d->parent;
-}
-
-/*!
- Add \a defaultObject to this context. The object will be added after
- any existing default objects.
-*/
-void QmlContext::addDefaultObject(QObject *defaultObject)
-{
- Q_D(QmlContext);
- d->defaultObjects.prepend(defaultObject);
-}
-
-/*!
- Set a the \a value of the \a name property on this context.
-*/
-void QmlContext::setContextProperty(const QString &name, const QVariant &value)
-{
- Q_D(QmlContext);
- if (d->notifyIndex == -1)
- d->notifyIndex = this->metaObject()->methodCount();
-
- if (d->engine) {
- bool ok;
- QObject *o = QmlEnginePrivate::get(d->engine)->toQObject(value, &ok);
- if (ok) {
- setContextProperty(name, o);
- return;
- }
- }
-
- if (!d->propertyNames) d->propertyNames = new QmlIntegerCache(d->engine);
-
- int idx = d->propertyNames->value(name);
- if (idx == -1) {
- d->propertyNames->add(name, d->idValueCount + d->propertyValues.count());
- d->propertyValues.append(value);
-
- d->refreshExpressions();
- } else {
- d->propertyValues[idx] = value;
- QMetaObject::activate(this, idx + d->notifyIndex, 0);
- }
-}
-
-void QmlContextPrivate::setIdProperty(int idx, QObject *obj)
-{
- if (notifyIndex == -1) {
- Q_Q(QmlContext);
- notifyIndex = q->metaObject()->methodCount();
- }
-
- idValues[idx].priv = this;
- idValues[idx] = obj;
-}
-
-void QmlContextPrivate::setIdPropertyData(QmlIntegerCache *data)
-{
- Q_ASSERT(!propertyNames);
- propertyNames = data;
- propertyNames->addref();
-
- idValueCount = data->count();
- idValues = new ContextGuard[idValueCount];
-}
-
-/*!
- Set the \a value of the \a name property on this context.
-
- QmlContext does \bold not take ownership of \a value.
-*/
-void QmlContext::setContextProperty(const QString &name, QObject *value)
-{
- Q_D(QmlContext);
- if (d->notifyIndex == -1)
- d->notifyIndex = this->metaObject()->methodCount();
-
- if (!d->propertyNames) d->propertyNames = new QmlIntegerCache(d->engine);
- int idx = d->propertyNames->value(name);
-
- if (idx == -1) {
- d->propertyNames->add(name, d->idValueCount + d->propertyValues.count());
- d->propertyValues.append(QVariant::fromValue(value));
-
- d->refreshExpressions();
- } else {
- d->propertyValues[idx] = QVariant::fromValue(value);
- QMetaObject::activate(this, idx + d->notifyIndex, 0);
- }
-}
-
-/*!
- Returns the value of the \a name property for this context
- as a QVariant.
- */
-QVariant QmlContext::contextProperty(const QString &name) const
-{
- Q_D(const QmlContext);
- QVariant value;
- int idx = -1;
- if (d->propertyNames)
- idx = d->propertyNames->value(name);
-
- if (idx == -1) {
- QByteArray utf8Name = name.toUtf8();
- for (int ii = d->defaultObjects.count() - 1; ii >= 0; --ii) {
- QObject *obj = d->defaultObjects.at(ii);
- QmlPropertyCache::Data local;
- QmlPropertyCache::Data *property = QmlPropertyCache::property(d->engine, obj, name, local);
-
- if (property) {
- value = obj->metaObject()->property(property->coreIndex).read(obj);
- break;
- }
- }
- if (!value.isValid() && parentContext())
- value = parentContext()->contextProperty(name);
- } else {
- value = d->propertyValues[idx];
- }
-
- return value;
-}
-
-/*!
- Resolves the URL \a src relative to the URL of the
- containing component.
-
- \sa QmlEngine::baseUrl(), setBaseUrl()
-*/
-QUrl QmlContext::resolvedUrl(const QUrl &src)
-{
- Q_D(QmlContext);
- QmlContext *ctxt = this;
- if (src.isRelative() && !src.isEmpty()) {
- if (ctxt) {
- while(ctxt) {
- if(ctxt->d_func()->url.isValid())
- break;
- else
- ctxt = ctxt->parentContext();
- }
-
- if (ctxt)
- return ctxt->d_func()->url.resolved(src);
- else if (d->engine)
- return d->engine->baseUrl().resolved(src);
- }
- return QUrl();
- } else {
- return src;
- }
-}
-
-/*!
- Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl.
-
- Calling this function will override the url of the containing
- component used by default.
-
- \sa resolvedUrl()
-*/
-void QmlContext::setBaseUrl(const QUrl &baseUrl)
-{
- d_func()->url = baseUrl;
-}
-
-/*!
- Returns the base url of the component, or the containing component
- if none is set.
-*/
-QUrl QmlContext::baseUrl() const
-{
- const QmlContext* p = this;
- while (p && p->d_func()->url.isEmpty()) {
- p = p->parentContext();
- }
- if (p)
- return p->d_func()->url;
- else
- return QUrl();
-}
-
-int QmlContextPrivate::context_count(QmlListProperty<QObject> *prop)
-{
- QmlContext *context = static_cast<QmlContext*>(prop->object);
- QmlContextPrivate *d = QmlContextPrivate::get(context);
- int contextProperty = (int)(intptr_t)prop->data;
-
- if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
- return 0;
- } else {
- return ((const QList<QObject> *)d->propertyValues.at(contextProperty).constData())->count();
- }
-}
-
-QObject *QmlContextPrivate::context_at(QmlListProperty<QObject> *prop, int index)
-{
- QmlContext *context = static_cast<QmlContext*>(prop->object);
- QmlContextPrivate *d = QmlContextPrivate::get(context);
- int contextProperty = (int)(intptr_t)prop->data;
-
- if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
- return 0;
- } else {
- return ((const QList<QObject*> *)d->propertyValues.at(contextProperty).constData())->at(index);
- }
-}
-
-QT_END_NAMESPACE