src/declarative/qml/qdeclarativeengine.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 ** 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
       
    14 ** this package.
       
    15 **
       
    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.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "private/qdeclarativeengine_p.h"
       
    43 #include "qdeclarativeengine.h"
       
    44 
       
    45 #include "private/qdeclarativecontext_p.h"
       
    46 #include "private/qdeclarativecompiler_p.h"
       
    47 #include "private/qdeclarativeglobalscriptclass_p.h"
       
    48 #include "qdeclarative.h"
       
    49 #include "qdeclarativecontext.h"
       
    50 #include "qdeclarativeexpression.h"
       
    51 #include "qdeclarativecomponent.h"
       
    52 #include "private/qdeclarativebinding_p_p.h"
       
    53 #include "private/qdeclarativevme_p.h"
       
    54 #include "private/qdeclarativeenginedebug_p.h"
       
    55 #include "private/qdeclarativestringconverters_p.h"
       
    56 #include "private/qdeclarativexmlhttprequest_p.h"
       
    57 #include "private/qdeclarativesqldatabase_p.h"
       
    58 #include "private/qdeclarativetypenamescriptclass_p.h"
       
    59 #include "private/qdeclarativelistscriptclass_p.h"
       
    60 #include "qdeclarativescriptstring.h"
       
    61 #include "private/qdeclarativeglobal_p.h"
       
    62 #include "private/qdeclarativeworkerscript_p.h"
       
    63 #include "private/qdeclarativecomponent_p.h"
       
    64 #include "qdeclarativenetworkaccessmanagerfactory.h"
       
    65 #include "qdeclarativeimageprovider.h"
       
    66 #include "private/qdeclarativedirparser_p.h"
       
    67 #include "qdeclarativeextensioninterface.h"
       
    68 #include "private/qdeclarativelist_p.h"
       
    69 #include "private/qdeclarativetypenamecache_p.h"
       
    70 #include "private/qdeclarativeinclude_p.h"
       
    71 
       
    72 #include <QtCore/qmetaobject.h>
       
    73 #include <QScriptClass>
       
    74 #include <QNetworkReply>
       
    75 #include <QNetworkRequest>
       
    76 #include <QNetworkAccessManager>
       
    77 #include <QDesktopServices>
       
    78 #include <QTimer>
       
    79 #include <QList>
       
    80 #include <QPair>
       
    81 #include <QDebug>
       
    82 #include <QMetaObject>
       
    83 #include <QStack>
       
    84 #include <QMap>
       
    85 #include <QPluginLoader>
       
    86 #include <QtGui/qfontdatabase.h>
       
    87 #include <QtCore/qlibraryinfo.h>
       
    88 #include <QtCore/qthreadstorage.h>
       
    89 #include <QtCore/qthread.h>
       
    90 #include <QtCore/qcoreapplication.h>
       
    91 #include <QtCore/qdir.h>
       
    92 #include <QtCore/qmutex.h>
       
    93 #include <QtGui/qcolor.h>
       
    94 #include <QtGui/qvector3d.h>
       
    95 #include <QtGui/qsound.h>
       
    96 #include <QGraphicsObject>
       
    97 #include <QtCore/qcryptographichash.h>
       
    98 
       
    99 #include <private/qobject_p.h>
       
   100 #include <private/qscriptdeclarativeclass_p.h>
       
   101 
       
   102 #include <private/qdeclarativeitemsmodule_p.h>
       
   103 #include <private/qdeclarativeutilmodule_p.h>
       
   104 
       
   105 #ifdef Q_OS_WIN // for %APPDATA%
       
   106 #include <qt_windows.h>
       
   107 #include <qlibrary.h>
       
   108 
       
   109 #define CSIDL_APPDATA		0x001a	// <username>\Application Data
       
   110 #endif
       
   111 
       
   112 Q_DECLARE_METATYPE(QDeclarativeProperty)
       
   113 
       
   114 QT_BEGIN_NAMESPACE
       
   115 
       
   116 /*!
       
   117   \qmlclass QtObject QObject
       
   118   \since 4.7
       
   119   \brief The QtObject element is the most basic element in QML
       
   120 
       
   121   The QtObject element is a non-visual element which contains only the
       
   122   objectName property. It is useful for when you need an extremely
       
   123   lightweight element to place your own custom properties in.
       
   124 
       
   125   It can also be useful for C++ integration, as it is just a plain
       
   126   QObject. See the QObject documentation for further details.
       
   127 */
       
   128 /*!
       
   129   \qmlproperty string QtObject::objectName
       
   130   This property allows you to give a name to this specific object instance.
       
   131 
       
   132   See \l{scripting.html#accessing-child-qobjects}{Accessing Child QObjects}
       
   133   in the scripting documentation for details how objectName can be used from
       
   134   scripts.
       
   135 */
       
   136 
       
   137 struct StaticQtMetaObject : public QObject
       
   138 {
       
   139     static const QMetaObject *get()
       
   140         { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
       
   141 };
       
   142 
       
   143 static bool qt_QmlQtModule_registered = false;
       
   144 
       
   145 void QDeclarativeEnginePrivate::defineModule()
       
   146 {
       
   147     qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
       
   148     qmlRegisterType<QObject>("Qt",4,7,"QtObject");
       
   149     qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
       
   150 
       
   151     qmlRegisterType<QDeclarativeBinding>();
       
   152 }
       
   153 
       
   154 /*!
       
   155 \qmlclass Qt QDeclarativeEnginePrivate
       
   156 \brief The QML Global Qt Object
       
   157 
       
   158 The Qt object provides useful enums and functions from Qt, for use in all QML
       
   159 files. Note that you do note create instances of this type, but instead use
       
   160 the members of the global "Qt" object.
       
   161 
       
   162 \section1 Enums
       
   163 
       
   164 The Qt object contains all enums in the Qt namespace. For example, you can
       
   165 access the AlignLeft member of the Qt::AlignmentFlag enum with \c Qt.AlignLeft.
       
   166 
       
   167 For a full list of enums, see the \l{Qt Namespace} documentation.
       
   168 
       
   169 \section1 Types
       
   170 The Qt object also contains helper functions for creating objects of specific
       
   171 data types. This is primarily useful when setting the properties of an item
       
   172 when the property has one of the following types:
       
   173 
       
   174 \list
       
   175 \o Color
       
   176 \o Rect
       
   177 \o Point
       
   178 \o Size
       
   179 \o Vector3D
       
   180 \endlist
       
   181 
       
   182 There are also string based constructors for these types, see \l{qdeclarativebasictypes.html}{Qml Types}.
       
   183 
       
   184 \section1 Date/Time Formatters
       
   185 
       
   186 The Qt object contains several functions for formatting dates and times.
       
   187 
       
   188 \list
       
   189     \o \l{Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)
       
   190     \o \l{Qt::formatDate}{string Qt.formatDate(datetime date, variant format)
       
   191     \o \l{Qt::formatTime}{string Qt.formatTime(datetime date, variant format)
       
   192 \endlist
       
   193 
       
   194 The format specification is described at \l{Qt::formatDateTime}{Qt.formatDateTime}.
       
   195 
       
   196 
       
   197 \section1 Dynamic Object Creation
       
   198 The following functions on the global object allow you to dynamically create QML
       
   199 items from files or strings. See \l{Dynamic Object Management} for an overview
       
   200 of their use.
       
   201 
       
   202 \list
       
   203     \o \l{Qt::createComponent}{object Qt.createComponent(url)}
       
   204     \o \l{Qt::createQmlObject}{object Qt.createQmlObject(string qml, object parent, string filepath)}
       
   205 \endlist
       
   206 */
       
   207 
       
   208 
       
   209 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
       
   210 : captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false),
       
   211   outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
       
   212   objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
       
   213   inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
       
   214   inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
       
   215   typeManager(e), importDatabase(e), uniqueId(1)
       
   216 {
       
   217     if (!qt_QmlQtModule_registered) {
       
   218         qt_QmlQtModule_registered = true;
       
   219         QDeclarativeItemModule::defineModule();
       
   220         QDeclarativeUtilModule::defineModule();
       
   221         QDeclarativeEnginePrivate::defineModule();
       
   222         QDeclarativeValueTypeFactory::registerValueTypes();
       
   223     }
       
   224     globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine);
       
   225 }
       
   226 
       
   227 /*!
       
   228 \qmlmethod url Qt::resolvedUrl(url)
       
   229 This function returns \c url resolved relative to the URL of the
       
   230 caller.
       
   231 */
       
   232 QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
       
   233 {
       
   234     if (p) {
       
   235         QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context);
       
   236         Q_ASSERT(ctxt);
       
   237         return ctxt->resolvedUrl(url);
       
   238     }
       
   239     return baseUrl.resolved(url);
       
   240 }
       
   241 
       
   242 QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
       
   243 : p(priv), sqlQueryClass(0), namedNodeMapClass(0), nodeListClass(0)
       
   244 {
       
   245     // Note that all documentation for stuff put on the global object goes in
       
   246     // doc/src/declarative/globalobject.qdoc
       
   247 
       
   248     bool mainthread = priv != 0;
       
   249 
       
   250     QScriptValue qtObject =
       
   251         newQMetaObject(StaticQtMetaObject::get());
       
   252     globalObject().setProperty(QLatin1String("Qt"), qtObject);
       
   253 
       
   254 #ifndef QT_NO_DESKTOPSERVICES
       
   255     offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator())
       
   256         + QDir::separator() + QLatin1String("QML")
       
   257         + QDir::separator() + QLatin1String("OfflineStorage");
       
   258 #endif
       
   259 
       
   260     qt_add_qmlxmlhttprequest(this);
       
   261     qt_add_qmlsqldatabase(this);
       
   262     // XXX A Multimedia "Qt.Sound" class also needs to be made available,
       
   263     // XXX but we don't want a dependency in that cirection.
       
   264     // XXX When the above a done some better way, that way should also be
       
   265     // XXX used to add Qt.Sound class.
       
   266 
       
   267     //types
       
   268     if (mainthread)
       
   269         qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::include, 2));
       
   270     else
       
   271         qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::worker_include, 2));
       
   272 
       
   273     qtObject.setProperty(QLatin1String("isQtObject"), newFunction(QDeclarativeEnginePrivate::isQtObject, 1));
       
   274     qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4));
       
   275     qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4));
       
   276     qtObject.setProperty(QLatin1String("rect"), newFunction(QDeclarativeEnginePrivate::rect, 4));
       
   277     qtObject.setProperty(QLatin1String("point"), newFunction(QDeclarativeEnginePrivate::point, 2));
       
   278     qtObject.setProperty(QLatin1String("size"), newFunction(QDeclarativeEnginePrivate::size, 2));
       
   279     qtObject.setProperty(QLatin1String("vector3d"), newFunction(QDeclarativeEnginePrivate::vector3d, 3));
       
   280 
       
   281     if (mainthread) {
       
   282         //color helpers
       
   283         qtObject.setProperty(QLatin1String("lighter"), newFunction(QDeclarativeEnginePrivate::lighter, 1));
       
   284         qtObject.setProperty(QLatin1String("darker"), newFunction(QDeclarativeEnginePrivate::darker, 1));
       
   285         qtObject.setProperty(QLatin1String("tint"), newFunction(QDeclarativeEnginePrivate::tint, 2));
       
   286     }
       
   287 
       
   288     //date/time formatting
       
   289     qtObject.setProperty(QLatin1String("formatDate"),newFunction(QDeclarativeEnginePrivate::formatDate, 2));
       
   290     qtObject.setProperty(QLatin1String("formatTime"),newFunction(QDeclarativeEnginePrivate::formatTime, 2));
       
   291     qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2));
       
   292 
       
   293     //misc methods
       
   294     qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1));
       
   295     qtObject.setProperty(QLatin1String("fontFamilies"),newFunction(QDeclarativeEnginePrivate::fontFamilies, 0));
       
   296     qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1));
       
   297     qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1));
       
   298     qtObject.setProperty(QLatin1String("atob"),newFunction(QDeclarativeEnginePrivate::atob, 1));
       
   299     qtObject.setProperty(QLatin1String("quit"), newFunction(QDeclarativeEnginePrivate::quit, 0));
       
   300     qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QDeclarativeScriptEngine::resolvedUrl, 1));
       
   301 
       
   302     if (mainthread) {
       
   303         qtObject.setProperty(QLatin1String("createQmlObject"),
       
   304                 newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
       
   305         qtObject.setProperty(QLatin1String("createComponent"),
       
   306                 newFunction(QDeclarativeEnginePrivate::createComponent, 1));
       
   307     }
       
   308 
       
   309     //firebug/webkit compat
       
   310     QScriptValue consoleObject = newObject();
       
   311     consoleObject.setProperty(QLatin1String("log"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
       
   312     consoleObject.setProperty(QLatin1String("debug"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
       
   313     globalObject().setProperty(QLatin1String("console"), consoleObject);
       
   314 
       
   315     // translation functions need to be installed
       
   316     // before the global script class is constructed (QTBUG-6437)
       
   317     installTranslatorFunctions();
       
   318 }
       
   319 
       
   320 QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
       
   321 {
       
   322     delete sqlQueryClass;
       
   323     delete nodeListClass;
       
   324     delete namedNodeMapClass;
       
   325 }
       
   326 
       
   327 QScriptValue QDeclarativeScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine)
       
   328 {
       
   329     QString arg = ctxt->argument(0).toString();
       
   330     QUrl r = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt,QUrl(arg));
       
   331     return QScriptValue(r.toString());
       
   332 }
       
   333 
       
   334 QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
       
   335 {
       
   336     return p->getNetworkAccessManager();
       
   337 }
       
   338 
       
   339 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
       
   340 {
       
   341     Q_ASSERT(inProgressCreations == 0);
       
   342     Q_ASSERT(bindValues.isEmpty());
       
   343     Q_ASSERT(parserStatus.isEmpty());
       
   344 
       
   345     while (cleanup) {
       
   346         QDeclarativeCleanup *c = cleanup;
       
   347         cleanup = c->next;
       
   348         if (cleanup) cleanup->prev = &cleanup;
       
   349         c->next = 0;
       
   350         c->prev = 0;
       
   351         c->clear();
       
   352     }
       
   353 
       
   354     delete rootContext;
       
   355     rootContext = 0;
       
   356     delete contextClass;
       
   357     contextClass = 0;
       
   358     delete objectClass;
       
   359     objectClass = 0;
       
   360     delete valueTypeClass;
       
   361     valueTypeClass = 0;
       
   362     delete typeNameClass;
       
   363     typeNameClass = 0;
       
   364     delete listClass;
       
   365     listClass = 0;
       
   366     delete globalClass;
       
   367     globalClass = 0;
       
   368 
       
   369     for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
       
   370         (*iter)->release();
       
   371     for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
       
   372         (*iter)->release();
       
   373 
       
   374 }
       
   375 
       
   376 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
       
   377 {
       
   378     bvs.clear();
       
   379 }
       
   380 
       
   381 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
       
   382 {
       
   383     for (int ii = 0; ii < pss.count; ++ii) {
       
   384         QDeclarativeParserStatus *ps = pss.at(ii);
       
   385         if(ps)
       
   386             ps->d = 0;
       
   387     }
       
   388     pss.clear();
       
   389 }
       
   390 
       
   391 Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer);
       
   392 
       
   393 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
       
   394 {
       
   395     QObjectPrivate *p = QObjectPrivate::get(o);
       
   396     if (p->declarativeData) {
       
   397         QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
       
   398         if (d->ownContext && d->context) {
       
   399             d->context->destroy();
       
   400             d->context = 0;
       
   401         }
       
   402     }
       
   403 }
       
   404 
       
   405 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
       
   406 {
       
   407     static_cast<QDeclarativeData *>(d)->destroyed(o);
       
   408 }
       
   409 
       
   410 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
       
   411 {
       
   412     static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
       
   413 }
       
   414 
       
   415 void QDeclarativeEnginePrivate::init()
       
   416 {
       
   417     Q_Q(QDeclarativeEngine);
       
   418     qRegisterMetaType<QVariant>("QVariant");
       
   419     qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
       
   420     qRegisterMetaType<QScriptValue>("QScriptValue");
       
   421     qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
       
   422 
       
   423     QDeclarativeData::init();
       
   424 
       
   425     contextClass = new QDeclarativeContextScriptClass(q);
       
   426     objectClass = new QDeclarativeObjectScriptClass(q);
       
   427     valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
       
   428     typeNameClass = new QDeclarativeTypeNameScriptClass(q);
       
   429     listClass = new QDeclarativeListScriptClass(q);
       
   430     rootContext = new QDeclarativeContext(q,true);
       
   431 
       
   432     if (QCoreApplication::instance()->thread() == q->thread() &&
       
   433         QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
       
   434         qmlEngineDebugServer();
       
   435         isDebugging = true;
       
   436         QDeclarativeEngineDebugServer::addEngine(q);
       
   437     }
       
   438 }
       
   439 
       
   440 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
       
   441 {
       
   442     Q_Q(QDeclarativeEngine);
       
   443     if (!workerScriptEngine)
       
   444         workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
       
   445     return workerScriptEngine;
       
   446 }
       
   447 
       
   448 /*!
       
   449   \class QDeclarativeEngine
       
   450   \since 4.7
       
   451   \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
       
   452   \mainclass
       
   453 
       
   454   Each QML component is instantiated in a QDeclarativeContext.
       
   455   QDeclarativeContext's are essential for passing data to QML
       
   456   components.  In QML, contexts are arranged hierarchically and this
       
   457   hierarchy is managed by the QDeclarativeEngine.
       
   458 
       
   459   Prior to creating any QML components, an application must have
       
   460   created a QDeclarativeEngine to gain access to a QML context.  The
       
   461   following example shows how to create a simple Text item.
       
   462 
       
   463   \code
       
   464   QDeclarativeEngine engine;
       
   465   QDeclarativeComponent component(&engine);
       
   466   component.setData("import Qt 4.7\nText { text: \"Hello world!\" }", QUrl());
       
   467   QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
       
   468 
       
   469   //add item to view, etc
       
   470   ...
       
   471   \endcode
       
   472 
       
   473   In this case, the Text item will be created in the engine's
       
   474   \l {QDeclarativeEngine::rootContext()}{root context}.
       
   475 
       
   476   \sa QDeclarativeComponent QDeclarativeContext
       
   477 */
       
   478 
       
   479 /*!
       
   480   Create a new QDeclarativeEngine with the given \a parent.
       
   481 */
       
   482 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
       
   483 : QObject(*new QDeclarativeEnginePrivate(this), parent)
       
   484 {
       
   485     Q_D(QDeclarativeEngine);
       
   486     d->init();
       
   487 }
       
   488 
       
   489 /*!
       
   490   Destroys the QDeclarativeEngine.
       
   491 
       
   492   Any QDeclarativeContext's created on this engine will be
       
   493   invalidated, but not destroyed (unless they are parented to the
       
   494   QDeclarativeEngine object).
       
   495 */
       
   496 QDeclarativeEngine::~QDeclarativeEngine()
       
   497 {
       
   498     Q_D(QDeclarativeEngine);
       
   499     if (d->isDebugging)
       
   500         QDeclarativeEngineDebugServer::remEngine(this);
       
   501 }
       
   502 
       
   503 /*! \fn void QDeclarativeEngine::quit()
       
   504     This signal is emitted when the QDeclarativeEngine quits.
       
   505  */
       
   506 
       
   507 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
       
   508     This signal is emitted when \a warnings messages are generated by QML.
       
   509  */
       
   510 
       
   511 /*!
       
   512   Clears the engine's internal component cache.
       
   513 
       
   514   Normally the QDeclarativeEngine caches components loaded from qml
       
   515   files.  This method clears this cache and forces the component to be
       
   516   reloaded.
       
   517  */
       
   518 void QDeclarativeEngine::clearComponentCache()
       
   519 {
       
   520     Q_D(QDeclarativeEngine);
       
   521     d->typeManager.clearCache();
       
   522 }
       
   523 
       
   524 /*!
       
   525   Returns the engine's root context.
       
   526 
       
   527   The root context is automatically created by the QDeclarativeEngine.
       
   528   Data that should be available to all QML component instances
       
   529   instantiated by the engine should be put in the root context.
       
   530 
       
   531   Additional data that should only be available to a subset of
       
   532   component instances should be added to sub-contexts parented to the
       
   533   root context.
       
   534 */
       
   535 QDeclarativeContext *QDeclarativeEngine::rootContext()
       
   536 {
       
   537     Q_D(QDeclarativeEngine);
       
   538     return d->rootContext;
       
   539 }
       
   540 
       
   541 /*!
       
   542   Sets the \a factory to use for creating QNetworkAccessManager(s).
       
   543 
       
   544   QNetworkAccessManager is used for all network access by QML.  By
       
   545   implementing a factory it is possible to create custom
       
   546   QNetworkAccessManager with specialized caching, proxy and cookie
       
   547   support.
       
   548 
       
   549   The factory must be set before exceuting the engine.
       
   550 */
       
   551 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
       
   552 {
       
   553     Q_D(QDeclarativeEngine);
       
   554     QMutexLocker locker(&d->mutex);
       
   555     d->networkAccessManagerFactory = factory;
       
   556 }
       
   557 
       
   558 /*!
       
   559   Returns the current QDeclarativeNetworkAccessManagerFactory.
       
   560 
       
   561   \sa setNetworkAccessManagerFactory()
       
   562 */
       
   563 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
       
   564 {
       
   565     Q_D(const QDeclarativeEngine);
       
   566     return d->networkAccessManagerFactory;
       
   567 }
       
   568 
       
   569 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
       
   570 {
       
   571     QMutexLocker locker(&mutex);
       
   572     QNetworkAccessManager *nam;
       
   573     if (networkAccessManagerFactory) {
       
   574         nam = networkAccessManagerFactory->create(parent);
       
   575     } else {
       
   576         nam = new QNetworkAccessManager(parent);
       
   577     }
       
   578 
       
   579     return nam;
       
   580 }
       
   581 
       
   582 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
       
   583 {
       
   584     Q_Q(const QDeclarativeEngine);
       
   585     if (!networkAccessManager)
       
   586         networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
       
   587     return networkAccessManager;
       
   588 }
       
   589 
       
   590 /*!
       
   591   Returns a common QNetworkAccessManager which can be used by any QML
       
   592   element instantiated by this engine.
       
   593 
       
   594   If a QDeclarativeNetworkAccessManagerFactory has been set and a
       
   595   QNetworkAccessManager has not yet been created, the
       
   596   QDeclarativeNetworkAccessManagerFactory will be used to create the
       
   597   QNetworkAccessManager; otherwise the returned QNetworkAccessManager
       
   598   will have no proxy or cache set.
       
   599 
       
   600   \sa setNetworkAccessManagerFactory()
       
   601 */
       
   602 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
       
   603 {
       
   604     Q_D(const QDeclarativeEngine);
       
   605     return d->getNetworkAccessManager();
       
   606 }
       
   607 
       
   608 /*!
       
   609 
       
   610   Sets the \a provider to use for images requested via the \e
       
   611   image: url scheme, with host \a providerId.
       
   612 
       
   613   QDeclarativeImageProvider allows images to be provided to QML
       
   614   asynchronously.  The image request will be run in a low priority
       
   615   thread.  This allows potentially costly image loading to be done in
       
   616   the background, without affecting the performance of the UI.
       
   617 
       
   618   Note that images loaded from a QDeclarativeImageProvider are cached
       
   619   by QPixmapCache, similar to any image loaded by QML.
       
   620 
       
   621   The QDeclarativeEngine assumes ownership of the provider.
       
   622 
       
   623   This example creates a provider with id \e colors:
       
   624 
       
   625   \snippet examples/declarative/cppextensions/imageprovider/imageprovider.cpp 0
       
   626 
       
   627   \snippet examples/declarative/cppextensions/imageprovider/imageprovider-example.qml 0
       
   628 
       
   629   \sa removeImageProvider()
       
   630 */
       
   631 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
       
   632 {
       
   633     Q_D(QDeclarativeEngine);
       
   634     QMutexLocker locker(&d->mutex);
       
   635     d->imageProviders.insert(providerId, provider);
       
   636 }
       
   637 
       
   638 /*!
       
   639   Returns the QDeclarativeImageProvider set for \a providerId.
       
   640 */
       
   641 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
       
   642 {
       
   643     Q_D(const QDeclarativeEngine);
       
   644     QMutexLocker locker(&d->mutex);
       
   645     return d->imageProviders.value(providerId);
       
   646 }
       
   647 
       
   648 /*!
       
   649   Removes the QDeclarativeImageProvider for \a providerId.
       
   650 
       
   651   Returns the provider if it was found; otherwise returns 0.
       
   652 
       
   653   \sa addImageProvider()
       
   654 */
       
   655 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
       
   656 {
       
   657     Q_D(QDeclarativeEngine);
       
   658     QMutexLocker locker(&d->mutex);
       
   659     delete d->imageProviders.take(providerId);
       
   660 }
       
   661 
       
   662 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
       
   663 {
       
   664     QMutexLocker locker(&mutex);
       
   665     QImage image;
       
   666     QDeclarativeImageProvider *provider = imageProviders.value(url.host());
       
   667     if (provider)
       
   668         image = provider->request(url.path().mid(1), size, req_size);
       
   669     return image;
       
   670 }
       
   671 
       
   672 /*!
       
   673   Return the base URL for this engine.  The base URL is only used to
       
   674   resolve components when a relative URL is passed to the
       
   675   QDeclarativeComponent constructor.
       
   676 
       
   677   If a base URL has not been explicitly set, this method returns the
       
   678   application's current working directory.
       
   679 
       
   680   \sa setBaseUrl()
       
   681 */
       
   682 QUrl QDeclarativeEngine::baseUrl() const
       
   683 {
       
   684     Q_D(const QDeclarativeEngine);
       
   685     if (d->baseUrl.isEmpty()) {
       
   686         return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
       
   687     } else {
       
   688         return d->baseUrl;
       
   689     }
       
   690 }
       
   691 
       
   692 /*!
       
   693   Set the  base URL for this engine to \a url.
       
   694 
       
   695   \sa baseUrl()
       
   696 */
       
   697 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
       
   698 {
       
   699     Q_D(QDeclarativeEngine);
       
   700     d->baseUrl = url;
       
   701 }
       
   702 
       
   703 /*!
       
   704   Returns true if warning messages will be output to stderr in addition
       
   705   to being emitted by the warnings() signal, otherwise false.
       
   706 
       
   707   The default value is true.
       
   708 */
       
   709 bool QDeclarativeEngine::outputWarningsToStandardError() const
       
   710 {
       
   711     Q_D(const QDeclarativeEngine);
       
   712     return d->outputWarningsToStdErr;
       
   713 }
       
   714 
       
   715 /*!
       
   716   Set whether warning messages will be output to stderr to \a enabled.
       
   717 
       
   718   If \a enabled is true, any warning messages generated by QML will be
       
   719   output to stderr and emitted by the warnings() signal.  If \a enabled
       
   720   is false, on the warnings() signal will be emitted.  This allows
       
   721   applications to handle warning output themselves.
       
   722 
       
   723   The default value is true.
       
   724 */
       
   725 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
       
   726 {
       
   727     Q_D(QDeclarativeEngine);
       
   728     d->outputWarningsToStdErr = enabled;
       
   729 }
       
   730 
       
   731 /*!
       
   732   Returns the QDeclarativeContext for the \a object, or 0 if no
       
   733   context has been set.
       
   734 
       
   735   When the QDeclarativeEngine instantiates a QObject, the context is
       
   736   set automatically.
       
   737   */
       
   738 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
       
   739 {
       
   740     if(!object)
       
   741         return 0;
       
   742 
       
   743     QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
       
   744 
       
   745     QDeclarativeData *data =
       
   746         static_cast<QDeclarativeData *>(priv->declarativeData);
       
   747 
       
   748     if (!data)
       
   749         return 0;
       
   750     else if (data->outerContext)
       
   751         return data->outerContext->asQDeclarativeContext();
       
   752     else
       
   753         return 0;
       
   754 }
       
   755 
       
   756 /*!
       
   757   Sets the QDeclarativeContext for the \a object to \a context.
       
   758   If the \a object already has a context, a warning is
       
   759   output, but the context is not changed.
       
   760 
       
   761   When the QDeclarativeEngine instantiates a QObject, the context is
       
   762   set automatically.
       
   763  */
       
   764 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
       
   765 {
       
   766     if (!object || !context)
       
   767         return;
       
   768 
       
   769     QDeclarativeData *data = QDeclarativeData::get(object, true);
       
   770     if (data->context) {
       
   771         qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
       
   772         return;
       
   773     }
       
   774 
       
   775     QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
       
   776     contextData->addObject(object);
       
   777 }
       
   778 
       
   779 /*!
       
   780   \enum QDeclarativeEngine::ObjectOwnership
       
   781 
       
   782   Ownership controls whether or not QML automatically destroys the
       
   783   QObject when the object is garbage collected by the JavaScript
       
   784   engine.  The two ownership options are:
       
   785 
       
   786   \value CppOwnership The object is owned by C++ code, and will
       
   787   never be deleted by QML.  The JavaScript destroy() method cannot be
       
   788   used on objects with CppOwnership.  This option is similar to
       
   789   QScriptEngine::QtOwnership.
       
   790 
       
   791   \value JavaScriptOwnership The object is owned by JavaScript.
       
   792   When the object is returned to QML as the return value of a method
       
   793   call or property access, QML will delete the object if there are no
       
   794   remaining JavaScript references to it and it has no
       
   795   QObject::parent().  This option is similar to
       
   796   QScriptEngine::ScriptOwnership.
       
   797 
       
   798   Generally an application doesn't need to set an object's ownership
       
   799   explicitly.  QML uses a heuristic to set the default object
       
   800   ownership.  By default, an object that is created by QML has
       
   801   JavaScriptOwnership.  The exception to this are the root objects
       
   802   created by calling QDeclarativeCompnent::create() or
       
   803   QDeclarativeComponent::beginCreate() which have CppOwnership by
       
   804   default.  The ownership of these root-level objects is considered to
       
   805   have been transfered to the C++ caller.
       
   806 
       
   807   Objects not-created by QML have CppOwnership by default.  The
       
   808   exception to this is objects returned from a C++ method call.  The
       
   809   ownership of these objects is passed to JavaScript.
       
   810 
       
   811   Calling setObjectOwnership() overrides the default ownership
       
   812   heuristic used by QML.
       
   813 */
       
   814 
       
   815 /*!
       
   816   Sets the \a ownership of \a object.
       
   817 */
       
   818 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
       
   819 {
       
   820     if (!object)
       
   821         return;
       
   822 
       
   823     // No need to do anything if CppOwnership and there is no QDeclarativeData as
       
   824     // the current ownership must be CppOwnership
       
   825     QDeclarativeData *ddata = QDeclarativeData::get(object, ownership == JavaScriptOwnership);
       
   826     if (!ddata)
       
   827         return;
       
   828 
       
   829     ddata->indestructible = (ownership == CppOwnership)?true:false;
       
   830     ddata->explicitIndestructibleSet = true;
       
   831 }
       
   832 
       
   833 /*!
       
   834   Returns the ownership of \a object.
       
   835 */
       
   836 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
       
   837 {
       
   838     if (!object)
       
   839         return CppOwnership;
       
   840 
       
   841     QDeclarativeData *ddata = QDeclarativeData::get(object, false);
       
   842     if (!ddata)
       
   843         return CppOwnership;
       
   844     else
       
   845         return ddata->indestructible?CppOwnership:JavaScriptOwnership;
       
   846 }
       
   847 
       
   848 void qmlExecuteDeferred(QObject *object)
       
   849 {
       
   850     QDeclarativeData *data = QDeclarativeData::get(object);
       
   851 
       
   852     if (data && data->deferredComponent) {
       
   853 
       
   854         QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
       
   855 
       
   856         QDeclarativeComponentPrivate::ConstructionState state;
       
   857         QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
       
   858 
       
   859         data->deferredComponent->release();
       
   860         data->deferredComponent = 0;
       
   861 
       
   862         QDeclarativeComponentPrivate::complete(ep, &state);
       
   863     }
       
   864 }
       
   865 
       
   866 QDeclarativeContext *qmlContext(const QObject *obj)
       
   867 {
       
   868     return QDeclarativeEngine::contextForObject(obj);
       
   869 }
       
   870 
       
   871 QDeclarativeEngine *qmlEngine(const QObject *obj)
       
   872 {
       
   873     QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
       
   874     return context?context->engine():0;
       
   875 }
       
   876 
       
   877 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
       
   878 {
       
   879     QDeclarativeData *data = QDeclarativeData::get(object);
       
   880     if (!data)
       
   881         return 0; // Attached properties are only on objects created by QML
       
   882 
       
   883     QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0;
       
   884     if (rv || !create)
       
   885         return rv;
       
   886 
       
   887     QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
       
   888     if (!pf)
       
   889         return 0;
       
   890 
       
   891     rv = pf(const_cast<QObject *>(object));
       
   892 
       
   893     if (rv) {
       
   894         if (!data->attachedProperties)
       
   895             data->attachedProperties = new QHash<int, QObject *>();
       
   896         data->attachedProperties->insert(id, rv);
       
   897     }
       
   898 
       
   899     return rv;
       
   900 }
       
   901 
       
   902 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
       
   903                                      const QMetaObject *attachedMetaObject, bool create)
       
   904 {
       
   905     if (*idCache == -1)
       
   906         *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
       
   907 
       
   908     if (*idCache == -1 || !object)
       
   909         return 0;
       
   910 
       
   911     return qmlAttachedPropertiesObjectById(*idCache, object, create);
       
   912 }
       
   913 
       
   914 void QDeclarativeData::destroyed(QObject *object)
       
   915 {
       
   916     if (deferredComponent)
       
   917         deferredComponent->release();
       
   918     if (attachedProperties)
       
   919         delete attachedProperties;
       
   920 
       
   921     if (nextContextObject)
       
   922         nextContextObject->prevContextObject = prevContextObject;
       
   923     if (prevContextObject)
       
   924         *prevContextObject = nextContextObject;
       
   925 
       
   926     QDeclarativeAbstractBinding *binding = bindings;
       
   927     while (binding) {
       
   928         QDeclarativeAbstractBinding *next = binding->m_nextBinding;
       
   929         binding->m_prevBinding = 0;
       
   930         binding->m_nextBinding = 0;
       
   931         binding->destroy();
       
   932         binding = next;
       
   933     }
       
   934 
       
   935     if (bindingBits)
       
   936         free(bindingBits);
       
   937 
       
   938     if (propertyCache)
       
   939         propertyCache->release();
       
   940 
       
   941     if (ownContext && context)
       
   942         context->destroy();
       
   943 
       
   944     while (guards) {
       
   945         QDeclarativeGuard<QObject> *guard = guards;
       
   946         *guard = (QObject *)0;
       
   947         guard->objectDestroyed(object);
       
   948     }
       
   949 
       
   950     if (scriptValue)
       
   951         delete scriptValue;
       
   952 
       
   953     if (ownMemory)
       
   954         delete this;
       
   955 }
       
   956 
       
   957 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
       
   958 {
       
   959     if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
       
   960 }
       
   961 
       
   962 bool QDeclarativeData::hasBindingBit(int bit) const
       
   963 {
       
   964     if (bindingBitsSize > bit)
       
   965         return bindingBits[bit / 32] & (1 << (bit % 32));
       
   966     else
       
   967         return false;
       
   968 }
       
   969 
       
   970 void QDeclarativeData::clearBindingBit(int bit)
       
   971 {
       
   972     if (bindingBitsSize > bit)
       
   973         bindingBits[bit / 32] &= ~(1 << (bit % 32));
       
   974 }
       
   975 
       
   976 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
       
   977 {
       
   978     if (bindingBitsSize <= bit) {
       
   979         int props = obj->metaObject()->propertyCount();
       
   980         Q_ASSERT(bit < props);
       
   981 
       
   982         int arraySize = (props + 31) / 32;
       
   983         int oldArraySize = bindingBitsSize / 32;
       
   984 
       
   985         bindingBits = (quint32 *)realloc(bindingBits,
       
   986                                          arraySize * sizeof(quint32));
       
   987 
       
   988         memset(bindingBits + oldArraySize,
       
   989                0x00,
       
   990                sizeof(quint32) * (arraySize - oldArraySize));
       
   991 
       
   992         bindingBitsSize = arraySize * 32;
       
   993     }
       
   994 
       
   995     bindingBits[bit / 32] |= (1 << (bit % 32));
       
   996 }
       
   997 
       
   998 /*!
       
   999     Creates a QScriptValue allowing you to use \a object in QML script.
       
  1000     \a engine is the QDeclarativeEngine it is to be created in.
       
  1001 
       
  1002     The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
       
  1003     to the special needs of QML requiring more functionality than a standard
       
  1004     QtScript QObject.
       
  1005 */
       
  1006 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
       
  1007                                                QDeclarativeEngine* engine)
       
  1008 {
       
  1009     QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
       
  1010     return enginePriv->objectClass->newQObject(object);
       
  1011 }
       
  1012 
       
  1013 /*!
       
  1014     Returns the QDeclarativeContext for the executing QScript \a ctxt.
       
  1015 */
       
  1016 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
       
  1017 {
       
  1018     QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
       
  1019     Q_ASSERT(scopeNode.isValid());
       
  1020     Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
       
  1021     return contextClass->contextFromValue(scopeNode);
       
  1022 }
       
  1023 
       
  1024 
       
  1025 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
       
  1026 {
       
  1027     if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
       
  1028         if (url.authority().isEmpty())
       
  1029             return QLatin1Char(':') + url.path();
       
  1030         return QString();
       
  1031     }
       
  1032     return url.toLocalFile();
       
  1033 }
       
  1034 
       
  1035 /*!
       
  1036 \qmlmethod object Qt::createComponent(url)
       
  1037 
       
  1038 This function takes the URL of a QML file as its only argument. It returns
       
  1039 a component object which can be used to create and load that QML file.
       
  1040 
       
  1041 Here is an example. Remember that QML files that might be loaded
       
  1042 over the network cannot be expected to be ready immediately.
       
  1043 
       
  1044 \snippet doc/src/snippets/declarative/componentCreation.js 0
       
  1045 \codeline
       
  1046 \snippet doc/src/snippets/declarative/componentCreation.js 1
       
  1047 
       
  1048 If you are certain the files will be local, you could simplify to:
       
  1049 
       
  1050 \snippet doc/src/snippets/declarative/componentCreation.js 2
       
  1051 
       
  1052 The methods and properties of the \l {Component} element are defined in its own
       
  1053 page, but when using it dynamically only two methods are usually used.
       
  1054  \l {Component::createObject()}{Component.createObject()} returns the created object or \c null if there is an error.
       
  1055 If there is an error, \l {Component::errorString()}{Component.errorString()} describes
       
  1056 the error that occurred. Note that createObject() takes exactly one argument, which is set
       
  1057 to the parent of the created object. Graphical objects without a parent will not appear
       
  1058 on the scene, but if you do not wish to parent the item at this point you can safely pass
       
  1059 in null.
       
  1060 
       
  1061 If you want to just create an arbitrary string of QML, instead of
       
  1062 loading a QML file, consider the \l{Qt.createQmlObject(string qml, object parent, string filepath)}{Qt.createQmlObject()} function.
       
  1063 */
       
  1064 
       
  1065 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
       
  1066 {
       
  1067     QDeclarativeEnginePrivate *activeEnginePriv =
       
  1068         static_cast<QDeclarativeScriptEngine*>(engine)->p;
       
  1069     QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
       
  1070 
       
  1071     QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
       
  1072     Q_ASSERT(context);
       
  1073 
       
  1074     if(ctxt->argumentCount() != 1) {
       
  1075         return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
       
  1076     }else{
       
  1077         QString arg = ctxt->argument(0).toString();
       
  1078         if (arg.isEmpty())
       
  1079             return engine->nullValue();
       
  1080         QUrl url = QUrl(context->resolvedUrl(QUrl(arg)));
       
  1081         QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
       
  1082         QDeclarativeComponentPrivate::get(c)->creationContext = context;
       
  1083         QDeclarativeData::get(c, true)->setImplicitDestructible();
       
  1084         return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
       
  1085     }
       
  1086 }
       
  1087 
       
  1088 /*!
       
  1089 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
       
  1090 
       
  1091 Creates a new object from the specified string of QML. It requires a
       
  1092 second argument, which is the id of an existing QML object to use as
       
  1093 the new object's parent. If a third argument is provided, this is used
       
  1094 for error reporting as the filepath that the QML came from.
       
  1095 
       
  1096 Example (where \c targetItem is the id of an existing QML item):
       
  1097 
       
  1098 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
       
  1099 
       
  1100 This function is intended for use inside QML only. It is intended to behave
       
  1101 similarly to eval, but for creating QML elements.
       
  1102 
       
  1103 Returns the created object, \c or null if there is an error. In the case of an
       
  1104 error, a QtScript Error object is thrown. This object has the additional property,
       
  1105 qmlErrors, which is an array of all the errors encountered when trying to execute the
       
  1106 QML. Each object in the array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
       
  1107 
       
  1108 Note that this function returns immediately, and therefore may not work if
       
  1109 the QML loads new components. If you are trying to load a new component,
       
  1110 for example from a QML file, consider the \l{Qt.createComponent(url file)}{Qt.createComponent()} function
       
  1111 instead. 'New components' refers to external QML files that have not yet
       
  1112 been loaded, and so it is safe to use \c Qt.createQmlObject() to load built-in
       
  1113 components.
       
  1114 */
       
  1115 
       
  1116 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
       
  1117 {
       
  1118     QDeclarativeEnginePrivate *activeEnginePriv =
       
  1119         static_cast<QDeclarativeScriptEngine*>(engine)->p;
       
  1120     QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
       
  1121 
       
  1122     if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
       
  1123         return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
       
  1124 
       
  1125     QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
       
  1126     Q_ASSERT(context);
       
  1127 
       
  1128     QString qml = ctxt->argument(0).toString();
       
  1129     if (qml.isEmpty())
       
  1130         return engine->nullValue();
       
  1131 
       
  1132     QUrl url;
       
  1133     if(ctxt->argumentCount() > 2)
       
  1134         url = QUrl(ctxt->argument(2).toString());
       
  1135     else
       
  1136         url = QUrl(QLatin1String("inline"));
       
  1137 
       
  1138     if (url.isValid() && url.isRelative())
       
  1139         url = context->resolvedUrl(url);
       
  1140 
       
  1141     QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
       
  1142     if(!parentArg)
       
  1143         return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
       
  1144 
       
  1145     QDeclarativeComponent component(activeEngine);
       
  1146     component.setData(qml.toUtf8(), url);
       
  1147 
       
  1148     if(component.isError()) {
       
  1149         QList<QDeclarativeError> errors = component.errors();
       
  1150         QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
       
  1151         QScriptValue arr = ctxt->engine()->newArray(errors.length());
       
  1152         int i = 0;
       
  1153         foreach (const QDeclarativeError &error, errors){
       
  1154             errstr += QLatin1String("    ") + error.toString() + QLatin1String("\n");
       
  1155             QScriptValue qmlErrObject = ctxt->engine()->newObject();
       
  1156             qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
       
  1157             qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
       
  1158             qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
       
  1159             qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
       
  1160             arr.setProperty(i++, qmlErrObject);
       
  1161         }
       
  1162         QScriptValue err = ctxt->throwError(errstr);
       
  1163         err.setProperty(QLatin1String("qmlErrors"),arr);
       
  1164         return err;
       
  1165     }
       
  1166 
       
  1167     if (!component.isReady())
       
  1168         return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
       
  1169 
       
  1170     QObject *obj = component.beginCreate(context->asQDeclarativeContext());
       
  1171     if(obj)
       
  1172         QDeclarativeData::get(obj, true)->setImplicitDestructible();
       
  1173     component.completeCreate();
       
  1174 
       
  1175     if(component.isError()) {
       
  1176         QList<QDeclarativeError> errors = component.errors();
       
  1177         QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
       
  1178         QScriptValue arr = ctxt->engine()->newArray(errors.length());
       
  1179         int i = 0;
       
  1180         foreach (const QDeclarativeError &error, errors){
       
  1181             errstr += QLatin1String("    ") + error.toString() + QLatin1String("\n");
       
  1182             QScriptValue qmlErrObject = ctxt->engine()->newObject();
       
  1183             qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
       
  1184             qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
       
  1185             qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
       
  1186             qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
       
  1187             arr.setProperty(i++, qmlErrObject);
       
  1188         }
       
  1189         QScriptValue err = ctxt->throwError(errstr);
       
  1190         err.setProperty(QLatin1String("qmlErrors"),arr);
       
  1191         return err;
       
  1192     }
       
  1193 
       
  1194     Q_ASSERT(obj);
       
  1195 
       
  1196     obj->setParent(parentArg);
       
  1197     QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj);
       
  1198     QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parentArg);
       
  1199     if(gobj && gparent)
       
  1200         gobj->setParentItem(gparent);
       
  1201 
       
  1202     QDeclarativeData::get(obj, true)->setImplicitDestructible();
       
  1203     return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
       
  1204 }
       
  1205 
       
  1206 /*!
       
  1207 \qmlmethod bool Qt::isQtObject(object)
       
  1208 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
       
  1209 */
       
  1210 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
       
  1211 {
       
  1212     if (ctxt->argumentCount() == 0)
       
  1213         return QScriptValue(engine, false);
       
  1214 
       
  1215     return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
       
  1216 }
       
  1217 
       
  1218 /*!
       
  1219 \qmlmethod Qt::vector3d(real x, real y, real z)
       
  1220 This function returns a Vector3D with the specified \c x, \c y and \c z.
       
  1221 */
       
  1222 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
       
  1223 {
       
  1224     if(ctxt->argumentCount() != 3)
       
  1225         return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
       
  1226     qsreal x = ctxt->argument(0).toNumber();
       
  1227     qsreal y = ctxt->argument(1).toNumber();
       
  1228     qsreal z = ctxt->argument(2).toNumber();
       
  1229     return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QVector3D(x, y, z)));
       
  1230 }
       
  1231 
       
  1232 /*!
       
  1233 \qmlmethod string Qt::formatDate(datetime date, variant format)
       
  1234 This function returns the string representation of \c date, formatted according to \c format.
       
  1235 */
       
  1236 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
       
  1237 {
       
  1238     int argCount = ctxt->argumentCount();
       
  1239     if(argCount == 0 || argCount > 2)
       
  1240         return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
       
  1241 
       
  1242     QDate date = ctxt->argument(0).toDateTime().date();
       
  1243     Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
       
  1244     if (argCount == 2) {
       
  1245         if (ctxt->argument(1).isString()) {
       
  1246             QString format = ctxt->argument(1).toString();
       
  1247             return engine->newVariant(qVariantFromValue(date.toString(format)));
       
  1248         } else if (ctxt->argument(1).isNumber()) {
       
  1249             enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
       
  1250         } else {
       
  1251             return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
       
  1252         }
       
  1253     }
       
  1254     return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
       
  1255 }
       
  1256 
       
  1257 /*!
       
  1258 \qmlmethod string Qt::formatTime(datetime time, variant format)
       
  1259 This function returns the string representation of \c time, formatted according to \c format.
       
  1260 
       
  1261 See Qt::formatDateTime for how to define \c format.
       
  1262 */
       
  1263 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
       
  1264 {
       
  1265     int argCount = ctxt->argumentCount();
       
  1266     if(argCount == 0 || argCount > 2)
       
  1267         return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
       
  1268 
       
  1269     QTime date = ctxt->argument(0).toDateTime().time();
       
  1270     Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
       
  1271     if (argCount == 2) {
       
  1272         if (ctxt->argument(1).isString()) {
       
  1273             QString format = ctxt->argument(1).toString();
       
  1274             return engine->newVariant(qVariantFromValue(date.toString(format)));
       
  1275         } else if (ctxt->argument(1).isNumber()) {
       
  1276             enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
       
  1277         } else {
       
  1278             return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
       
  1279         }
       
  1280     }
       
  1281     return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
       
  1282 }
       
  1283 
       
  1284 /*!
       
  1285 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
       
  1286 This function returns the string representation of \c dateTime, formatted according to \c format.
       
  1287 
       
  1288 \c format for the date/time formatting functions is be specified as follows.
       
  1289 
       
  1290     These expressions may be used for the date:
       
  1291 
       
  1292     \table
       
  1293     \header \i Expression \i Output
       
  1294     \row \i d \i the day as number without a leading zero (1 to 31)
       
  1295     \row \i dd \i the day as number with a leading zero (01 to 31)
       
  1296     \row \i ddd
       
  1297             \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
       
  1298             Uses QDate::shortDayName().
       
  1299     \row \i dddd
       
  1300             \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
       
  1301             Uses QDate::longDayName().
       
  1302     \row \i M \i the month as number without a leading zero (1-12)
       
  1303     \row \i MM \i the month as number with a leading zero (01-12)
       
  1304     \row \i MMM
       
  1305             \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
       
  1306             Uses QDate::shortMonthName().
       
  1307     \row \i MMMM
       
  1308             \i the long localized month name (e.g. 'January' to 'December').
       
  1309             Uses QDate::longMonthName().
       
  1310     \row \i yy \i the year as two digit number (00-99)
       
  1311     \row \i yyyy \i the year as four digit number
       
  1312     \endtable
       
  1313 
       
  1314     These expressions may be used for the time:
       
  1315 
       
  1316     \table
       
  1317     \header \i Expression \i Output
       
  1318     \row \i h
       
  1319          \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
       
  1320     \row \i hh
       
  1321          \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
       
  1322     \row \i m \i the minute without a leading zero (0 to 59)
       
  1323     \row \i mm \i the minute with a leading zero (00 to 59)
       
  1324     \row \i s \i the second without a leading zero (0 to 59)
       
  1325     \row \i ss \i the second with a leading zero (00 to 59)
       
  1326     \row \i z \i the milliseconds without leading zeroes (0 to 999)
       
  1327     \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
       
  1328     \row \i AP
       
  1329             \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
       
  1330     \row \i ap
       
  1331             \i use am/pm display. \e ap will be replaced by either "am" or "pm".
       
  1332     \endtable
       
  1333 
       
  1334     All other input characters will be ignored. Any sequence of characters that
       
  1335     are enclosed in singlequotes will be treated as text and not be used as an
       
  1336     expression. Two consecutive singlequotes ("''") are replaced by a singlequote
       
  1337     in the output.
       
  1338 
       
  1339     Example format strings (assumed that the date and time is 21 May 2001
       
  1340     14:13:09):
       
  1341 
       
  1342     \table
       
  1343     \header \i Format       \i Result
       
  1344     \row \i dd.MM.yyyy      \i 21.05.2001
       
  1345     \row \i ddd MMMM d yy   \i Tue May 21 01
       
  1346     \row \i hh:mm:ss.zzz    \i 14:13:09.042
       
  1347     \row \i h:m:s ap        \i 2:13:9 pm
       
  1348     \endtable
       
  1349 
       
  1350 If no format is specified the locale's short format is used. Alternatively, you can specify
       
  1351 \c Qt.DefaultLocaleLongDate to get the locale's long format.
       
  1352 */
       
  1353 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
       
  1354 {
       
  1355     int argCount = ctxt->argumentCount();
       
  1356     if(argCount == 0 || argCount > 2)
       
  1357         return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
       
  1358 
       
  1359     QDateTime date = ctxt->argument(0).toDateTime();
       
  1360     Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
       
  1361     if (argCount == 2) {
       
  1362         if (ctxt->argument(1).isString()) {
       
  1363             QString format = ctxt->argument(1).toString();
       
  1364             return engine->newVariant(qVariantFromValue(date.toString(format)));
       
  1365         } else if (ctxt->argument(1).isNumber()) {
       
  1366             enumFormat = Qt::DateFormat(ctxt->argument(1).toUInt32());
       
  1367         } else { 
       
  1368             return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
       
  1369         }
       
  1370     }
       
  1371     return engine->newVariant(qVariantFromValue(date.toString(enumFormat)));
       
  1372 }
       
  1373 
       
  1374 /*!
       
  1375 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
       
  1376 
       
  1377 This function returns a Color with the specified \c red, \c green, \c blue and \c alpha components.
       
  1378 All components should be in the range 0-1 inclusive.
       
  1379 */
       
  1380 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
       
  1381 {
       
  1382     int argCount = ctxt->argumentCount();
       
  1383     if(argCount < 3 || argCount > 4)
       
  1384         return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
       
  1385     qsreal r = ctxt->argument(0).toNumber();
       
  1386     qsreal g = ctxt->argument(1).toNumber();
       
  1387     qsreal b = ctxt->argument(2).toNumber();
       
  1388     qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
       
  1389 
       
  1390     if (r < 0.0) r=0.0;
       
  1391     if (r > 1.0) r=1.0;
       
  1392     if (g < 0.0) g=0.0;
       
  1393     if (g > 1.0) g=1.0;
       
  1394     if (b < 0.0) b=0.0;
       
  1395     if (b > 1.0) b=1.0;
       
  1396     if (a < 0.0) a=0.0;
       
  1397     if (a > 1.0) a=1.0;
       
  1398 
       
  1399     return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a)));
       
  1400 }
       
  1401 
       
  1402 /*!
       
  1403 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
       
  1404 
       
  1405 This function returns a Color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
       
  1406 All components should be in the range 0-1 inclusive.
       
  1407 */
       
  1408 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
       
  1409 {
       
  1410     int argCount = ctxt->argumentCount();
       
  1411     if(argCount < 3 || argCount > 4)
       
  1412         return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
       
  1413     qsreal h = ctxt->argument(0).toNumber();
       
  1414     qsreal s = ctxt->argument(1).toNumber();
       
  1415     qsreal l = ctxt->argument(2).toNumber();
       
  1416     qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
       
  1417 
       
  1418     if (h < 0.0) h=0.0;
       
  1419     if (h > 1.0) h=1.0;
       
  1420     if (s < 0.0) s=0.0;
       
  1421     if (s > 1.0) s=1.0;
       
  1422     if (l < 0.0) l=0.0;
       
  1423     if (l > 1.0) l=1.0;
       
  1424     if (a < 0.0) a=0.0;
       
  1425     if (a > 1.0) a=1.0;
       
  1426 
       
  1427     return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a)));
       
  1428 }
       
  1429 
       
  1430 /*!
       
  1431 \qmlmethod rect Qt::rect(int x, int y, int width, int height) 
       
  1432 
       
  1433 This function returns a Rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
       
  1434 */
       
  1435 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
       
  1436 {
       
  1437     if(ctxt->argumentCount() != 4)
       
  1438         return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
       
  1439 
       
  1440     qsreal x = ctxt->argument(0).toNumber();
       
  1441     qsreal y = ctxt->argument(1).toNumber();
       
  1442     qsreal w = ctxt->argument(2).toNumber();
       
  1443     qsreal h = ctxt->argument(3).toNumber();
       
  1444 
       
  1445     if (w < 0 || h < 0)
       
  1446         return engine->nullValue();
       
  1447 
       
  1448     return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QRectF(x, y, w, h)));
       
  1449 }
       
  1450 
       
  1451 /*!
       
  1452 \qmlmethod point Qt::point(int x, int y)
       
  1453 This function returns a Point with the specified \c x and \c y coordinates.
       
  1454 */
       
  1455 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
       
  1456 {
       
  1457     if(ctxt->argumentCount() != 2)
       
  1458         return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
       
  1459     qsreal x = ctxt->argument(0).toNumber();
       
  1460     qsreal y = ctxt->argument(1).toNumber();
       
  1461     return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QPointF(x, y)));
       
  1462 }
       
  1463 
       
  1464 /*!
       
  1465 \qmlmethod Qt::size(int width, int height)
       
  1466 This function returns as Size with the specified \c width and \c height.
       
  1467 */
       
  1468 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
       
  1469 {
       
  1470     if(ctxt->argumentCount() != 2)
       
  1471         return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
       
  1472     qsreal w = ctxt->argument(0).toNumber();
       
  1473     qsreal h = ctxt->argument(1).toNumber();
       
  1474     return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(qVariantFromValue(QSizeF(w, h)));
       
  1475 }
       
  1476 
       
  1477 /*!
       
  1478 \qmlmethod color Qt::lighter(color baseColor, real factor)
       
  1479 This function returns a color lighter than \c baseColor by the \c factor provided.
       
  1480 
       
  1481 If the factor is greater than 1.0, this functions returns a lighter color.
       
  1482 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
       
  1483 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
       
  1484 If the factor is 0 or negative, the return value is unspecified.
       
  1485 
       
  1486 The function converts the current RGB color to HSV, multiplies the value (V) component
       
  1487 by factor and converts the color back to RGB.
       
  1488 
       
  1489 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
       
  1490 */
       
  1491 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
       
  1492 {
       
  1493     if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
       
  1494         return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
       
  1495     QVariant v = ctxt->argument(0).toVariant();
       
  1496     QColor color;
       
  1497     if (v.userType() == QVariant::Color)
       
  1498         color = v.value<QColor>();
       
  1499     else if (v.userType() == QVariant::String) {
       
  1500         bool ok;
       
  1501         color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
       
  1502         if (!ok)
       
  1503             return engine->nullValue();
       
  1504     } else
       
  1505         return engine->nullValue();
       
  1506     qsreal factor = 1.5;
       
  1507     if (ctxt->argumentCount() == 2)
       
  1508         factor = ctxt->argument(1).toNumber();
       
  1509     color = color.lighter(int(qRound(factor*100.)));
       
  1510     return qScriptValueFromValue(engine, qVariantFromValue(color));
       
  1511 }
       
  1512 
       
  1513 /*!
       
  1514 \qmlmethod color Qt::darker(color baseColor, real factor)
       
  1515 This function returns a color darker than \c baseColor by the \c factor provided.
       
  1516 
       
  1517 If the factor is greater than 1.0, this function returns a darker color.
       
  1518 Setting factor to 3.0 returns a color that has one-third the brightness.
       
  1519 If the factor is less than 1.0, the return color is lighter, but we recommend using
       
  1520 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
       
  1521 value is unspecified.
       
  1522 
       
  1523 The function converts the current RGB color to HSV, divides the value (V) component
       
  1524 by factor and converts the color back to RGB.
       
  1525 
       
  1526 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
       
  1527 */
       
  1528 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
       
  1529 {
       
  1530     if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
       
  1531         return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
       
  1532     QVariant v = ctxt->argument(0).toVariant();
       
  1533     QColor color;
       
  1534     if (v.userType() == QVariant::Color)
       
  1535         color = v.value<QColor>();
       
  1536     else if (v.userType() == QVariant::String) {
       
  1537         bool ok;
       
  1538         color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
       
  1539         if (!ok)
       
  1540             return engine->nullValue();
       
  1541     } else
       
  1542         return engine->nullValue();
       
  1543     qsreal factor = 2.0;
       
  1544     if (ctxt->argumentCount() == 2)
       
  1545         factor = ctxt->argument(1).toNumber();
       
  1546     color = color.darker(int(qRound(factor*100.)));
       
  1547     return qScriptValueFromValue(engine, qVariantFromValue(color));
       
  1548 }
       
  1549 
       
  1550 /*!
       
  1551 \qmlmethod bool Qt::openUrlExternally(url target)
       
  1552 This function attempts to open the specified \c target url in an external application, based on the user's desktop preferences. It will return true if it succeeds, and false otherwise.
       
  1553 */
       
  1554 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
       
  1555 {
       
  1556     if(ctxt->argumentCount() < 1)
       
  1557         return QScriptValue(e, false);
       
  1558     bool ret = false;
       
  1559 #ifndef QT_NO_DESKTOPSERVICES
       
  1560     ret = QDesktopServices::openUrl(QUrl(ctxt->argument(0).toString()));
       
  1561 #endif
       
  1562     return QScriptValue(e, ret);
       
  1563 }
       
  1564 
       
  1565 /*!
       
  1566 \qmlmethod list<string> Qt::fontFamilies()
       
  1567 This function returns a list of the font families available to the application.
       
  1568 */
       
  1569 
       
  1570 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
       
  1571 {
       
  1572     if(ctxt->argumentCount() != 0)
       
  1573         return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
       
  1574 
       
  1575     QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
       
  1576     QFontDatabase database;
       
  1577     return p->scriptValueFromVariant(database.families());
       
  1578 }
       
  1579 
       
  1580 /*!
       
  1581 \qmlmethod string Qt::md5(data)
       
  1582 This function returns a hex string of the md5 hash of \c data.
       
  1583 */
       
  1584 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
       
  1585 {
       
  1586     if (ctxt->argumentCount() != 1)
       
  1587         return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
       
  1588 
       
  1589     QByteArray data = ctxt->argument(0).toString().toUtf8();
       
  1590     QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
       
  1591 
       
  1592     return QScriptValue(QLatin1String(result.toHex()));
       
  1593 }
       
  1594 
       
  1595 /*!
       
  1596 \qmlmethod string Qt::btoa(data)
       
  1597 Binary to ASCII - this function returns a base64 encoding of \c data.
       
  1598 */
       
  1599 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
       
  1600 {
       
  1601     if (ctxt->argumentCount() != 1) 
       
  1602         return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
       
  1603 
       
  1604     QByteArray data = ctxt->argument(0).toString().toUtf8();
       
  1605 
       
  1606     return QScriptValue(QLatin1String(data.toBase64()));
       
  1607 }
       
  1608 
       
  1609 /*!
       
  1610 \qmlmethod string Qt::atob(data)
       
  1611 ASCII to binary - this function returns a base64 decoding of \c data.
       
  1612 */
       
  1613 
       
  1614 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
       
  1615 {
       
  1616     if (ctxt->argumentCount() != 1) 
       
  1617         return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
       
  1618 
       
  1619     QByteArray data = ctxt->argument(0).toString().toUtf8();
       
  1620 
       
  1621     return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
       
  1622 }
       
  1623 
       
  1624 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
       
  1625 {
       
  1626     if(ctxt->argumentCount() < 1)
       
  1627         return e->newVariant(QVariant(false));
       
  1628 
       
  1629     QByteArray msg;
       
  1630 
       
  1631     for (int i=0; i<ctxt->argumentCount(); ++i) {
       
  1632         if (!msg.isEmpty()) msg += ' ';
       
  1633         msg += ctxt->argument(i).toString().toLocal8Bit();
       
  1634         // does not support firebug "%[a-z]" formatting, since firebug really
       
  1635         // does just ignore the format letter, which makes it pointless.
       
  1636     }
       
  1637 
       
  1638     qDebug("%s",msg.constData());
       
  1639 
       
  1640     return e->newVariant(QVariant(true));
       
  1641 }
       
  1642 
       
  1643 void QDeclarativeEnginePrivate::sendQuit()
       
  1644 {
       
  1645     Q_Q(QDeclarativeEngine);
       
  1646     emit q->quit();
       
  1647 }
       
  1648 
       
  1649 static void dumpwarning(const QDeclarativeError &error)
       
  1650 {
       
  1651     qWarning().nospace() << qPrintable(error.toString());
       
  1652 }
       
  1653 
       
  1654 static void dumpwarning(const QList<QDeclarativeError> &errors)
       
  1655 {
       
  1656     for (int ii = 0; ii < errors.count(); ++ii)
       
  1657         dumpwarning(errors.at(ii));
       
  1658 }
       
  1659 
       
  1660 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
       
  1661 {
       
  1662     Q_Q(QDeclarativeEngine);
       
  1663     q->warnings(QList<QDeclarativeError>() << error);
       
  1664     if (outputWarningsToStdErr)
       
  1665         dumpwarning(error);
       
  1666 }
       
  1667 
       
  1668 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
       
  1669 {
       
  1670     Q_Q(QDeclarativeEngine);
       
  1671     q->warnings(errors);
       
  1672     if (outputWarningsToStdErr)
       
  1673         dumpwarning(errors);
       
  1674 }
       
  1675 
       
  1676 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
       
  1677 {
       
  1678     if (engine)
       
  1679         QDeclarativeEnginePrivate::get(engine)->warning(error);
       
  1680     else
       
  1681         dumpwarning(error);
       
  1682 }
       
  1683 
       
  1684 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
       
  1685 {
       
  1686     if (engine)
       
  1687         QDeclarativeEnginePrivate::get(engine)->warning(error);
       
  1688     else
       
  1689         dumpwarning(error);
       
  1690 }
       
  1691 
       
  1692 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
       
  1693 {
       
  1694     if (engine)
       
  1695         engine->warning(error);
       
  1696     else
       
  1697         dumpwarning(error);
       
  1698 }
       
  1699 
       
  1700 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
       
  1701 {
       
  1702     if (engine)
       
  1703         engine->warning(error);
       
  1704     else
       
  1705         dumpwarning(error);
       
  1706 }
       
  1707 
       
  1708 /*!
       
  1709 \qmlmethod Qt::quit()
       
  1710 This function causes the QDeclarativeEngine::quit() signal to be emitted.
       
  1711 Within the \l {Qt Declarative UI Runtime}{qml} application this causes the 
       
  1712 launcher application to exit.
       
  1713 */
       
  1714 
       
  1715 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
       
  1716 {
       
  1717     QDeclarativeEnginePrivate *qe = get (e);
       
  1718     qe->sendQuit();
       
  1719     return QScriptValue();
       
  1720 }
       
  1721 
       
  1722 /*!
       
  1723 \qmlmethod color Qt::tint(color baseColor, color tintColor)
       
  1724     This function allows tinting one color with another.
       
  1725 
       
  1726     The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque.
       
  1727 
       
  1728     \qml
       
  1729     Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" }
       
  1730     Rectangle { x: 100; width: 80; height: 80; color: Qt.tint("lightsteelblue", "#10FF0000") }
       
  1731     \endqml
       
  1732     \image declarative-rect_tint.png
       
  1733 
       
  1734     Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
       
  1735 */
       
  1736 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
       
  1737 {
       
  1738     if(ctxt->argumentCount() != 2)
       
  1739         return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
       
  1740     //get color
       
  1741     QVariant v = ctxt->argument(0).toVariant();
       
  1742     QColor color;
       
  1743     if (v.userType() == QVariant::Color)
       
  1744         color = v.value<QColor>();
       
  1745     else if (v.userType() == QVariant::String) {
       
  1746         bool ok;
       
  1747         color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
       
  1748         if (!ok)
       
  1749             return engine->nullValue();
       
  1750     } else
       
  1751         return engine->nullValue();
       
  1752 
       
  1753     //get tint color
       
  1754     v = ctxt->argument(1).toVariant();
       
  1755     QColor tintColor;
       
  1756     if (v.userType() == QVariant::Color)
       
  1757         tintColor = v.value<QColor>();
       
  1758     else if (v.userType() == QVariant::String) {
       
  1759         bool ok;
       
  1760         tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
       
  1761         if (!ok)
       
  1762             return engine->nullValue();
       
  1763     } else
       
  1764         return engine->nullValue();
       
  1765 
       
  1766     //tint
       
  1767     QColor finalColor;
       
  1768     int a = tintColor.alpha();
       
  1769     if (a == 0xFF)
       
  1770         finalColor = tintColor;
       
  1771     else if (a == 0x00)
       
  1772         finalColor = color;
       
  1773     else {
       
  1774         qreal a = tintColor.alphaF();
       
  1775         qreal inv_a = 1.0 - a;
       
  1776 
       
  1777         finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
       
  1778                            tintColor.greenF() * a + color.greenF() * inv_a,
       
  1779                            tintColor.blueF() * a + color.blueF() * inv_a,
       
  1780                            a + inv_a * color.alphaF());
       
  1781     }
       
  1782 
       
  1783     return qScriptValueFromValue(engine, qVariantFromValue(finalColor));
       
  1784 }
       
  1785 
       
  1786 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
       
  1787 {
       
  1788     if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
       
  1789         QDeclarativeListReferencePrivate *p =
       
  1790             QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
       
  1791         if (p->object) {
       
  1792             return listClass->newList(p->property, p->propertyType);
       
  1793         } else {
       
  1794             return scriptEngine.nullValue();
       
  1795         }
       
  1796     } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
       
  1797         const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
       
  1798         QScriptValue rv = scriptEngine.newArray(list.count());
       
  1799         for (int ii = 0; ii < list.count(); ++ii) {
       
  1800             QObject *object = list.at(ii);
       
  1801             rv.setProperty(ii, objectClass->newQObject(object));
       
  1802         }
       
  1803         return rv;
       
  1804     } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
       
  1805         return valueTypeClass->newObject(val, vt);
       
  1806     }
       
  1807 
       
  1808     bool objOk;
       
  1809     QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
       
  1810     if (objOk) {
       
  1811         return objectClass->newQObject(obj);
       
  1812     } else {
       
  1813         return qScriptValueFromValue(&scriptEngine, val);
       
  1814     }
       
  1815 }
       
  1816 
       
  1817 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
       
  1818 {
       
  1819     QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
       
  1820     if (dc == objectClass)
       
  1821         return QVariant::fromValue(objectClass->toQObject(val));
       
  1822     else if (dc == valueTypeClass)
       
  1823         return valueTypeClass->toVariant(val);
       
  1824     else if (dc == contextClass)
       
  1825         return QVariant();
       
  1826 
       
  1827     // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
       
  1828     if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
       
  1829         QList<QObject *> list;
       
  1830         int length = val.property(QLatin1String("length")).toInt32();
       
  1831         for (int ii = 0; ii < length; ++ii) {
       
  1832             QScriptValue arrayItem = val.property(ii);
       
  1833             QObject *d = arrayItem.toQObject();
       
  1834             list << d;
       
  1835         }
       
  1836         return QVariant::fromValue(list);
       
  1837     }
       
  1838 
       
  1839     return val.toVariant();
       
  1840 }
       
  1841 
       
  1842 /*!
       
  1843   Adds \a path as a directory where the engine searches for
       
  1844   installed modules in a URL-based directory structure.
       
  1845 
       
  1846   The newly added \a path will be first in the importPathList().
       
  1847 
       
  1848   \sa setImportPathList()
       
  1849 */
       
  1850 void QDeclarativeEngine::addImportPath(const QString& path)
       
  1851 {
       
  1852     Q_D(QDeclarativeEngine);
       
  1853     d->importDatabase.addImportPath(path);
       
  1854 }
       
  1855 
       
  1856 /*!
       
  1857   Returns the list of directories where the engine searches for
       
  1858   installed modules in a URL-based directory structure.
       
  1859 
       
  1860   For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
       
  1861   imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
       
  1862   in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
       
  1863   provided by that module. A \c qmldir file is required for defining the
       
  1864   type version mapping and possibly declarative extensions plugins.
       
  1865 
       
  1866   By default, the list contains the directory of the application executable,
       
  1867   paths specified in the \c QML_IMPORT_PATH environment variable,
       
  1868   and the builtin \c ImportsPath from QLibraryInfo.
       
  1869 
       
  1870   \sa addImportPath() setImportPathList()
       
  1871 */
       
  1872 QStringList QDeclarativeEngine::importPathList() const
       
  1873 {
       
  1874     Q_D(const QDeclarativeEngine);
       
  1875     return d->importDatabase.importPathList();
       
  1876 }
       
  1877 
       
  1878 /*!
       
  1879   Sets \a paths as the list of directories where the engine searches for
       
  1880   installed modules in a URL-based directory structure.
       
  1881 
       
  1882   By default, the list contains the directory of the application executable,
       
  1883   paths specified in the \c QML_IMPORT_PATH environment variable,
       
  1884   and the builtin \c ImportsPath from QLibraryInfo.
       
  1885 
       
  1886   \sa importPathList() addImportPath()
       
  1887   */
       
  1888 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
       
  1889 {
       
  1890     Q_D(QDeclarativeEngine);
       
  1891     d->importDatabase.setImportPathList(paths);
       
  1892 }
       
  1893 
       
  1894 
       
  1895 /*!
       
  1896   Adds \a path as a directory where the engine searches for
       
  1897   native plugins for imported modules (referenced in the \c qmldir file).
       
  1898 
       
  1899   By default, the list contains only \c .,  i.e. the engine searches
       
  1900   in the directory of the \c qmldir file itself.
       
  1901 
       
  1902   The newly added \a path will be first in the pluginPathList().
       
  1903 
       
  1904   \sa setPluginPathList()
       
  1905 */
       
  1906 void QDeclarativeEngine::addPluginPath(const QString& path)
       
  1907 {
       
  1908     Q_D(QDeclarativeEngine);
       
  1909     d->importDatabase.addPluginPath(path);
       
  1910 }
       
  1911 
       
  1912 
       
  1913 /*!
       
  1914   Returns the list of directories where the engine searches for
       
  1915   native plugins for imported modules (referenced in the \c qmldir file).
       
  1916 
       
  1917   By default, the list contains only \c .,  i.e. the engine searches
       
  1918   in the directory of the \c qmldir file itself.
       
  1919 
       
  1920   \sa addPluginPath() setPluginPathList()
       
  1921 */
       
  1922 QStringList QDeclarativeEngine::pluginPathList() const
       
  1923 {
       
  1924     Q_D(const QDeclarativeEngine);
       
  1925     return d->importDatabase.pluginPathList();
       
  1926 }
       
  1927 
       
  1928 /*!
       
  1929   Sets the list of directories where the engine searches for
       
  1930   native plugins for imported modules (referenced in the \c qmldir file)
       
  1931   to \a paths.
       
  1932 
       
  1933   By default, the list contains only \c .,  i.e. the engine searches
       
  1934   in the directory of the \c qmldir file itself.
       
  1935 
       
  1936   \sa pluginPathList() addPluginPath()
       
  1937   */
       
  1938 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
       
  1939 {
       
  1940     Q_D(QDeclarativeEngine);
       
  1941     d->importDatabase.setPluginPathList(paths);
       
  1942 }
       
  1943 
       
  1944 
       
  1945 /*!
       
  1946   Imports the plugin named \a filePath with the \a uri provided.
       
  1947   Returns true if the plugin was successfully imported; otherwise returns false.
       
  1948 
       
  1949   On failure and if non-null, *\a errorString will be set to a message describing the failure.
       
  1950 
       
  1951   The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
       
  1952 */
       
  1953 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
       
  1954 {
       
  1955     Q_D(QDeclarativeEngine);
       
  1956     return d->importDatabase.importPlugin(filePath, uri, errorString);
       
  1957 }
       
  1958 
       
  1959 /*!
       
  1960   \property QDeclarativeEngine::offlineStoragePath
       
  1961   \brief the directory for storing offline user data
       
  1962 
       
  1963   Returns the directory where SQL and other offline
       
  1964   storage is placed.
       
  1965 
       
  1966   QDeclarativeWebView and the SQL databases created with openDatabase()
       
  1967   are stored here.
       
  1968 
       
  1969   The default is QML/OfflineStorage in the platform-standard
       
  1970   user application data directory.
       
  1971 
       
  1972   Note that the path may not currently exist on the filesystem, so
       
  1973   callers wanting to \e create new files at this location should create
       
  1974   it first - see QDir::mkpath().
       
  1975 */
       
  1976 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
       
  1977 {
       
  1978     Q_D(QDeclarativeEngine);
       
  1979     d->scriptEngine.offlineStoragePath = dir;
       
  1980 }
       
  1981 
       
  1982 QString QDeclarativeEngine::offlineStoragePath() const
       
  1983 {
       
  1984     Q_D(const QDeclarativeEngine);
       
  1985     return d->scriptEngine.offlineStoragePath;
       
  1986 }
       
  1987 
       
  1988 static void voidptr_destructor(void *v)
       
  1989 {
       
  1990     void **ptr = (void **)v;
       
  1991     delete ptr;
       
  1992 }
       
  1993 
       
  1994 static void *voidptr_constructor(const void *v)
       
  1995 {
       
  1996     if (!v) {
       
  1997         return new void*;
       
  1998     } else {
       
  1999         return new void*(*(void **)v);
       
  2000     }
       
  2001 }
       
  2002 
       
  2003 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
       
  2004 {
       
  2005     QByteArray name = data->root->className();
       
  2006 
       
  2007     QByteArray ptr = name + '*';
       
  2008     QByteArray lst = "QDeclarativeListProperty<" + name + ">";
       
  2009 
       
  2010     int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
       
  2011                                            voidptr_constructor);
       
  2012     int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
       
  2013                                            voidptr_constructor);
       
  2014 
       
  2015     m_qmlLists.insert(lst_type, ptr_type);
       
  2016     m_compositeTypes.insert(ptr_type, data);
       
  2017     data->addref();
       
  2018 }
       
  2019 
       
  2020 bool QDeclarativeEnginePrivate::isList(int t) const
       
  2021 {
       
  2022     return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
       
  2023 }
       
  2024 
       
  2025 int QDeclarativeEnginePrivate::listType(int t) const
       
  2026 {
       
  2027     QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
       
  2028     if (iter != m_qmlLists.end())
       
  2029         return *iter;
       
  2030     else
       
  2031         return QDeclarativeMetaType::listType(t);
       
  2032 }
       
  2033 
       
  2034 bool QDeclarativeEnginePrivate::isQObject(int t)
       
  2035 {
       
  2036     return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
       
  2037 }
       
  2038 
       
  2039 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
       
  2040 {
       
  2041     int t = v.userType();
       
  2042     if (m_compositeTypes.contains(t)) {
       
  2043         if (ok) *ok = true;
       
  2044         return *(QObject **)(v.constData());
       
  2045     } else {
       
  2046         return QDeclarativeMetaType::toQObject(v, ok);
       
  2047     }
       
  2048 }
       
  2049 
       
  2050 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
       
  2051 {
       
  2052     if (m_compositeTypes.contains(t))
       
  2053         return QDeclarativeMetaType::Object;
       
  2054     else if (m_qmlLists.contains(t))
       
  2055         return QDeclarativeMetaType::List;
       
  2056     else
       
  2057         return QDeclarativeMetaType::typeCategory(t);
       
  2058 }
       
  2059 
       
  2060 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
       
  2061 {
       
  2062     QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
       
  2063     if (iter != m_compositeTypes.end()) {
       
  2064         return (*iter)->root;
       
  2065     } else {
       
  2066         QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
       
  2067         return type?type->baseMetaObject():0;
       
  2068     }
       
  2069 }
       
  2070 
       
  2071 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
       
  2072 {
       
  2073     QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
       
  2074     if (iter != m_compositeTypes.end()) {
       
  2075         return (*iter)->root;
       
  2076     } else {
       
  2077         QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
       
  2078         return type?type->metaObject():0;
       
  2079     }
       
  2080 }
       
  2081 
       
  2082 QT_END_NAMESPACE