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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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"
49 #include "private/qdeclarativeglobalscriptclass_p.h"
51 #include <QtCore/qdebug.h>
52 #include <QtScript/qscriptprogram.h>
54 #include <private/qscriptdeclarativeclass_p.h>
58 bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e)
62 if (e->inProgressCreations == 0) return false; // Not in construction
64 if (prevError) return true; // Already in error chain
66 prevError = &e->erroredBindings;
67 nextError = e->erroredBindings;
68 e->erroredBindings = this;
69 if (nextError) nextError->prevError = &nextError;
74 QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression()
75 : dataRef(0), expressionFunctionMode(ExplicitContext), scopeObject(0), trackChange(false),
76 guardList(0), guardListLength(0), guardObject(0), guardObjectNotifyIndex(-1), deleted(0)
80 QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression()
82 if (guardList) { delete [] guardList; guardList = 0; }
83 if (dataRef) dataRef->release();
84 if (deleted) *deleted = true;
87 QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate()
88 : expressionFunctionValid(true), line(-1)
92 QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate()
96 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr,
101 QDeclarativeAbstractExpression::setContext(ctxt);
103 expressionFunctionValid = false;
106 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QScriptValue &func,
109 expression = func.toString();
111 QDeclarativeAbstractExpression::setContext(ctxt);
114 expressionFunction = func;
115 expressionFunctionMode = ExplicitContext;
116 expressionFunctionValid = true;
119 void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr,
120 QDeclarativeRefCount *rc,
121 QObject *me, const QString &srcUrl, int lineNumber)
126 if (dataRef) dataRef->release();
128 if (dataRef) dataRef->addref();
130 quint32 *exprData = (quint32 *)expr;
131 QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc;
133 expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
135 int progIdx = *(exprData);
136 bool isSharedProgram = progIdx & 0x80000000;
137 progIdx &= 0x7FFFFFFF;
139 QDeclarativeEngine *engine = ctxt->engine;
140 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
141 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
143 if (isSharedProgram) {
145 if (!dd->cachedClosures.at(progIdx)) {
146 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
147 scriptContext->pushScope(ep->contextClass->newSharedContext());
148 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
149 dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(expression, url, line));
150 scriptEngine->popContext();
153 expressionFunction = *dd->cachedClosures.at(progIdx);
154 expressionFunctionMode = SharedContext;
155 expressionFunctionValid = true;
159 if (!dd->cachedPrograms.at(progIdx)) {
160 dd->cachedPrograms[progIdx] = new QScriptProgram(expression, url, line);
163 expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx),
166 expressionFunctionMode = ExplicitContext;
167 expressionFunctionValid = true;
170 QDeclarativeAbstractExpression::setContext(ctxt);
174 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
175 const QString &program, const QString &fileName,
176 int lineNumber, QScriptValue *contextObject)
178 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
179 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
181 *contextObject = ep->contextClass->newContext(context, object);
182 scriptContext->pushScope(*contextObject);
184 scriptContext->pushScope(ep->contextClass->newContext(context, object));
186 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
187 QScriptValue rv = ep->scriptEngine.evaluate(program, fileName, lineNumber);
188 ep->scriptEngine.popContext();
192 QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
193 const QScriptProgram &program,
194 QScriptValue *contextObject)
196 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
197 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
199 *contextObject = ep->contextClass->newContext(context, object);
200 scriptContext->pushScope(*contextObject);
202 scriptContext->pushScope(ep->contextClass->newContext(context, object));
204 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
205 QScriptValue rv = ep->scriptEngine.evaluate(program);
206 ep->scriptEngine.popContext();
211 \class QDeclarativeExpression
213 \brief The QDeclarativeExpression class evaluates JavaScript in a QML context.
215 For example, given a file \c main.qml like this:
221 width: 200; height: 200
225 The following code evaluates a JavaScript expression in the context of the
229 QDeclarativeEngine *engine = new QDeclarativeEngine;
230 QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));
232 QObject *myObject = component.create();
233 QDeclarativeExpression *expr = new QDeclarativeExpression(engine->rootContext(), myObject, "width * 2");
234 int result = expr->evaluate().toInt(); // result = 400
238 static int QDeclarativeExpression_notifyIdx = -1;
241 Create an invalid QDeclarativeExpression.
243 As the expression will not have an associated QDeclarativeContext, this will be a
244 null expression object and its value will always be an invalid QVariant.
246 QDeclarativeExpression::QDeclarativeExpression()
247 : QObject(*new QDeclarativeExpressionPrivate, 0)
249 Q_D(QDeclarativeExpression);
251 if (QDeclarativeExpression_notifyIdx == -1)
252 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
253 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
257 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr,
258 QDeclarativeRefCount *rc, QObject *me,
259 const QString &url, int lineNumber,
260 QDeclarativeExpressionPrivate &dd)
263 Q_D(QDeclarativeExpression);
264 d->init(ctxt, expr, rc, me, url, lineNumber);
266 if (QDeclarativeExpression_notifyIdx == -1)
267 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
268 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
272 Create a QDeclarativeExpression object that is a child of \a parent.
274 The \a expression JavaScript will be executed in the \a ctxt QDeclarativeContext.
275 If specified, the \a scope object's properties will also be in scope during
276 the expression's execution.
278 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt,
280 const QString &expression,
282 : QObject(*new QDeclarativeExpressionPrivate, parent)
284 Q_D(QDeclarativeExpression);
285 d->init(QDeclarativeContextData::get(ctxt), expression, scope);
287 if (QDeclarativeExpression_notifyIdx == -1)
288 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
289 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
295 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
296 const QString &expression)
297 : QObject(*new QDeclarativeExpressionPrivate, 0)
299 Q_D(QDeclarativeExpression);
300 d->init(ctxt, expression, scope);
302 if (QDeclarativeExpression_notifyIdx == -1)
303 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
304 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
308 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope,
309 const QString &expression, QDeclarativeExpressionPrivate &dd)
312 Q_D(QDeclarativeExpression);
313 d->init(ctxt, expression, scope);
315 if (QDeclarativeExpression_notifyIdx == -1)
316 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
317 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
321 QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QObject *scope, const QScriptValue &func,
322 QDeclarativeExpressionPrivate &dd)
325 Q_D(QDeclarativeExpression);
326 d->init(ctxt, func, scope);
328 if (QDeclarativeExpression_notifyIdx == -1)
329 QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
330 d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
334 Destroy the QDeclarativeExpression instance.
336 QDeclarativeExpression::~QDeclarativeExpression()
341 Returns the QDeclarativeEngine this expression is associated with, or 0 if there
342 is no association or the QDeclarativeEngine has been destroyed.
344 QDeclarativeEngine *QDeclarativeExpression::engine() const
346 Q_D(const QDeclarativeExpression);
347 return d->context()?d->context()->engine:0;
351 Returns the QDeclarativeContext this expression is associated with, or 0 if there
352 is no association or the QDeclarativeContext has been destroyed.
354 QDeclarativeContext *QDeclarativeExpression::context() const
356 Q_D(const QDeclarativeExpression);
357 QDeclarativeContextData *data = d->context();
358 return data?data->asQDeclarativeContext():0;
362 Returns the expression string.
364 QString QDeclarativeExpression::expression() const
366 Q_D(const QDeclarativeExpression);
367 return d->expression;
371 Set the expression to \a expression.
373 void QDeclarativeExpression::setExpression(const QString &expression)
375 Q_D(QDeclarativeExpression);
377 d->resetNotifyOnChange();
378 d->expression = expression;
379 d->expressionFunctionValid = false;
380 d->expressionFunction = QScriptValue();
383 void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine,
384 QDeclarativeError &error)
386 if (scriptEngine->hasUncaughtException() &&
387 scriptEngine->uncaughtException().isError()) {
390 int lineNumber = scriptEngine->uncaughtExceptionLineNumber();
392 QScriptValue exception = scriptEngine->uncaughtException();
393 QLatin1String fileNameProp("fileName");
395 if (!exception.property(fileNameProp).toString().isEmpty()){
396 fileName = exception.property(fileNameProp).toString();
398 fileName = QLatin1String("<Unknown File>");
401 error.setUrl(QUrl(fileName));
402 error.setLine(lineNumber);
404 error.setDescription(exception.toString());
406 error = QDeclarativeError();
410 bool QDeclarativeQtScriptExpression::notifyOnValueChange() const
415 void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify)
417 trackChange = notify;
418 if (!notify && guardList)
422 void QDeclarativeQtScriptExpression::resetNotifyOnChange()
427 void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex)
429 if (guardList) clearGuards();
431 if (!object || notifyIndex == -1) {
435 guardObject = object;
436 guardObjectNotifyIndex = notifyIndex;
441 void QDeclarativeQtScriptExpression::setEvaluateFlags(EvaluateFlags flags)
446 QDeclarativeQtScriptExpression::EvaluateFlags QDeclarativeQtScriptExpression::evaluateFlags() const
451 QScriptValue QDeclarativeQtScriptExpression::scriptValue(QObject *secondaryScope, bool *isUndefined)
453 Q_ASSERT(context() && context()->engine);
454 Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1));
456 if (!expressionFunction.isValid()) {
457 if (isUndefined) *isUndefined = true;
458 return QScriptValue();
461 DeleteWatcher watcher(this);
463 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine);
465 bool lastCaptureProperties = ep->captureProperties;
466 QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
467 ep->captureProperties = trackChange;
468 ep->capturedProperties.copyAndClear(lastCapturedProperties);
470 QScriptValue value = eval(secondaryScope, isUndefined);
472 if (!watcher.wasDeleted() && trackChange) {
473 if (ep->capturedProperties.count() == 0) {
475 if (guardList) clearGuards();
479 updateGuards(ep->capturedProperties);
484 lastCapturedProperties.copyAndClear(ep->capturedProperties);
485 ep->captureProperties = lastCaptureProperties;
490 QScriptValue QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined)
492 Q_ASSERT(context() && context()->engine);
494 DeleteWatcher watcher(this);
496 QDeclarativeEngine *engine = context()->engine;
497 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
499 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
501 QDeclarativeContextData *oldSharedContext = 0;
502 QObject *oldSharedScope = 0;
503 QObject *oldOverride = 0;
504 bool isShared = (expressionFunctionMode == SharedContext);
507 oldSharedContext = ep->sharedContext;
508 oldSharedScope = ep->sharedScope;
509 ep->sharedContext = context();
510 ep->sharedScope = scopeObject;
512 oldOverride = ep->contextClass->setOverrideObject(expressionContext, secondaryScope);
515 QScriptValue thisObject;
516 if (evalFlags & RequiresThisObject)
517 thisObject = ep->objectClass->newQObject(scopeObject);
518 QScriptValue svalue = expressionFunction.call(thisObject); // This could cause this c++ object to be deleted
521 ep->sharedContext = oldSharedContext;
522 ep->sharedScope = oldSharedScope;
523 } else if (!watcher.wasDeleted()) {
524 ep->contextClass->setOverrideObject(expressionContext, oldOverride);
528 *isUndefined = svalue.isUndefined() || scriptEngine->hasUncaughtException();
531 if (scriptEngine->hasUncaughtException()) {
532 if (!watcher.wasDeleted())
533 QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
535 scriptEngine->clearExceptions();
536 return QScriptValue();
538 if (!watcher.wasDeleted())
539 error = QDeclarativeError();
545 void QDeclarativeQtScriptExpression::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
547 Q_ASSERT(guardObject);
548 Q_ASSERT(guardObjectNotifyIndex != -1);
550 if (properties.count() != guardListLength) {
551 QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()];
553 for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii)
554 guardList[ii].copyAndClear(newGuardList[ii]);
557 guardList = newGuardList;
558 guardListLength = properties.count();
561 bool outputWarningHeader = false;
562 bool noChanges = true;
563 for (int ii = 0; ii < properties.count(); ++ii) {
564 QDeclarativeNotifierEndpoint &guard = guardList[ii];
565 const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
567 guard.target = guardObject;
568 guard.targetMethod = guardObjectNotifyIndex;
570 if (property.notifier != 0) {
572 if (!noChanges && guard.isConnected(property.notifier)) {
578 bool existing = false;
579 for (int jj = 0; !existing && jj < ii; ++jj)
580 if (guardList[jj].isConnected(property.notifier))
587 guard.connect(property.notifier);
592 } else if (property.notifyIndex != -1) {
594 if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
600 bool existing = false;
601 for (int jj = 0; !existing && jj < ii; ++jj)
602 if (guardList[jj].isConnected(property.object, property.notifyIndex))
609 guard.connect(property.object, property.notifyIndex);
614 if (!outputWarningHeader) {
615 outputWarningHeader = true;
616 qWarning() << "QDeclarativeExpression: Expression" << expression
617 << "depends on non-NOTIFYable properties:";
620 const QMetaObject *metaObj = property.object->metaObject();
621 QMetaProperty metaProp = metaObj->property(property.coreIndex);
623 qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
628 QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined)
630 if (!expressionFunctionValid) {
631 QDeclarativeEngine *engine = context()->engine;
632 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
633 QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
635 QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
636 expressionContext = ep->contextClass->newContext(context(), scopeObject);
637 scriptContext->pushScope(expressionContext);
638 scriptContext->pushScope(ep->globalClass->staticGlobalObject());
640 QDeclarativeRewrite::RewriteBinding rewriteBinding;
641 rewriteBinding.setName(name);
643 const QString code = rewriteBinding(expression, &ok);
645 expressionFunction = scriptEngine->evaluate(code, url, line);
647 scriptEngine->popContext();
648 expressionFunctionMode = ExplicitContext;
649 expressionFunctionValid = true;
652 return QDeclarativeQtScriptExpression::scriptValue(secondaryScope, isUndefined);
655 QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
657 Q_Q(QDeclarativeExpression);
659 if (!context() || !context()->isValid()) {
660 qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
664 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
665 ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
666 QVariant retn(ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined), qMetaTypeId<QList<QObject*> >()));
667 ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
672 Evaulates the expression, returning the result of the evaluation,
673 or an invalid QVariant if the expression is invalid or has an error.
675 \a valueIsUndefined is set to true if the expression resulted in an
678 \sa hasError(), error()
680 QVariant QDeclarativeExpression::evaluate(bool *valueIsUndefined)
682 Q_D(QDeclarativeExpression);
683 return d->value(0, valueIsUndefined);
687 Returns true if the valueChanged() signal is emitted when the expression's evaluated
690 bool QDeclarativeExpression::notifyOnValueChanged() const
692 Q_D(const QDeclarativeExpression);
693 return d->notifyOnValueChange();
697 Sets whether the valueChanged() signal is emitted when the
698 expression's evaluated value changes.
700 If \a notifyOnChange is true, the QDeclarativeExpression will
701 monitor properties involved in the expression's evaluation, and emit
702 QDeclarativeExpression::valueChanged() if they have changed. This
703 allows an application to ensure that any value associated with the
704 result of the expression remains up to date.
706 If \a notifyOnChange is false (default), the QDeclarativeExpression
707 will not montitor properties involved in the expression's
708 evaluation, and QDeclarativeExpression::valueChanged() will never be
709 emitted. This is more efficient if an application wants a "one off"
710 evaluation of the expression.
712 void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange)
714 Q_D(QDeclarativeExpression);
715 d->setNotifyOnValueChange(notifyOnChange);
719 Returns the source file URL for this expression. The source location must
720 have been previously set by calling setSourceLocation().
722 QString QDeclarativeExpression::sourceFile() const
724 Q_D(const QDeclarativeExpression);
729 Returns the source file line number for this expression. The source location
730 must have been previously set by calling setSourceLocation().
732 int QDeclarativeExpression::lineNumber() const
734 Q_D(const QDeclarativeExpression);
739 Set the location of this expression to \a line of \a url. This information
740 is used by the script engine.
742 void QDeclarativeExpression::setSourceLocation(const QString &url, int line)
744 Q_D(QDeclarativeExpression);
750 Returns the expression's scope object, if provided, otherwise 0.
752 In addition to data provided by the expression's QDeclarativeContext, the scope
753 object's properties are also in scope during the expression's evaluation.
755 QObject *QDeclarativeExpression::scopeObject() const
757 Q_D(const QDeclarativeExpression);
758 return d->scopeObject;
762 Returns true if the last call to evaluate() resulted in an error,
765 \sa error(), clearError()
767 bool QDeclarativeExpression::hasError() const
769 Q_D(const QDeclarativeExpression);
770 return d->error.isValid();
774 Clear any expression errors. Calls to hasError() following this will
777 \sa hasError(), error()
779 void QDeclarativeExpression::clearError()
781 Q_D(QDeclarativeExpression);
782 d->error = QDeclarativeError();
786 Return any error from the last call to evaluate(). If there was no error,
787 this returns an invalid QDeclarativeError instance.
789 \sa hasError(), clearError()
792 QDeclarativeError QDeclarativeExpression::error() const
794 Q_D(const QDeclarativeExpression);
799 void QDeclarativeExpressionPrivate::_q_notify()
804 void QDeclarativeQtScriptExpression::clearGuards()
812 \fn void QDeclarativeExpression::valueChanged()
814 Emitted each time the expression value changes from the last time it was
815 evaluated. The expression must have been evaluated at least once (by
816 calling QDeclarativeExpression::evaluate()) before this signal will be emitted.
819 void QDeclarativeExpressionPrivate::emitValueChanged()
821 Q_Q(QDeclarativeExpression);
822 emit q->valueChanged();
825 QDeclarativeAbstractExpression::QDeclarativeAbstractExpression()
826 : m_context(0), m_prevExpression(0), m_nextExpression(0)
830 QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression()
832 if (m_prevExpression) {
833 *m_prevExpression = m_nextExpression;
834 if (m_nextExpression)
835 m_nextExpression->m_prevExpression = m_prevExpression;
839 QDeclarativeContextData *QDeclarativeAbstractExpression::context() const
844 void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context)
846 if (m_prevExpression) {
847 *m_prevExpression = m_nextExpression;
848 if (m_nextExpression)
849 m_nextExpression->m_prevExpression = m_prevExpression;
850 m_prevExpression = 0;
851 m_nextExpression = 0;
857 m_nextExpression = m_context->expressions;
858 if (m_nextExpression)
859 m_nextExpression->m_prevExpression = &m_nextExpression;
860 m_prevExpression = &context->expressions;
861 m_context->expressions = this;
865 void QDeclarativeAbstractExpression::refresh()
869 bool QDeclarativeAbstractExpression::isValid() const
871 return m_context != 0;
876 #include <moc_qdeclarativeexpression.cpp>