Specify better increment for captured properties
[qt:qtquick1.git] / src / declarative / qml / qdeclarativeexpression_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVEEXPRESSION_P_H
43 #define QDECLARATIVEEXPRESSION_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "qdeclarativeexpression.h"
57
58 #include "private/qdeclarativeengine_p.h"
59 #include "private/qdeclarativeguard_p.h"
60
61 #include <QtScript/qscriptvalue.h>
62
63 QT_BEGIN_NAMESPACE
64
65 class QDeclarativeAbstractExpression
66 {
67 public:
68     QDeclarativeAbstractExpression();
69     virtual ~QDeclarativeAbstractExpression();
70
71     bool isValid() const;
72
73     QDeclarativeContextData *context() const;
74     void setContext(QDeclarativeContextData *);
75
76     virtual void refresh();
77
78 private:
79     friend class QDeclarativeContext;
80     friend class QDeclarativeContextData;
81     friend class QDeclarativeContextPrivate;
82     QDeclarativeContextData *m_context;
83     QDeclarativeAbstractExpression **m_prevExpression;
84     QDeclarativeAbstractExpression  *m_nextExpression;
85 };
86
87 class QDeclarativeDelayedError 
88 {
89 public:
90     inline QDeclarativeDelayedError() : nextError(0), prevError(0) {}
91     inline ~QDeclarativeDelayedError() { removeError(); }
92
93     QDeclarativeError error;
94
95     bool addError(QDeclarativeEnginePrivate *);
96
97     inline void removeError() {
98         if (!prevError) return;
99         if (nextError) nextError->prevError = prevError;
100         *prevError = nextError;
101         nextError = 0;
102         prevError = 0;
103     }
104
105 private:
106     QDeclarativeDelayedError  *nextError;
107     QDeclarativeDelayedError **prevError;
108 };
109
110 class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression, 
111                                        public QDeclarativeDelayedError
112 {
113 public:
114     enum Mode { SharedContext, ExplicitContext };
115
116     enum EvaluateFlag { RequiresThisObject = 0x01 };
117     Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
118
119     QDeclarativeQtScriptExpression();
120     virtual ~QDeclarativeQtScriptExpression();
121
122     QDeclarativeRefCount *dataRef;
123
124     QString expression;
125
126     Mode expressionFunctionMode;
127     QScriptValue expressionFunction;
128
129     QScriptValue expressionContext; // Only used in ExplicitContext
130     QObject *scopeObject;           // Only used in SharedContext
131
132     bool notifyOnValueChange() const;
133     void setNotifyOnValueChange(bool);
134     void resetNotifyOnChange();
135     void setNotifyObject(QObject *, int );
136
137     void setEvaluateFlags(EvaluateFlags flags);
138     EvaluateFlags evaluateFlags() const;
139
140     QScriptValue scriptValue(QObject *secondaryScope, bool *isUndefined);
141
142     class DeleteWatcher {
143     public:
144         inline DeleteWatcher(QDeclarativeQtScriptExpression *data);
145         inline ~DeleteWatcher();
146         inline bool wasDeleted() const;
147     private:
148         bool *m_wasDeleted;
149         bool m_wasDeletedStorage;
150         QDeclarativeQtScriptExpression *m_d;
151     };
152
153 private:
154     void clearGuards();
155     QScriptValue eval(QObject *secondaryScope, bool *isUndefined);
156     void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty, 16> &properties);
157
158     bool trackChange;
159
160     QDeclarativeNotifierEndpoint *guardList;
161     int guardListLength;
162
163     QObject *guardObject;
164     int guardObjectNotifyIndex;
165     bool *deleted;
166
167     EvaluateFlags evalFlags;
168 };
169
170 Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeQtScriptExpression::EvaluateFlags)
171
172
173 class QDeclarativeExpression;
174 class QString;
175 class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression
176 {
177     Q_DECLARE_PUBLIC(QDeclarativeExpression)
178 public:
179     QDeclarativeExpressionPrivate();
180     ~QDeclarativeExpressionPrivate();
181
182     void init(QDeclarativeContextData *, const QString &, QObject *);
183     void init(QDeclarativeContextData *, const QScriptValue &, QObject *);
184     void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
185
186     QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
187     QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0);
188
189     static QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr) {
190         return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr));
191     }
192     static QDeclarativeExpression *get(QDeclarativeExpressionPrivate *expr) {
193         return expr->q_func();
194     }
195
196     void _q_notify();
197     virtual void emitValueChanged();
198
199     static void exceptionToError(QScriptEngine *, QDeclarativeError &);
200     static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, const QString &,
201                                           int, QScriptValue *);
202     static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, 
203                                           QScriptValue *);
204
205     bool expressionFunctionValid:1;
206
207     QString url; // This is a QString for a reason.  QUrls are slooooooow...
208     int line;
209     QByteArray name; //function name, hint for the debugger
210 };
211
212 QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data)
213 : m_wasDeletedStorage(false), m_d(data) 
214 {
215     if (!m_d->deleted) 
216         m_d->deleted = &m_wasDeletedStorage; 
217     m_wasDeleted = m_d->deleted;
218 }
219
220 QDeclarativeQtScriptExpression::DeleteWatcher::~DeleteWatcher() 
221 {
222     if (false == *m_wasDeleted && m_wasDeleted == m_d->deleted)
223         m_d->deleted = 0;
224 }
225
226 bool QDeclarativeQtScriptExpression::DeleteWatcher::wasDeleted() const 
227
228     return *m_wasDeleted; 
229 }
230
231 QT_END_NAMESPACE
232
233 #endif // QDECLARATIVEEXPRESSION_P_H