1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qdeclarativeexpression.h"
43 #include "private/qdeclarativeexpression_p.h"
45 #include "private/qdeclarativeengine_p.h"
46 #include "private/qdeclarativecontext_p.h"
47 #include "private/qdeclarativerewrite_p.h"
48 #include "private/qdeclarativecompiler_p.h"
50 #include <QtCore/qdebug.h>
51 #include <QtScript/qscriptprogram.h>
53 #include <private/qscriptdeclarativeclass_p.h>
57 bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e)
61 if (e->inProgressCreations == 0) return false; // Not in construction
63 if (prevError) return true; // Already in error chain
65 prevError = &e->erroredBindings;
66 nextError = e->erroredBindings;
67 e->erroredBindings = this;
68 if (nextError) nextError->prevError = &nextError;
73 QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression()
74 : dataRef(0), expressionFunctionMode(ExplicitContext), scopeObject(0), trackChange(false),
75 guardList(0), guardListLength(0), guardObject(0), guardObjectNotifyIndex(-1), deleted(0)
79 QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression()
83 v8function = v8::Persistent<v8::Function>();
84 v8qmlscope = v8::Persistent<v8::Function>();
86 if (guardList) { delete [] guardList; guardList = 0; }
87 if (dataRef) dataRef->release();
88 if (deleted) *deleted = true;
91 QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate()
92 : expressionFunctionValid(true), line(-1)
96 QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate()
100 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr,
105 QDeclarativeAbstractExpression::setContext(ctxt);
107 expressionFunctionValid = false;
110 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, v8::Handle<v8::Function> func,
114 // expression = func.toString();
116 QDeclarativeAbstractExpression::setContext(ctxt);
119 v8function = v8::Persistent<v8::Function>::New(func);
120 expressionFunctionMode = ExplicitContext;
121 expressionFunctionValid = true;
124 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr,
125 QDeclarativeRefCount *rc,
126 QObject *me, const QString &srcUrl, int lineNumber)
134 if (dataRef) dataRef->addref();
136 quint32 *exprData = (quint32 *)expr;
137 QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc;
139 expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
141 int progIdx = *(exprData);
142 bool isSharedProgram = progIdx & 0x80000000;
143 progIdx &= 0x7FFFFFFF;
145 v8function = evalFunction(ctxt, me, expression, url, line, &v8qmlscope);
147 expressionFunctionMode = ExplicitContext;
148 expressionFunctionValid = true;
150 QDeclarativeAbstractExpression::setContext(ctxt);
154 // Callee owns the persistent handle
155 v8::Persistent<v8::Function>
156 QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObject *scope,
157 const QString &code, const QString &filename, int line,
158 v8::Persistent<v8::Object> *qmlscope)
160 QDeclarativeEngine *engine = ctxt->engine;
161 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
163 // XXX aakenned optimize
164 v8::HandleScope handle_scope;
165 v8::Context::Scope ctxtscope(ep->v8engine.context());
169 v8::Local<v8::Object> scopeobject = ep->v8engine.qmlScope(ctxt, scope);
170 v8::Local<v8::Script> script = ep->v8engine.qmlModeCompile(code, filename, line);
171 v8::Local<v8::Value> result = script->Run(scopeobject);
172 if (qmlscope) *qmlscope = v8::Persistent<v8::Object>::New(scopeobject);
173 return v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(result));
176 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
177 const QString &program, const QString &fileName,
178 int lineNumber, QScriptValue *contextObject)
181 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
182 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
184 *contextObject = ep->contextClass->newContext(context, object);
185 scriptContext->pushScope(*contextObject);
187 scriptContext->pushScope(ep->contextClass->newContext(context, object));
189 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
190 QScriptValue rv = ep->scriptEngine.evaluate(program, fileName, lineNumber);
191 ep->scriptEngine.popContext();
198 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
199 const QScriptProgram &program,
200 QScriptValue *contextObject)
203 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
204 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
206 *contextObject = ep->contextClass->newContext(context, object);
207 scriptContext->pushScope(*contextObject);
209 scriptContext->pushScope(ep->contextClass->newContext(context, object));
211 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
212 QScriptValue rv = ep->scriptEngine.evaluate(program);
213 ep->scriptEngine.popContext();
221 \class QDeclarativeExpression
223 \brief The QDeclarativeExpression class evaluates JavaScript in a QML context.
225 For example, given a file \c main.qml like this:
231 width: 200; height: 200
235 The following code evaluates a JavaScript expression in the context of the
239 QDeclarativeEngine *engine = new QDeclarativeEngine;
240 QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));
242 QObject *myObject = component.create();
243 QDeclarativeExpression *expr = new QDeclarativeExpression(engine->rootContext(), myObject, "width * 2");
244 int result = expr->evaluate().toInt(); // result = 400
248 static int QDeclarativeExpression_notifyIdx = -1;
251 Create an invalid QDeclarativeExpression.
253 As the expression will not have an associated QDeclarativeContext, this will be a
254 null expression object and its value will always be an invalid QVariant.
256 QDeclarativeExpression::QDeclarativeExpression()
257 : QObject(*new QDeclarativeExpressionPrivate, 0)
259 Q_D(QDeclarativeExpression);
261 if (QDeclarativeExpression_notifyIdx == -1)
262 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
263 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
267 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr,
268 QDeclarativeRefCount *rc, QObject *me,
269 const QString &url, int lineNumber,
270 QDeclarativeExpressionPrivate &dd)
273 Q_D(QDeclarativeExpression);
274 d->init(ctxt, expr, rc, me, url, lineNumber);
276 if (QDeclarativeExpression_notifyIdx == -1)
277 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
278 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
282 Create a QDeclarativeExpression object that is a child of \a parent.
284 The \a expression JavaScript will be executed in the \a ctxt QDeclarativeContext.
285 If specified, the \a scope object's properties will also be in scope during
286 the expression's execution.
288 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt,
290 const QString &expression,
292 : QObject(*new QDeclarativeExpressionPrivate, parent)
294 Q_D(QDeclarativeExpression);
295 d->init(QDeclarativeContextData::get(ctxt), expression, scope);
297 if (QDeclarativeExpression_notifyIdx == -1)
298 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
299 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
305 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
306 const QString &expression)
307 : QObject(*new QDeclarativeExpressionPrivate, 0)
309 Q_D(QDeclarativeExpression);
310 d->init(ctxt, expression, scope);
312 if (QDeclarativeExpression_notifyIdx == -1)
313 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
314 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
318 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
319 const QString &expression, QDeclarativeExpressionPrivate &dd)
322 Q_D(QDeclarativeExpression);
323 d->init(ctxt, expression, scope);
325 if (QDeclarativeExpression_notifyIdx == -1)
326 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
327 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
333 To avoid exposing v8 in the public API, functionPtr must be a pointer to a v8::Handle<v8::Function>.
335 v8::Handle<v8::Function> function;
336 new QDeclarativeExpression(ctxt, scope, &function, ...);
338 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, void *functionPtr,
339 QDeclarativeExpressionPrivate &dd)
342 v8::Handle<v8::Function> function = *(v8::Handle<v8::Function> *)functionPtr;
344 Q_D(QDeclarativeExpression);
345 d->init(ctxt, function, scope);
347 if (QDeclarativeExpression_notifyIdx == -1)
348 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
350 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
354 Destroy the QDeclarativeExpression instance.
356 QDeclarativeExpression::~QDeclarativeExpression()
361 Returns the QDeclarativeEngine this expression is associated with, or 0 if there
362 is no association or the QDeclarativeEngine has been destroyed.
364 QDeclarativeEngine *QDeclarativeExpression::engine() const
366 Q_D(const QDeclarativeExpression);
367 return d->context()?d->context()->engine:0;
371 Returns the QDeclarativeContext this expression is associated with, or 0 if there
372 is no association or the QDeclarativeContext has been destroyed.
374 QDeclarativeContext *QDeclarativeExpression::context() const
376 Q_D(const QDeclarativeExpression);
377 QDeclarativeContextData *data = d->context();
378 return data?data->asQDeclarativeContext():0;
382 Returns the expression string.
384 QString QDeclarativeExpression::expression() const
386 Q_D(const QDeclarativeExpression);
387 return d->expression;
391 Set the expression to \a expression.
393 void QDeclarativeExpression::setExpression(const QString &expression)
395 Q_D(QDeclarativeExpression);
397 d->resetNotifyOnChange();
398 d->expression = expression;
399 d->expressionFunctionValid = false;
400 d->v8function.Dispose();
401 d->v8qmlscope.Dispose();
402 d->v8function = v8::Persistent<v8::Function>();
403 d->v8qmlscope = v8::Persistent<v8::Function>();
406 void QDeclarativeExpressionPrivate::exceptionToError(v8::Handle<v8::Message> message,
407 QDeclarativeError &error)
409 Q_ASSERT(!message.IsEmpty());
411 v8::Handle<v8::Value> name = message->GetScriptResourceName();
412 v8::Handle<v8::String> description = message->Get();
413 int lineNumber = message->GetLineNumber();
415 Q_ASSERT(name->IsString());
417 v8::Local<v8::String> file = name->ToString();
418 if (file->Length() == 0)
419 error.setUrl(QUrl(QLatin1String("<Unknown File>")));
421 error.setUrl(QUrl(QV8Engine::toStringStatic(file)));
423 error.setLine(lineNumber);
426 QString qDescription = QV8Engine::toStringStatic(description);
427 if (qDescription.startsWith(QLatin1String("Uncaught ")))
428 qDescription = qDescription.mid(9 /* strlen("Uncaught ") */);
430 error.setDescription(qDescription);
433 void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine,
434 QDeclarativeError &error)
436 qFatal("Not implemented - we use v8 now");
439 bool QDeclarativeQtScriptExpression::notifyOnValueChange() const
444 void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify)
446 trackChange = notify;
447 if (!notify && guardList)
451 void QDeclarativeQtScriptExpression::resetNotifyOnChange()
456 void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex)
458 if (guardList) clearGuards();
460 if (!object || notifyIndex == -1) {
464 guardObject = object;
465 guardObjectNotifyIndex = notifyIndex;
470 void QDeclarativeQtScriptExpression::setEvaluateFlags(EvaluateFlags flags)
475 QDeclarativeQtScriptExpression::EvaluateFlags QDeclarativeQtScriptExpression::evaluateFlags() const
480 v8::Local<v8::Value> QDeclarativeQtScriptExpression::v8value(QObject *secondaryScope, bool *isUndefined)
482 Q_ASSERT(context() && context()->engine);
483 Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1));
485 if (v8function.IsEmpty() || v8function->IsUndefined()) {
486 if (isUndefined) *isUndefined = true;
487 return v8::Local<v8::Value>();
490 DeleteWatcher watcher(this);
492 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine);
494 bool lastCaptureProperties = ep->captureProperties;
495 QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
496 ep->captureProperties = trackChange;
497 ep->capturedProperties.copyAndClear(lastCapturedProperties);
499 v8::Local<v8::Value> value = eval(secondaryScope, isUndefined);
501 if (!watcher.wasDeleted() && trackChange) {
502 if (ep->capturedProperties.count() == 0) {
504 if (guardList) clearGuards();
508 updateGuards(ep->capturedProperties);
513 lastCapturedProperties.copyAndClear(ep->capturedProperties);
514 ep->captureProperties = lastCaptureProperties;
519 v8::Local<v8::Value> QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined)
521 Q_ASSERT(context() && context()->engine);
522 DeleteWatcher watcher(this);
524 QDeclarativeEngine *engine = context()->engine;
525 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
527 QObject *restoreSecondaryScope = 0;
529 restoreSecondaryScope = ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, secondaryScope);
531 v8::TryCatch try_catch;
532 v8::Context::Scope scope(ep->v8engine.context()); // XXX is this needed?
534 v8::Handle<v8::Object> This;
536 if (evaluateFlags() & RequiresThisObject) {
537 v8::Handle<v8::Value> value = ep->v8engine.newQObject(scopeObject);
538 if (value->IsObject()) This = v8::Handle<v8::Object>::Cast(value);
540 if (This.IsEmpty()) {
541 This = ep->v8engine.global();
544 v8::Local<v8::Value> result = v8function->Call(This, 0, 0);
547 ep->v8engine.contextWrapper()->setSecondaryScope(v8qmlscope, restoreSecondaryScope);
550 *isUndefined = try_catch.HasCaught() || result->IsUndefined();
552 if (watcher.wasDeleted()) {
553 } else if (try_catch.HasCaught()) {
554 v8::Local<v8::Message> message = try_catch.Message();
555 if (!message.IsEmpty()) {
556 QDeclarativeExpressionPrivate::exceptionToError(message, error);
558 error = QDeclarativeError();
561 error = QDeclarativeError();
567 void QDeclarativeQtScriptExpression::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
569 Q_ASSERT(guardObject);
570 Q_ASSERT(guardObjectNotifyIndex != -1);
572 if (properties.count() != guardListLength) {
573 QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()];
575 for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii)
576 guardList[ii].copyAndClear(newGuardList[ii]);
579 guardList = newGuardList;
580 guardListLength = properties.count();
583 bool outputWarningHeader = false;
584 bool noChanges = true;
585 for (int ii = 0; ii < properties.count(); ++ii) {
586 QDeclarativeNotifierEndpoint &guard = guardList[ii];
587 const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
589 guard.target = guardObject;
590 guard.targetMethod = guardObjectNotifyIndex;
592 if (property.notifier != 0) {
594 if (!noChanges && guard.isConnected(property.notifier)) {
600 bool existing = false;
601 for (int jj = 0; !existing && jj < ii; ++jj)
602 if (guardList[jj].isConnected(property.notifier))
609 guard.connect(property.notifier);
614 } else if (property.notifyIndex != -1) {
616 if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
622 bool existing = false;
623 for (int jj = 0; !existing && jj < ii; ++jj)
624 if (guardList[jj].isConnected(property.object, property.notifyIndex))
631 guard.connect(property.object, property.notifyIndex);
636 if (!outputWarningHeader) {
637 outputWarningHeader = true;
638 qWarning() << "QDeclarativeExpression: Expression" << expression
639 << "depends on non-NOTIFYable properties:";
642 const QMetaObject *metaObj = property.object->metaObject();
643 QMetaProperty metaProp = metaObj->property(property.coreIndex);
645 qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
650 // Must be called with a valid handle scope
651 v8::Local<v8::Value> QDeclarativeExpressionPrivate::v8value(QObject *secondaryScope, bool *isUndefined)
653 if (!expressionFunctionValid) {
654 QDeclarativeEngine *engine = context()->engine;
655 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
657 QDeclarativeRewrite::RewriteBinding rewriteBinding;
658 rewriteBinding.setName(name);
660 const QString code = rewriteBinding(expression, &ok);
661 if (ok) v8function = evalFunction(context(), scopeObject, code, url, line, &v8qmlscope);
662 expressionFunctionMode = ExplicitContext;
663 expressionFunctionValid = true;
666 return QDeclarativeQtScriptExpression::v8value(secondaryScope, isUndefined);
669 QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
671 Q_Q(QDeclarativeExpression);
673 if (!context() || !context()->isValid()) {
674 qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
678 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
681 ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
684 v8::HandleScope handle_scope;
685 v8::Local<v8::Value> result = v8value(secondaryScope, isUndefined);
686 rv = ep->v8engine.toVariant(result, qMetaTypeId<QList<QObject*> >());
689 ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
695 Evaulates the expression, returning the result of the evaluation,
696 or an invalid QVariant if the expression is invalid or has an error.
698 \a valueIsUndefined is set to true if the expression resulted in an
701 \sa hasError(), error()
703 QVariant QDeclarativeExpression::evaluate(bool *valueIsUndefined)
705 Q_D(QDeclarativeExpression);
706 return d->value(0, valueIsUndefined);
710 Returns true if the valueChanged() signal is emitted when the expression's evaluated
713 bool QDeclarativeExpression::notifyOnValueChanged() const
715 Q_D(const QDeclarativeExpression);
716 return d->notifyOnValueChange();
720 Sets whether the valueChanged() signal is emitted when the
721 expression's evaluated value changes.
723 If \a notifyOnChange is true, the QDeclarativeExpression will
724 monitor properties involved in the expression's evaluation, and emit
725 QDeclarativeExpression::valueChanged() if they have changed. This
726 allows an application to ensure that any value associated with the
727 result of the expression remains up to date.
729 If \a notifyOnChange is false (default), the QDeclarativeExpression
730 will not montitor properties involved in the expression's
731 evaluation, and QDeclarativeExpression::valueChanged() will never be
732 emitted. This is more efficient if an application wants a "one off"
733 evaluation of the expression.
735 void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange)
737 Q_D(QDeclarativeExpression);
738 d->setNotifyOnValueChange(notifyOnChange);
742 Returns the source file URL for this expression. The source location must
743 have been previously set by calling setSourceLocation().
745 QString QDeclarativeExpression::sourceFile() const
747 Q_D(const QDeclarativeExpression);
752 Returns the source file line number for this expression. The source location
753 must have been previously set by calling setSourceLocation().
755 int QDeclarativeExpression::lineNumber() const
757 Q_D(const QDeclarativeExpression);
762 Set the location of this expression to \a line of \a url. This information
763 is used by the script engine.
765 void QDeclarativeExpression::setSourceLocation(const QString &url, int line)
767 Q_D(QDeclarativeExpression);
773 Returns the expression's scope object, if provided, otherwise 0.
775 In addition to data provided by the expression's QDeclarativeContext, the scope
776 object's properties are also in scope during the expression's evaluation.
778 QObject *QDeclarativeExpression::scopeObject() const
780 Q_D(const QDeclarativeExpression);
781 return d->scopeObject;
785 Returns true if the last call to evaluate() resulted in an error,
788 \sa error(), clearError()
790 bool QDeclarativeExpression::hasError() const
792 Q_D(const QDeclarativeExpression);
793 return d->error.isValid();
797 Clear any expression errors. Calls to hasError() following this will
800 \sa hasError(), error()
802 void QDeclarativeExpression::clearError()
804 Q_D(QDeclarativeExpression);
805 d->error = QDeclarativeError();
809 Return any error from the last call to evaluate(). If there was no error,
810 this returns an invalid QDeclarativeError instance.
812 \sa hasError(), clearError()
815 QDeclarativeError QDeclarativeExpression::error() const
817 Q_D(const QDeclarativeExpression);
822 void QDeclarativeExpressionPrivate::_q_notify()
827 void QDeclarativeQtScriptExpression::clearGuards()
835 \fn void QDeclarativeExpression::valueChanged()
837 Emitted each time the expression value changes from the last time it was
838 evaluated. The expression must have been evaluated at least once (by
839 calling QDeclarativeExpression::evaluate()) before this signal will be emitted.
842 void QDeclarativeExpressionPrivate::emitValueChanged()
844 Q_Q(QDeclarativeExpression);
845 emit q->valueChanged();
848 QDeclarativeAbstractExpression::QDeclarativeAbstractExpression()
849 : m_context(0), m_prevExpression(0), m_nextExpression(0)
853 QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression()
855 if (m_prevExpression) {
856 *m_prevExpression = m_nextExpression;
857 if (m_nextExpression)
858 m_nextExpression->m_prevExpression = m_prevExpression;
862 QDeclarativeContextData *QDeclarativeAbstractExpression::context() const
867 void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context)
869 if (m_prevExpression) {
870 *m_prevExpression = m_nextExpression;
871 if (m_nextExpression)
872 m_nextExpression->m_prevExpression = m_prevExpression;
873 m_prevExpression = 0;
874 m_nextExpression = 0;
880 m_nextExpression = m_context->expressions;
881 if (m_nextExpression)
882 m_nextExpression->m_prevExpression = &m_nextExpression;
883 m_prevExpression = &context->expressions;
884 m_context->expressions = this;
888 void QDeclarativeAbstractExpression::refresh()
892 bool QDeclarativeAbstractExpression::isValid() const
894 return m_context != 0;
899 #include <moc_qdeclarativeexpression.cpp>