source: trunk/src/declarative/qml/qdeclarativeengine.cpp@ 1147

Last change on this file since 1147 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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