Optimize default property resolution in compiler
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarative.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QDECLARATIVE_H
43 #define QDECLARATIVE_H
44
45 #include <QtDeclarative/qdeclarativeprivate.h>
46 #include <QtDeclarative/qdeclarativeparserstatus.h>
47 #include <QtDeclarative/qdeclarativepropertyvaluesource.h>
48 #include <QtDeclarative/qdeclarativepropertyvalueinterceptor.h>
49 #include <QtDeclarative/qdeclarativelist.h>
50
51 #include <QtCore/qbytearray.h>
52 #include <QtCore/qmetaobject.h>
53
54 QT_BEGIN_HEADER
55
56 #define QML_VERSION     0x020000
57 #define QML_VERSION_STR "2.0"
58
59 #define QML_DECLARE_TYPE(TYPE) \
60     Q_DECLARE_METATYPE(TYPE *) \
61     Q_DECLARE_METATYPE(QDeclarativeListProperty<TYPE>) 
62
63 #define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \
64     Q_DECLARE_METATYPE(QDeclarativeListProperty<TYPE>) 
65
66 #define QML_DECLARE_INTERFACE(INTERFACE) \
67     QML_DECLARE_TYPE(INTERFACE)
68
69 #define QML_DECLARE_INTERFACE_HASMETATYPE(INTERFACE) \
70     QML_DECLARE_TYPE_HASMETATYPE(INTERFACE)
71
72 enum { /* TYPEINFO flags */
73     QML_HAS_ATTACHED_PROPERTIES = 0x01
74 };
75
76 #define QML_DECLARE_TYPEINFO(TYPE, FLAGS) \
77 QT_BEGIN_NAMESPACE \
78 template <> \
79 class QDeclarativeTypeInfo<TYPE > \
80 { \
81 public: \
82     enum { \
83         hasAttachedProperties = (((FLAGS) & QML_HAS_ATTACHED_PROPERTIES) == QML_HAS_ATTACHED_PROPERTIES) \
84     }; \
85 }; \
86 QT_END_NAMESPACE
87
88 QT_BEGIN_NAMESPACE
89
90 QT_MODULE(Declarative)
91
92 template<typename T>
93 int qmlRegisterType()
94 {
95     QByteArray name(T::staticMetaObject.className());
96
97     QByteArray pointerName(name + '*');
98     QByteArray listName("QDeclarativeListProperty<" + name + ">");
99
100     QDeclarativePrivate::RegisterType type = {
101         0, 
102
103         qRegisterMetaType<T *>(pointerName.constData()),
104         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
105         0, 0,
106         QString(),
107
108         0, 0, 0, 0, &T::staticMetaObject,
109
110         QDeclarativePrivate::attachedPropertiesFunc<T>(),
111         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
112
113         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(), 
114         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
115         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
116
117         0, 0,
118
119         0,
120         0
121     };
122
123     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
124 }
125
126 int Q_DECLARATIVE_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message);
127
128 template<typename T>
129 int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason)
130 {
131     QByteArray name(T::staticMetaObject.className());
132
133     QByteArray pointerName(name + '*');
134     QByteArray listName("QDeclarativeListProperty<" + name + ">");
135
136     QDeclarativePrivate::RegisterType type = {
137         0,
138
139         qRegisterMetaType<T *>(pointerName.constData()),
140         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
141         0, 0,
142         reason,
143
144         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
145
146         QDeclarativePrivate::attachedPropertiesFunc<T>(),
147         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
148
149         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
150         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
151         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
152
153         0, 0,
154
155         0,
156         0
157     };
158
159     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
160 }
161
162 template<typename T>
163 int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
164 {
165     QByteArray name(T::staticMetaObject.className());
166
167     QByteArray pointerName(name + '*');
168     QByteArray listName("QDeclarativeListProperty<" + name + ">");
169
170     QDeclarativePrivate::RegisterType type = {
171         0, 
172
173         qRegisterMetaType<T *>(pointerName.constData()),
174         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
175         sizeof(T), QDeclarativePrivate::createInto<T>,
176         QString(),
177
178         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
179
180         QDeclarativePrivate::attachedPropertiesFunc<T>(),
181         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
182
183         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(), 
184         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
185         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
186
187         0, 0,
188
189         0,
190         0
191     };
192
193     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
194 }
195
196 template<typename T, int metaObjectRevision>
197 int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
198 {
199     QByteArray name(T::staticMetaObject.className());
200
201     QByteArray pointerName(name + '*');
202     QByteArray listName("QDeclarativeListProperty<" + name + ">");
203
204     QDeclarativePrivate::RegisterType type = {
205         1,
206
207         qRegisterMetaType<T *>(pointerName.constData()),
208         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
209         sizeof(T), QDeclarativePrivate::createInto<T>,
210         QString(),
211
212         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
213
214         QDeclarativePrivate::attachedPropertiesFunc<T>(),
215         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
216
217         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
218         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
219         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
220
221         0, 0,
222
223         0,
224         metaObjectRevision
225     };
226
227     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
228 }
229
230 template<typename T, int metaObjectRevision>
231 int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
232 {
233     QByteArray name(T::staticMetaObject.className());
234
235     QByteArray pointerName(name + '*');
236     QByteArray listName("QDeclarativeListProperty<" + name + ">");
237
238     QDeclarativePrivate::RegisterType type = {
239         1,
240
241         qRegisterMetaType<T *>(pointerName.constData()),
242         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
243         sizeof(T), QDeclarativePrivate::createInto<T>,
244         QString(),
245
246         uri, versionMajor, versionMinor, 0, &T::staticMetaObject,
247
248         QDeclarativePrivate::attachedPropertiesFunc<T>(),
249         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
250
251         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
252         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
253         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
254
255         0, 0,
256
257         0,
258         metaObjectRevision
259     };
260
261     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
262 }
263
264
265 template<typename T, typename E>
266 int qmlRegisterExtendedType()
267 {
268     QByteArray name(T::staticMetaObject.className());
269
270     QByteArray pointerName(name + '*');
271     QByteArray listName("QDeclarativeListProperty<" + name + ">");
272
273     QDeclarativePrivate::RegisterType type = {
274         0, 
275
276         qRegisterMetaType<T *>(pointerName.constData()),
277         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
278         0, 0,
279         QString(),
280
281         0, 0, 0, 0, &T::staticMetaObject,
282
283         QDeclarativePrivate::attachedPropertiesFunc<T>(),
284         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
285
286         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(), 
287         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
288         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
289
290         QDeclarativePrivate::createParent<E>, &E::staticMetaObject,
291
292         0,
293         0
294     };
295
296     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
297 }
298
299 template<typename T, typename E>
300 int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, 
301                             const char *qmlName)
302 {
303     QByteArray name(T::staticMetaObject.className());
304
305     QByteArray pointerName(name + '*');
306     QByteArray listName("QDeclarativeListProperty<" + name + ">");
307
308     QDeclarativeAttachedPropertiesFunc attached = QDeclarativePrivate::attachedPropertiesFunc<E>();
309     const QMetaObject * attachedMetaObject = QDeclarativePrivate::attachedPropertiesMetaObject<E>(); 
310     if (!attached) {
311         attached = QDeclarativePrivate::attachedPropertiesFunc<T>();
312         attachedMetaObject = QDeclarativePrivate::attachedPropertiesMetaObject<T>();
313     }
314
315     QDeclarativePrivate::RegisterType type = {
316         0, 
317
318         qRegisterMetaType<T *>(pointerName.constData()),
319         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
320         sizeof(T), QDeclarativePrivate::createInto<T>,
321         QString(),
322
323         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
324
325         attached,
326         attachedMetaObject,
327
328         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(), 
329         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
330         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
331
332         QDeclarativePrivate::createParent<E>, &E::staticMetaObject,
333
334         0,
335         0
336     };
337
338     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
339 }
340
341 template<typename T>
342 int qmlRegisterInterface(const char *typeName)
343 {
344     QByteArray name(typeName);
345
346     QByteArray pointerName(name + '*');
347     QByteArray listName("QDeclarativeListProperty<" + name + ">");
348
349     QDeclarativePrivate::RegisterInterface qmlInterface = {
350         0,
351
352         qRegisterMetaType<T *>(pointerName.constData()),
353         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
354
355         qobject_interface_iid<T *>()
356     };
357
358     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::InterfaceRegistration, &qmlInterface);
359 }
360
361 template<typename T>
362 int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, 
363                           const char *qmlName, QDeclarativeCustomParser *parser)
364 {
365     QByteArray name(T::staticMetaObject.className());
366
367     QByteArray pointerName(name + '*');
368     QByteArray listName("QDeclarativeListProperty<" + name + ">");
369
370     QDeclarativePrivate::RegisterType type = {
371         0, 
372
373         qRegisterMetaType<T *>(pointerName.constData()),
374         qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
375         sizeof(T), QDeclarativePrivate::createInto<T>,
376         QString(),
377
378         uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
379
380         QDeclarativePrivate::attachedPropertiesFunc<T>(),
381         QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
382
383         QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(), 
384         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
385         QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
386
387         0, 0,
388
389         parser,
390         0
391     };
392
393     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
394 }
395
396 class QDeclarativeContext;
397 class QDeclarativeEngine;
398 class QJSValue;
399 class QJSEngine;
400 Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
401 Q_DECLARATIVE_EXPORT QDeclarativeContext *qmlContext(const QObject *);
402 Q_DECLARATIVE_EXPORT QDeclarativeEngine *qmlEngine(const QObject *);
403 Q_DECLARATIVE_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *, bool create = true);
404 Q_DECLARATIVE_EXPORT QObject *qmlAttachedPropertiesObject(int *, const QObject *, const QMetaObject *, bool create);
405
406 template<typename T>
407 QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
408 {
409     static int idx = -1;
410     return qmlAttachedPropertiesObject(&idx, obj, &T::staticMetaObject, create);
411 }
412
413 // For the use of QtQuick1 module
414 Q_DECLARATIVE_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor);
415
416 /*!
417    This function may be used to register a module API provider \a callback in a particular \a uri
418    with a version specified in \a versionMajor and \a versionMinor.
419
420    Installing a module API into a uri allows developers to provide arbitrary functionality
421    (methods and properties) in a namespace that doesn't necessarily contain elements.
422
423    A module API may be either a QObject or a QJSValue.  Only one module API provider
424    may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
425    This function should be used to register a module API provider function which returns a QJSValue as a module API.
426
427    \e NOTE: QJSValue module API properties will \e not trigger binding re-evaluation if changed.
428
429    Usage:
430    \code
431    // first, define the module API provider function (callback).
432    static QJSValue *example_qjsvalue_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
433    {
434        Q_UNUSED(engine)
435
436        static int seedValue = 5;
437        QJSValue example = scriptEngine->newObject();
438        example.setProperty("someProperty", seedValue++);
439        return example;
440    }
441
442    // second, register the module API provider with QML by calling this function in an initialization function.
443    ...
444    qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider);
445    ...
446    \endcode
447
448    In order to use the registered module API in QML, you must import the module API.
449    \qml
450    import QtQuick 2.0
451    import Qt.example.qjsvalueApi 1.0 as ExampleApi
452    Item {
453        id: root
454        property int someValue: ExampleApi.someProperty
455    }
456    \endqml
457   */
458 inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
459                                 QJSValue (*callback)(QDeclarativeEngine *, QJSEngine *))
460 {
461     QDeclarativePrivate::RegisterModuleApi api = {
462         0,
463
464         uri, versionMajor, versionMinor,
465
466         callback, 0
467     };
468
469     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ModuleApiRegistration, &api);
470 }
471
472 /*!
473    This function may be used to register a module API provider \a callback in a particular \a uri
474    with a version specified in \a versionMajor and \a versionMinor.
475
476    Installing a module API into a uri allows developers to provide arbitrary functionality
477    (methods and properties) in a namespace that doesn't necessarily contain elements.
478
479    A module API may be either a QObject or a QJSValue.  Only one module API provider
480    may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
481    This function should be used to register a module API provider function which returns a QObject as a module API.
482
483    Usage:
484    \code
485    // first, define your QObject which provides the functionality.
486    class ModuleApiExample : public QObject
487    {
488        Q_OBJECT
489        Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
490
491    public:
492        ModuleApiExample(QObject* parent = 0)
493            : QObject(parent), m_someProperty(0)
494        {
495        }
496
497        ~ModuleApiExample() {}
498
499        Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; }
500
501        int someProperty() const { return m_someProperty; }
502        void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); }
503
504    signals:
505        void somePropertyChanged(int newValue);
506
507    private:
508        int m_someProperty;
509    };
510
511    // second, define the module API provider function (callback).
512    static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
513    {
514        Q_UNUSED(engine)
515        Q_UNUSED(scriptEngine)
516
517        ModuleApiExample *example = new ModuleApiExample();
518        return example;
519    }
520
521    // third, register the module API provider with QML by calling this function in an initialization function.
522    ...
523    qmlRegisterModuleApi("Qt.example.qobjectApi", 1, 0, example_qobject_module_api_provider);
524    ...
525    \endcode
526
527    In order to use the registered module API in QML, you must import the module API.
528    \qml
529    import QtQuick 2.0
530    import Qt.example.qobjectApi 1.0 as ExampleApi
531    Item {
532        id: root
533        property int someValue: ExampleApi.someProperty
534
535        Component.onCompleted: {
536            someValue = ExampleApi.doSomething()
537        }
538    }
539    \endqml
540   */
541 inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
542                                 QObject *(*callback)(QDeclarativeEngine *, QJSEngine *))
543 {
544     QDeclarativePrivate::RegisterModuleApi api = {
545         0,
546
547         uri, versionMajor, versionMinor,
548
549         0, callback
550     };
551
552     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ModuleApiRegistration, &api);
553 }
554
555 // Enable debugging before any QDeclarativeEngine is created
556 struct Q_DECLARATIVE_EXPORT QDeclarativeDebuggingEnabler
557 {
558     QDeclarativeDebuggingEnabler();
559 };
560
561 // Execute code in constructor before first QDeclarativeEngine is instantiated
562 #if defined(QT_DECLARATIVE_DEBUG)
563 static QDeclarativeDebuggingEnabler qmlEnableDebuggingHelper;
564 #endif
565
566 QT_END_NAMESPACE
567
568 QML_DECLARE_TYPE(QObject)
569 Q_DECLARE_METATYPE(QVariant)
570
571 QT_END_HEADER
572
573 #endif // QDECLARATIVE_H