diff options
57 files changed, 816 insertions, 154 deletions
@@ -83,7 +83,7 @@ bin/kmap2qmap* bin/qlalr* bin/qmlconv* bin/qmldebugger* -bin/qmlviewer* +bin/qml* bin/qttracereplay* configure.cache config.status @@ -356,12 +356,13 @@ sub fixPaths { #setup my $ret = $file; + $ret =~ s,/cygdrive/([a-zA-Z])/,$1:/,g; my $file_dir = dirname($file); if($file_dir eq ".") { $file_dir = getcwd(); $file_dir =~ s=\\=/=g; } - $file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:,g; + $file_dir =~ s,/cygdrive/([a-zA-Z])/,$1:/,g; if($dir eq ".") { $dir = getcwd(); $dir =~ s=\\=/=g; diff --git a/demos/interview/model.cpp b/demos/interview/model.cpp index 3f9548a..840bc60 100644 --- a/demos/interview/model.cpp +++ b/demos/interview/model.cpp @@ -45,6 +45,7 @@ Model::Model(int rows, int columns, QObject *parent) : QAbstractItemModel(parent), + services(QPixmap(":/images/services.png")), rc(rows), cc(columns), tree(new QVector<Node>(rows, Node(0))) { @@ -105,7 +106,6 @@ QVariant Model::data(const QModelIndex &index, int role) const QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const { - static QIcon services(QPixmap(":/images/services.png")); if (role == Qt::DisplayRole) return QString::number(section); if (role == Qt::DecorationRole) diff --git a/demos/interview/model.h b/demos/interview/model.h index bad83a8..c7c15f7 100644 --- a/demos/interview/model.h +++ b/demos/interview/model.h @@ -44,6 +44,7 @@ #include <QAbstractItemModel> #include <QFileIconProvider> +#include <QIcon> #include <QVector> class Model : public QAbstractItemModel @@ -80,6 +81,7 @@ private: Node *parent(Node *child) const; int row(Node *node) const; + QIcon services; int rc, cc; QVector<Node> *tree; QFileIconProvider iconProvider; diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 1fd4dad..6cca39b 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -91,6 +91,7 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l VisualDataModel \o \l Package \o \l XmlListModel and XmlRole +\o \l WorkerListModel \o \l DateTimeFormatter \o \l NumberFormatter \endlist @@ -102,6 +103,7 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l Component \o \l Timer \o \l QtObject +\o \l WorkerScript \endlist \endtable diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index cf53df0..c670c51 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -473,6 +473,29 @@ \section1 Declarative UI development with Qt Quick + Qt 4.7 introduces Quick, the Qt UI Creation Kit. that enables the creation + of dynamic user interfaces, easier and more effective than possible + with existing UI technologies. This UI Creation Kit consist of three + technologies: + + \list + \i QML is a declarative language oriented on JavaScript that utilizes + Qt's Meta-Object capabilities to enable designers and developers to + collaborate tightly and create animated and fluid user experiences, + using existing knowledge in script language and design. + + \i QtDeclarative is a C++ library that provides the underlying engine, + which translates the declarative description of the UI in QML into + items on a QGraphicsScene. The library also provides APIs to bind + custom C++ types and elements to QML, and to connect the QML UI with + the underlying application logic written in C++. + + \i Qt Creator has been improved to support interactive editing of + QML UIs through drag-and-drop. The text editor supports the QML + syntax and provides authoring assistance such as auto-completion, + error lookup, help lookup and easy preview of QML UI's. + \endlist + \section1 Network Bearer Management Bearer Management controls the connectivity state of the system. @@ -494,7 +517,7 @@ \section1 New Classes, Functions, Macros, etc. - Links to new classes, functions, macros, and other items + Links to new classes, elements, functions, macros, and other items introduced in Qt 4.7. \sincelist 4.7 diff --git a/examples/declarative/workerlistmodel/dataloader.js b/examples/declarative/workerlistmodel/dataloader.js new file mode 100644 index 0000000..eac7478 --- /dev/null +++ b/examples/declarative/workerlistmodel/dataloader.js @@ -0,0 +1,14 @@ +// ![0] +WorkerScript.onMessage = function(msg) { + console.log("Worker told to", msg.action); + + if (msg.action == 'appendCurrentTime') { + var data = {'time': new Date().toTimeString()}; + msg.model.append(data); + msg.model.sync(); // updates the changes to the list + + var msgToSend = {'msg': 'Model updated!'}; + WorkerScript.sendMessage(msgToSend); + } +} +// ![0] diff --git a/examples/declarative/workerlistmodel/timedisplay.qml b/examples/declarative/workerlistmodel/timedisplay.qml new file mode 100644 index 0000000..3bf2630 --- /dev/null +++ b/examples/declarative/workerlistmodel/timedisplay.qml @@ -0,0 +1,33 @@ +// ![0] +import Qt 4.6 + +ListView { + width: 200 + height: 300 + + model: listModel + delegate: Component { + Text { text: time } + } + + WorkerListModel { id: listModel } + + WorkerScript { + id: worker + source: "dataloader.js" + onMessage: { + console.log("Worker said", messageObject.msg); + } + } + + Timer { + id: timer + interval: 2000; repeat: true; running: true; triggeredOnStart: true + + onTriggered: { + var msg = {'action': 'appendCurrentTime', 'model': listModel}; + worker.sendMessage(msg); + } + } +} +// ![0] diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index ec4ba2f..222ba8f 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -243,6 +243,7 @@ QDataStream& operator>>(QDataStream& s, QList<T>& l) l.clear(); quint32 c; s >> c; + l.reserve(c); for(quint32 i = 0; i < c; ++i) { T t; diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index be1b2ae..ecffe99 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1137,8 +1137,11 @@ bool QMetaObject::invokeMethod(QObject *obj, idx = obj->metaObject()->indexOfMethod(norm.constData()); } - if (idx < 0 || idx >= obj->metaObject()->methodCount()) + if (idx < 0 || idx >= obj->metaObject()->methodCount()) { + qWarning("QMetaObject::invokeMethod: No such method %s::%s", + obj->metaObject()->className(), sig.constData()); return false; + } QMetaMethod method = obj->metaObject()->method(idx); return method.invoke(obj, type, ret, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index bfc65bc..550ff58 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -158,7 +158,7 @@ namespace QtSharedPointer { #if defined(Q_NO_TEMPLATE_FRIENDS) public: #else - template <class X> friend class QWeakPointer; + template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer); #endif Type *value; @@ -402,7 +402,7 @@ namespace QtSharedPointer { public: #else template <class X> friend class ExternalRefCount; - template <class X> friend class QWeakPointer; + template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer); template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src); #endif diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 44c1798..724f3e0 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -116,11 +116,10 @@ enum CPUFeatures { NEON = 0x100 }; +Q_CORE_EXPORT uint qDetectCPUFeatures(); QT_END_NAMESPACE QT_END_HEADER -Q_CORE_EXPORT uint qDetectCPUFeatures(); - #endif // QSIMD_P_H diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index a7376cc..090c46d 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -45,6 +45,7 @@ #include "qdeclarativeflickable_p_p.h" #include <qdeclarativeeasefollow_p.h> +#include <qdeclarativeguard_p.h> #include <qlistmodelinterface_p.h> #include <QKeyEvent> @@ -251,7 +252,7 @@ public: } } - QGuard<QDeclarativeVisualModel> model; + QDeclarativeGuard<QDeclarativeVisualModel> model; QVariant modelVariant; QList<FxGridItem*> visibleItems; QHash<QDeclarativeItem*,int> unrequestedItems; diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 99ab053..2739ab8 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -232,6 +232,16 @@ qreal QDeclarativeImage::paintedHeight() const \o Error - an error occurred while loading the image \endlist + Note that a change in the status property does not cause anything to happen + (although it reflects what has happened with the image internally). If you wish + to react to the change in status you need to do it yourself, for example in one + of the following ways: + \list + \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: image.status = Image.Ready;} + \o Do something inside the onStatusChanged signal handler, e.g. Image{id: image; onStatusChanged: if(image.status == Image.Ready) console.log('Loaded');} + \o Bind to the status variable somewhere, e.g. Text{text: if(image.status!=Image.Ready){'Not Loaded';}else{'Loaded';}} + \endlist + \sa progress */ diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index e7fff90..a05e638 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -47,6 +47,7 @@ #include <qdeclarativeeasefollow_p.h> #include <qdeclarativeexpression.h> #include <qdeclarativeengine.h> +#include <qdeclarativeguard_p.h> #include <qlistmodelinterface_p.h> #include <QKeyEvent> @@ -429,7 +430,7 @@ public: virtual void flickX(qreal velocity); virtual void flickY(qreal velocity); - QGuard<QDeclarativeVisualModel> model; + QDeclarativeGuard<QDeclarativeVisualModel> model; QVariant modelVariant; QList<FxListItem*> visibleItems; QHash<QDeclarativeItem*,int> unrequestedItems; diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index bd89321..b0499d7 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -320,6 +320,15 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() \o Error - an error occurred while loading the QML source \endlist + Note that a change in the status property does not cause anything to happen + (although it reflects what has happened to the loader internally). If you wish + to react to the change in status you need to do it yourself, for example in one + of the following ways: + \list + \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: loader.status = Loader.Ready;} + \o Do something inside the onStatusChanged signal handler, e.g. Loader{id: loader; onStatusChanged: if(loader.status == Loader.Ready) console.log('Loaded');} + \o Bind to the status variable somewhere, e.g. Text{text: if(loader.status!=Loader.Ready){'Not Loaded';}else{'Loaded';}} + \endlist \sa progress */ diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index ca50910..6344a8a 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -60,6 +60,7 @@ #include <qdeclarative.h> #include <qdeclarativeanimation_p_p.h> +#include <qdeclarativeguard_p.h> #include <qdatetime.h> @@ -132,7 +133,7 @@ public: int pathOffset; int requestedIndex; QList<QDeclarativeItem *> items; - QGuard<QDeclarativeVisualModel> model; + QDeclarativeGuard<QDeclarativeVisualModel> model; QVariant modelVariant; enum MovementReason { Other, Key, Mouse }; MovementReason moveReason; diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 8e44b26..be73b39 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -613,6 +613,11 @@ void QDeclarativeTextEdit::setPersistentSelection(bool on) emit persistentSelectionChanged(d->persistentSelection); } +/* + \qmlproperty number TextEdit::textMargin + + The margin, in pixels, around the text in the TextEdit. +*/ qreal QDeclarativeTextEdit::textMargin() const { Q_D(const QDeclarativeTextEdit); diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index cd72ef9..a0aed46 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -53,6 +53,7 @@ #include <qdeclarativedeclarativedata_p.h> #include <qdeclarativepropertycache_p.h> #include <qdeclarativeguard_p.h> +#include <qdeclarativeglobal_p.h> #include <qlistmodelinterface_p.h> #include <qhash.h> @@ -80,6 +81,14 @@ public: static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->emitChildrenChanged(); } + static int children_count(QDeclarativeListProperty<QDeclarativeItem> *prop) { + return static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.count(); + } + + static QDeclarativeItem *children_at(QDeclarativeListProperty<QDeclarativeItem> *prop, int index) { + return static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.at(index); + } + void itemAppended() { Q_Q(QDeclarativeVisualItemModel); QDeclarativeVisualItemModelAttached *attached = QDeclarativeVisualItemModelAttached::properties(children.last()); @@ -135,7 +144,8 @@ QDeclarativeVisualItemModel::QDeclarativeVisualItemModel() QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children() { Q_D(QDeclarativeVisualItemModel); - return QDeclarativeListProperty<QDeclarativeItem>(this, d, QDeclarativeVisualItemModelPrivate::children_append); + return QDeclarativeListProperty<QDeclarativeItem>(this, d, d->children_append, + d->children_count, d->children_at); } /*! @@ -984,8 +994,8 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray if (complete) d->m_delegate->completeCreate(); if (nobj) { - ctxt->setParent(nobj); - data->setParent(nobj); + QDeclarative_setParent_noEvent(ctxt, nobj); + QDeclarative_setParent_noEvent(data, nobj); d->m_cache.insertItem(index, nobj); if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(nobj)) emit createdPackage(index, package); @@ -1268,7 +1278,6 @@ void QDeclarativeVisualDataModel::_q_dataChanged(const QModelIndex &begin, const void QDeclarativeVisualDataModel::_q_modelReset() { - Q_D(QDeclarativeVisualDataModel); emit modelReset(); } diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index f66b9c7..ec5809d 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -130,8 +130,9 @@ protected: private: Q_DECLARE_PRIVATE(QDeclarativeBinding) }; -Q_DECLARE_METATYPE(QDeclarativeBinding*); QT_END_NAMESPACE +Q_DECLARE_METATYPE(QDeclarativeBinding*); + #endif // QDECLARATIVEBINDING_P_H diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 08b47b7..fea59e5 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -155,9 +155,9 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj int parenIdx = methodName.indexOf(QLatin1Char('(')); Q_ASSERT(parenIdx != -1); - methodName = methodName.left(parenIdx); + QStringRef methodNameRef = methodName.leftRef(parenIdx); - if (methodName == property) { + if (methodNameRef == property) { rv.load(m); return rv; } diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 03151e4..c1d090e 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -841,6 +841,41 @@ bool QDeclarativeWorkerListModelAgent::event(QEvent *e) return QObject::event(e); } +/*! + \qmlclass WorkerListModel QDeclarativeWorkerListModel + \brief The WorkerListModel element provides a threaded list model. + + Use WorkerListModel together with WorkerScript to define a list model + that is controlled by a separate thread. This is useful if list modification + operations are synchronous and take some time: using WorkerListModel + moves these operations to a different thread and avoids blocking of the + main GUI thread. + + The thread that creates the WorkerListModel can modify the model for any + initial set-up requirements. However, once the model has been modified by + the associated WorkerScript, the model can only be modified by that worker + script and becomes read-only to all other threads. + + Here is an example application that uses WorkerScript to append the + current time to a WorkerListModel: + + \snippet examples/declarative/workerlistmodel/timedisplay.qml 0 + + The included file, \tt dataloader.js, looks like this: + + \snippet examples/declarative/workerlistmodel/dataloader.js 0 + + The application's \tt Timer object periodically sends a message to the + worker script by calling \tt WorkerScript::sendMessage(). When this message + is received, \tt WorkerScript.onMessage() is invoked in + \tt dataloader.js, which appends the current time to the worker list + model. + + Note that unlike ListModel, WorkerListModel does not have \tt move() and + \tt setProperty() methods. + + \sa WorkerScript, ListModel +*/ QDeclarativeWorkerListModel::QDeclarativeWorkerListModel(QObject *parent) : QListModelInterface(parent), m_agent(0) { @@ -854,6 +889,14 @@ QDeclarativeWorkerListModel::~QDeclarativeWorkerListModel() } } +/*! + \qmlmethod WorkerListModel::clear() + + Deletes all content from the model. The properties are cleared such that + different properties may be set on subsequent additions. + + \sa append() remove() +*/ void QDeclarativeWorkerListModel::clear() { if (m_agent) { @@ -869,6 +912,13 @@ void QDeclarativeWorkerListModel::clear() } } +/*! + \qmlmethod WorkerListModel::remove(int index) + + Deletes the content at \a index from the model. + + \sa clear() +*/ void QDeclarativeWorkerListModel::remove(int index) { if (m_agent) { @@ -884,6 +934,18 @@ void QDeclarativeWorkerListModel::remove(int index) emit countChanged(); } +/*! + \qmlmethod WorkerListModel::append(jsobject dict) + + Adds a new item to the end of the list model, with the + values in \a dict. + + \code + FruitModel.append({"cost": 5.95, "name":"Pizza"}) + \endcode + + \sa set() remove() +*/ void QDeclarativeWorkerListModel::append(const QScriptValue &value) { if (m_agent) { @@ -914,6 +976,21 @@ void QDeclarativeWorkerListModel::append(const QScriptValue &value) emit countChanged(); } +/*! + \qmlmethod WorkerListModel::insert(int index, jsobject dict) + + Adds a new item to the list model at position \a index, with the + values in \a dict. + + \code + FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) + \endcode + + The \a index must be to an existing item in the list, or one past + the end of the list (equivalent to append). + + \sa set() append() +*/ void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value) { if (m_agent) { @@ -946,6 +1023,30 @@ void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value) emit countChanged(); } +/*! + \qmlmethod object ListModel::get(int index) + + Returns the item at \a index in the list model. + + \code + FruitModel.append({"cost": 5.95, "name":"Jackfruit"}) + FruitModel.get(0).cost + \endcode + + The \a index must be an element in the list. + + Note that properties of the returned object that are themselves objects + will also be models, and this get() method is used to access elements: + + \code + FruitModel.append(..., "attributes": + [{"name":"spikes","value":"7mm"}, + {"name":"color","value":"green"}]); + FruitModel.get(0).attributes.get(1).value; // == "green" + \endcode + + \sa append() +*/ QScriptValue QDeclarativeWorkerListModel::get(int index) const { QDeclarativeEngine *engine = qmlEngine(this); @@ -962,6 +1063,21 @@ QScriptValue QDeclarativeWorkerListModel::get(int index) const return rv; } +/*! + \qmlmethod WorkerListModel::set(int index, jsobject dict) + + Changes the item at \a index in the list model with the + values in \a dict. Properties not appearing in \a valuemap + are left unchanged. + + \code + FruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) + \endcode + + The \a index must be an element in the list. + + \sa append() +*/ void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value) { if (m_agent) { @@ -995,6 +1111,22 @@ void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value) } } +/*! + \qmlmethod WorkerListModel::sync() + + Writes any unsaved changes to the list model. This must be called after + changes have been made to the list model in the worker script. + + Note that this method can only be called from the associated worker script. +*/ +void QDeclarativeWorkerListModel::sync() +{ + // This is really a dummy method to make it look like sync() exists in + // WorkerListModel (and not QDeclarativeWorkerListModelAgent) and to let + // us document sync(). + qmlInfo(this) << "sync() can only be called from a WorkerScript"; +} + QDeclarativeWorkerListModelAgent *QDeclarativeWorkerListModel::agent() { if (!m_agent) @@ -1013,6 +1145,10 @@ QString QDeclarativeWorkerListModel::toString(int role) const return m_roles.value(role); } +/*! + \qmlproperty int ListModel::count + The number of data entries in the model. +*/ int QDeclarativeWorkerListModel::count() const { return m_values.count(); @@ -1038,4 +1174,3 @@ QT_END_NAMESPACE #include "qdeclarativeworkerscript.moc" - diff --git a/src/declarative/qml/qdeclarativeworkerscript_p.h b/src/declarative/qml/qdeclarativeworkerscript_p.h index a810801..912eac9 100644 --- a/src/declarative/qml/qdeclarativeworkerscript_p.h +++ b/src/declarative/qml/qdeclarativeworkerscript_p.h @@ -134,6 +134,7 @@ public: Q_INVOKABLE void insert(int index, const QScriptValue&); Q_INVOKABLE QScriptValue get(int index) const; Q_INVOKABLE void set(int index, const QScriptValue &); + Q_INVOKABLE void sync(); QDeclarativeWorkerListModelAgent *agent(); diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 10230d3..ebf1a20 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1573,7 +1573,8 @@ QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent QDeclarativeAnimationGroup(parent) { Q_D(QDeclarativeAnimationGroup); - d->ag = new QSequentialAnimationGroup(this); + d->ag = new QSequentialAnimationGroup; + QDeclarative_setParent_noEvent(d->ag, this); } QDeclarativeSequentialAnimation::~QDeclarativeSequentialAnimation() @@ -1638,7 +1639,8 @@ QDeclarativeParallelAnimation::QDeclarativeParallelAnimation(QObject *parent) : QDeclarativeAnimationGroup(parent) { Q_D(QDeclarativeAnimationGroup); - d->ag = new QParallelAnimationGroup(this); + d->ag = new QParallelAnimationGroup; + QDeclarative_setParent_noEvent(d->ag, this); } QDeclarativeParallelAnimation::~QDeclarativeParallelAnimation() @@ -1797,7 +1799,7 @@ QDeclarativePropertyAnimation::~QDeclarativePropertyAnimation() void QDeclarativePropertyAnimationPrivate::init() { Q_Q(QDeclarativePropertyAnimation); - va = new QDeclarativeTimeLineValueAnimator; + va = new QDeclarativeBulkValueAnimator; QDeclarative_setParent_noEvent(va, q); } @@ -2213,7 +2215,7 @@ QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation() return d->va; } -struct PropertyUpdater : public QDeclarativeTimeLineValue +struct PropertyUpdater : public QDeclarativeBulkValueUpdater { QDeclarativeStateActions actions; int interpolatorType; //for Number/ColorAnimation @@ -2231,7 +2233,6 @@ struct PropertyUpdater : public QDeclarativeTimeLineValue wasDeleted = &deleted; if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 v = 1 - v; - QDeclarativeTimeLineValue::setValue(v); for (int ii = 0; ii < actions.count(); ++ii) { QDeclarativeAction &action = actions[ii]; diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index e582066..ae82a90 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -149,14 +149,21 @@ private: bool running; }; -//animates QDeclarativeTimeLineValue (assumes start and end values will be reals or compatible) -class QDeclarativeTimeLineValueAnimator : public QVariantAnimation +class QDeclarativeBulkValueUpdater +{ +public: + virtual ~QDeclarativeBulkValueUpdater() {} + virtual void setValue(qreal value) = 0; +}; + +//animates QDeclarativeBulkValueUpdater (assumes start and end values will be reals or compatible) +class QDeclarativeBulkValueAnimator : public QVariantAnimation { Q_OBJECT public: - QDeclarativeTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {} - ~QDeclarativeTimeLineValueAnimator() { if (policy == DeleteWhenStopped) { delete animValue; animValue = 0; } } - void setAnimValue(QDeclarativeTimeLineValue *value, DeletionPolicy p) + QDeclarativeBulkValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {} + ~QDeclarativeBulkValueAnimator() { if (policy == DeleteWhenStopped) { delete animValue; animValue = 0; } } + void setAnimValue(QDeclarativeBulkValueUpdater *value, DeletionPolicy p) { if (state() == Running) stop(); @@ -193,7 +200,7 @@ protected: } private: - QDeclarativeTimeLineValue *animValue; + QDeclarativeBulkValueUpdater *animValue; bool *fromSourced; DeletionPolicy policy; }; @@ -352,7 +359,7 @@ public: int interpolatorType; QVariantAnimation::Interpolator interpolator; - QDeclarativeTimeLineValueAnimator *va; + QDeclarativeBulkValueAnimator *va; static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress); static void convertVariant(QVariant &variant, int type); diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index 4d12ae1..8f5f537 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -189,6 +189,16 @@ void QDeclarativeFontLoader::setName(const QString &name) \o Loading - the font is currently being loaded \o Error - an error occurred while loading the font \endlist + + Note that a change in the status property does not cause anything to happen + (although it reflects what has happened to the font loader internally). If you wish + to react to the change in status you need to do it yourself, for example in one + of the following ways: + \list + \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: loader.status = FontLoader.Ready;} + \o Do something inside the onStatusChanged signal handler, e.g. FontLoader{id: loader; onStatusChanged: if(loader.status == FontLoader.Ready) console.log('Loaded');} + \o Bind to the status variable somewhere, e.g. Text{text: if(loader.status!=FontLoader.Ready){'Not Loaded';}else{'Loaded';}} + \endlist */ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const { diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 2b8c7de..1f85b89 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -70,7 +70,9 @@ #include "qdeclarativetransitionmanager_p_p.h" #include "qdeclarativetransition_p.h" #include "qdeclarativeview.h" +#ifndef QT_NO_XMLPATTERNS #include "qdeclarativexmllistmodel_p.h" +#endif #include "qnumberformat_p.h" #include "qperformancelog_p_p.h" diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 6fe5bf3..f08e634 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -51,6 +51,7 @@ #include <qdeclarativedebug_p.h> #include <qdeclarativedebugservice_p.h> #include <qdeclarativeglobal_p.h> +#include <qdeclarativeguard_p.h> #include <qscriptvalueiterator.h> #include <qdebug.h> @@ -136,8 +137,8 @@ public: QDeclarativeView *q; - QGuard<QGraphicsObject> root; - QGuard<QDeclarativeItem> qmlRoot; + QDeclarativeGuard<QGraphicsObject> root; + QDeclarativeGuard<QDeclarativeItem> qmlRoot; QUrl source; @@ -282,13 +283,14 @@ QDeclarativeView::~QDeclarativeView() /*! Sets the source to the \a url, loads the QML component and instantiates it. + + Calling this methods multiple times with the same url will result + in the QML being reloaded. */ void QDeclarativeView::setSource(const QUrl& url) { - if (url != d->source) { - d->source = url; - d->execute(); - } + d->source = url; + d->execute(); } /*! diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 162a669..d260ada 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -647,11 +647,21 @@ void QDeclarativeXmlListModel::setNamespaceDeclarations(const QString &declarati This property holds the status of data source loading. It can be one of: \list \o Null - no data source has been set - \o Ready - nthe data source has been loaded + \o Ready - the data source has been loaded \o Loading - the data source is currently being loaded \o Error - an error occurred while loading the data source \endlist + Note that a change in the status property does not cause anything to happen + (although it reflects what has happened to the XmlListModel internally). If you wish + to react to the change in status you need to do it yourself, for example in one + of the following ways: + \list + \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: xmlListModel.status = XmlListModel.Ready;} + \o Do something inside the onStatusChanged signal handler, e.g. XmlListModel{id: xmlListModel; onStatusChanged: if(xmlListModel.status == XmlListModel.Ready) console.log('Loaded');} + \o Bind to the status variable somewhere, e.g. Text{text: if(xmlListModel.status!=XmlListModel.Ready){'Not Loaded';}else{'Loaded';}} + \endlist + \sa progress */ diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index e511c3a..babfc72 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1222,9 +1222,16 @@ void qt_init(QApplicationPrivate *priv, int) #endif if (!app_proc_ae_handlerUPP) { app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor); - for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) - AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, - app_proc_ae_handlerUPP, SRefCon(qApp), false); + for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) { + // Install apple event handler, but avoid overwriting an already + // existing handler (it means a 3rd party application has installed one): + SRefCon refCon = 0; + AEEventHandlerUPP current_handler = NULL; + AEGetEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, ¤t_handler, &refCon, false); + if (!current_handler) + AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, + app_proc_ae_handlerUPP, SRefCon(qApp), false); + } } if (QApplicationPrivate::app_style) { @@ -2495,6 +2502,13 @@ void QApplicationPrivate::setupAppleEvents() // finished initialization, which appears to be just after [NSApplication run] has // started to execute. By setting up our apple events handlers this late, we override // the ones set up by NSApplication. + + // If Qt is used as a plugin, we let the 3rd party application handle events + // like quit and open file events. Otherwise, if we install our own handlers, we + // easily end up breaking functionallity the 3rd party application depend on: + if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) + return; + QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]; NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager]; [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:) diff --git a/src/gui/kernel/qcursor_mac.mm b/src/gui/kernel/qcursor_mac.mm index cfebf60..03e38b0 100644 --- a/src/gui/kernel/qcursor_mac.mm +++ b/src/gui/kernel/qcursor_mac.mm @@ -114,27 +114,18 @@ void qt_mac_set_cursor(const QCursor *c, const QPoint &) } c->handle(); //force the cursor to get loaded, if it's not - if(1 || currentCursor != c->d) { - if(currentCursor && currentCursor->type == QCursorData::TYPE_ThemeCursor - && currentCursor->curs.tc.anim) - currentCursor->curs.tc.anim->stop(); - QMacCocoaAutoReleasePool pool; - if(c->d->type == QCursorData::TYPE_ImageCursor) { - [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set]; - } else if(c->d->type == QCursorData::TYPE_ThemeCursor) { -#ifdef QT_MAC_USE_COCOA - if (c->d->curs.cp.nscursor == 0) - [[NSCursor arrowCursor] set]; - [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set]; -#else - if(SetAnimatedThemeCursor(c->d->curs.tc.curs, 0) == themeBadCursorIndexErr) { - SetThemeCursor(c->d->curs.tc.curs); - } else { - if(!c->d->curs.tc.anim) - c->d->curs.tc.anim = new QMacAnimateCursor; - c->d->curs.tc.anim->start(c->d->curs.tc.curs); - } -#endif + if(currentCursor && currentCursor->type == QCursorData::TYPE_ThemeCursor + && currentCursor->curs.tc.anim) + currentCursor->curs.tc.anim->stop(); + if(c->d->type == QCursorData::TYPE_ImageCursor) { + [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set]; + } else if(c->d->type == QCursorData::TYPE_ThemeCursor) { + if(SetAnimatedThemeCursor(c->d->curs.tc.curs, 0) == themeBadCursorIndexErr) { + SetThemeCursor(c->d->curs.tc.curs); + } else { + if(!c->d->curs.tc.anim) + c->d->curs.tc.anim = new QMacAnimateCursor; + c->d->curs.tc.anim->start(c->d->curs.tc.curs); } } currentCursor = c->d; diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index d6d288e..0b735a2 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -532,25 +532,48 @@ QString QColor::name() const void QColor::setNamedColor(const QString &name) { + if (!setColorFromString(name)) + qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData()); +} + +/*! + \since 4.7 + + Returns true if the \a name is a valid color name and can + be used to construct a valid QColor object, otherwise returns + false. + + The algorithm used is the same as with \a setNamedColor(). + \sa setNamedColor() +*/ +bool QColor::isValidColor(const QString &name) +{ + return QColor().setColorFromString(name); +} + +bool QColor::setColorFromString(const QString &name) +{ if (name.isEmpty()) { invalidate(); - return; + return false; } if (name.startsWith(QLatin1Char('#'))) { QRgb rgb; if (qt_get_hex_rgb(name.constData(), name.length(), &rgb)) { setRgb(rgb); + return true; } else { invalidate(); + return false; } - return; } #ifndef QT_NO_COLORNAMES QRgb rgb; if (qt_get_named_rgb(name.constData(), name.length(), &rgb)) { setRgba(rgb); + return true; } else #endif { @@ -561,11 +584,12 @@ void QColor::setNamedColor(const QString &name) && QX11Info::display() && XParseColor(QX11Info::display(), QX11Info::appColormap(), name.toLatin1().constData(), &result)) { setRgb(result.red >> 8, result.green >> 8, result.blue >> 8); + return true; } else #endif { - qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData()); invalidate(); + return false; } } } diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index 332dc25..0ac828d 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -225,6 +225,8 @@ public: QT3_SUPPORT uint pixel(int screen = -1) const; #endif + static bool isValidColor(const QString &name); + private: #ifndef QT3_SUPPORT // do not allow a spec to be used as an alpha value @@ -232,6 +234,7 @@ private: #endif void invalidate(); + bool setColorFromString(const QString &name); Spec cspec; union { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index dc96c17..9d83718 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -8933,8 +8933,15 @@ void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount, for (int i = 0; i < fragmentCount; ++i) { QTransform transform = oldTransform; - transform.translate(fragments[i].x, fragments[i].y); - transform.rotate(fragments[i].rotation); + qreal xOffset = 0; + qreal yOffset = 0; + if (fragments[i].rotation == 0) { + xOffset = fragments[i].x; + yOffset = fragments[i].y; + } else { + transform.translate(fragments[i].x, fragments[i].y); + transform.rotate(fragments[i].rotation); + } setOpacity(oldOpacity * fragments[i].opacity); setTransform(transform); @@ -8942,7 +8949,7 @@ void QPainter::drawPixmapFragments(const Fragment *fragments, int fragmentCount, qreal h = fragments[i].scaleY * fragments[i].height; QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, fragments[i].width, fragments[i].height); - drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect); + drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect); } setOpacity(oldOpacity); diff --git a/src/plugins/imageformats/tiff/tiff.pro b/src/plugins/imageformats/tiff/tiff.pro index 514fd69..85f618f 100644 --- a/src/plugins/imageformats/tiff/tiff.pro +++ b/src/plugins/imageformats/tiff/tiff.pro @@ -55,7 +55,8 @@ contains(QT_CONFIG, system-tiff) { } wince*: { SOURCES += ../../../corelib/kernel/qfunctions_wince.cpp \ - ../../../3rdparty/libtiff/libtiff/tif_wince.c + ../../../3rdparty/libtiff/libtiff/tif_wince.c \ + ../../../3rdparty/libtiff/libtiff/tif_win32.c } symbian*: { SOURCES += ../../../3rdparty/libtiff/port/lfind.c diff --git a/src/plugins/mediaservices/mediaservices.pro b/src/plugins/mediaservices/mediaservices.pro index d84b276..19d678b 100644 --- a/src/plugins/mediaservices/mediaservices.pro +++ b/src/plugins/mediaservices/mediaservices.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs contains(QT_CONFIG, mediaservice) { - win32:!wince: SUBDIRS += directshow + win32:!wince*: SUBDIRS += directshow mac: SUBDIRS += qt7 diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index d2e96d1..9cd5c63 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -563,7 +563,7 @@ JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObjec slot = arg1; else { QScript::SaveFrameHelper saveFrame(engine, exec); - QString propertyName(QScriptEnginePrivate::toString(exec, arg1)); + JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1); slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -645,7 +645,7 @@ JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject * slot = arg1; else { QScript::SaveFrameHelper saveFrame(engine, exec); - QString propertyName = QScriptEnginePrivate::toString(exec, arg1); + JSC::UString propertyName = QScriptEnginePrivate::toString(exec, arg1); slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -723,19 +723,19 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje if ((args.size() > 4) && !args.at(4).isNumber()) return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number"); #ifndef QT_NO_QOBJECT - QString context(args.at(0).toString(exec)); + JSC::UString context = args.at(0).toString(exec); #endif - QString text(args.at(1).toString(exec)); + JSC::UString text = args.at(1).toString(exec); #ifndef QT_NO_QOBJECT - QString comment; + JSC::UString comment; if (args.size() > 2) comment = args.at(2).toString(exec); QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr; if (args.size() > 3) { - QString encStr(args.at(3).toString(exec)); - if (encStr == QLatin1String("CodecForTr")) + JSC::UString encStr = args.at(3).toString(exec); + if (encStr == "CodecForTr") encoding = QCoreApplication::CodecForTr; - else if (encStr == QLatin1String("UnicodeUTF8")) + else if (encStr == "UnicodeUTF8") encoding = QCoreApplication::UnicodeUTF8; else return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr)); @@ -744,11 +744,11 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje if (args.size() > 4) n = args.at(4).toInt32(exec); #endif - QString result; + JSC::UString result; #ifndef QT_NO_QOBJECT - result = QCoreApplication::translate(context.toLatin1().constData(), - text.toLatin1().constData(), - comment.toLatin1().constData(), + result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(), + QScript::convertToLatin1(text).constData(), + QScript::convertToLatin1(comment).constData(), encoding, n); #else result = text; @@ -774,25 +774,25 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS if ((args.size() > 2) && !args.at(2).isNumber()) return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number"); #ifndef QT_NO_QOBJECT - QString context; + JSC::UString context; QScriptContext *ctx = QScriptEnginePrivate::contextForFrame(exec); if (ctx && ctx->parentContext()) context = QFileInfo(QScriptContextInfo(ctx->parentContext()).fileName()).baseName(); #endif - QString text(args.at(0).toString(exec)); + JSC::UString text = args.at(0).toString(exec); #ifndef QT_NO_QOBJECT - QString comment; + JSC::UString comment; if (args.size() > 1) comment = args.at(1).toString(exec); int n = -1; if (args.size() > 2) n = args.at(2).toInt32(exec); #endif - QString result; + JSC::UString result; #ifndef QT_NO_QOBJECT - result = QCoreApplication::translate(context.toLatin1().constData(), - text.toLatin1().constData(), - comment.toLatin1().constData(), + result = QCoreApplication::translate(QScript::convertToLatin1(context).constData(), + QScript::convertToLatin1(text).constData(), + QScript::convertToLatin1(comment).constData(), QCoreApplication::CodecForTr, n); #else result = text; @@ -1580,9 +1580,9 @@ QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value) { if (!isRegExp(value)) return QRegExp(); - QString pattern = toString(exec, property(exec, value, QLatin1String("source"), QScriptValue::ResolvePrototype)); + QString pattern = toString(exec, property(exec, value, "source", QScriptValue::ResolvePrototype)); Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (toBool(exec, property(exec, value, QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype))) + if (toBool(exec, property(exec, value, "ignoreCase", QScriptValue::ResolvePrototype))) kase = Qt::CaseInsensitive; return QRegExp(pattern, kase, QRegExp::RegExp2); } @@ -1637,7 +1637,7 @@ JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSV } if (!result && (resolveMode & QScriptValue::ResolveScope)) { // ### check if it's a function object and look in the scope chain - JSC::JSValue scope = property(exec, value, QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); + JSC::JSValue scope = property(exec, value, "__qt_scope__", QScriptValue::ResolveLocal); if (isObject(scope)) result = property(exec, scope, id, resolveMode); } diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index d0d020a..5166d89 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -123,6 +123,9 @@ namespace QScript inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); + inline void convertToLatin1_helper(const UChar *i, int length, char *s); + inline QByteArray convertToLatin1(const JSC::UString &str); + class UStringSourceProviderWithFeedback; struct GlobalClientData : public JSC::JSGlobalData::ClientData @@ -165,7 +168,7 @@ public: static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue); static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue); static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue); - static inline QString toString(JSC::ExecState *, JSC::JSValue); + static inline JSC::UString toString(JSC::ExecState *, JSC::JSValue); static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); #ifndef QT_NO_REGEXP @@ -181,8 +184,8 @@ public: static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index, int resolveMode = QScriptValue::ResolvePrototype); static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode); - static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const QString &, int resolveMode); - static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const QString &name, JSC::JSValue, + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::UString &, int resolveMode); + static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::UString &name, JSC::JSValue, const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue, const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); @@ -191,7 +194,7 @@ public: static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode); static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, - const QString &name, const QScriptValue::ResolveFlags &mode); + const JSC::UString &name, const QScriptValue::ResolveFlags &mode); static bool convertValue(JSC::ExecState*, JSC::JSValue value, int type, void *ptr); @@ -516,6 +519,21 @@ inline bool ToBool(const QString &value) return !value.isEmpty(); } +inline void convertToLatin1_helper(const UChar *i, int length, char *s) +{ + const UChar *e = i + length; + while (i != e) + *(s++) = (uchar) *(i++); + *s = '\0'; +} + +inline QByteArray convertToLatin1(const JSC::UString &str) +{ + QByteArray ba(str.size(), Qt::Uninitialized); + convertToLatin1_helper(str.data(), str.size(), ba.data()); + return ba; +} + } // namespace QScript inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) @@ -629,7 +647,7 @@ inline void QScriptValuePrivate::initFrom(const QString &value) engine->registerScriptValue(this); } -inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const QString &name, int resolveMode) +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::UString &name, int resolveMode) { return property(exec, value, JSC::Identifier(exec, name), resolveMode); } @@ -655,13 +673,13 @@ inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JS } inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, - const QString &name, + const JSC::UString &name, const QScriptValue::ResolveFlags &mode) { return propertyFlags(exec, value, JSC::Identifier(exec, name), mode); } -inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const QString &name, +inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::UString &name, JSC::JSValue value, const QScriptValue::PropertyFlags &flags) { setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags); @@ -677,7 +695,7 @@ inline JSC::JSValue QScriptValuePrivate::property(quint32 index, int resolveMode return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode); } -inline JSC::JSValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, int resolveMode) const { JSC::ExecState *exec = engine->currentFrame; return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode); @@ -701,7 +719,7 @@ inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue & QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags); } -inline void QScriptValuePrivate::setProperty(const QString &name, const JSC::JSValue &value, +inline void QScriptValuePrivate::setProperty(const JSC::UString &name, const JSC::JSValue &value, const QScriptValue::PropertyFlags &flags) { JSC::ExecState *exec = engine->currentFrame; @@ -919,7 +937,7 @@ inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue return QScript::ToUInt16(toNumber(exec, value)); } -inline QString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value) +inline JSC::UString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value) { JSC::JSValue savedException; saveException(exec, &savedException); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 7f1fdaa..414a45c 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -562,7 +562,7 @@ QScriptValue QScriptValue::scope() const if (!d || !d->isObject()) return QScriptValue(); // ### make hidden property - JSC::JSValue result = d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal); return d->engine->scriptValueFromJSCValue(result); } diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 77b7330..089b923 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -88,8 +88,8 @@ public: inline JSC::JSValue property(const JSC::Identifier &id, int resolveMode) const; inline JSC::JSValue property(quint32 index, int resolveMode) const; - inline JSC::JSValue property(const QString &, int resolveMode) const; - inline void setProperty(const QString &name, const JSC::JSValue &value, + inline JSC::JSValue property(const JSC::UString &, int resolveMode) const; + inline void setProperty(const JSC::UString &name, const JSC::JSValue &value, const QScriptValue::PropertyFlags &flags); inline void setProperty(const JSC::Identifier &id, const JSC::JSValue &value, const QScriptValue::PropertyFlags &flags); diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 30e5a26..8d111f9 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -654,8 +654,8 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; } } else { - QString sval = QScriptEnginePrivate::toString(exec, actual); - int ival = m.keyToValue(sval.toLatin1()); + JSC::UString sval = QScriptEnginePrivate::toString(exec, actual); + int ival = m.keyToValue(convertToLatin1(sval)); if (ival != -1) { qVariantSetValue(v, ival); converted = true; @@ -1168,7 +1168,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * { //Note: this has to be kept in sync with getOwnPropertyDescriptor #ifndef QT_NO_PROPERTIES - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; if (!qobject) { QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") @@ -1285,7 +1285,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS { //Note: this has to be kept in sync with getOwnPropertySlot abd getPropertyAttributes #ifndef QT_NO_PROPERTIES - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; if (!qobject) { QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") @@ -1419,7 +1419,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, JSC::JSValue value, JSC::PutPropertySlot &slot) { #ifndef QT_NO_PROPERTIES - QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; if (!qobject) { QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") @@ -1517,7 +1517,7 @@ bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec bool checkDontDelete) { #ifndef QT_NO_PROPERTIES - QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; if (!qobject) { QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") @@ -1567,7 +1567,7 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, { #ifndef QT_NO_PROPERTIES //Note: this has to be kept in sync with getOwnPropertyDescriptor and getOwnPropertySlot - QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; if (!qobject) return false; @@ -1853,7 +1853,7 @@ bool QMetaObjectWrapperObject::getOwnPropertySlot( return true; } - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); @@ -1881,7 +1881,7 @@ void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& } const QMetaObject *meta = data->value; if (meta) { - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); for (int j = 0; j < e.keyCount(); ++j) { @@ -1901,7 +1901,7 @@ bool QMetaObjectWrapperObject::deleteProperty( return false; const QMetaObject *meta = data->value; if (meta) { - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); for (int j = 0; j < e.keyCount(); ++j) { @@ -1923,7 +1923,7 @@ bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, } const QMetaObject *meta = data->value; if (meta) { - QByteArray name = QString(propertyName.ustring()).toLatin1(); + QByteArray name = convertToLatin1(propertyName.ustring()); for (int i = 0; i < meta->enumeratorCount(); ++i) { QMetaEnum e = meta->enumerator(i); for (int j = 0; j < e.keyCount(); ++j) { diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 5c9dd55..4590f17 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -877,6 +877,19 @@ int qt_snprintf(char *str, int size, const char *format, ...) return res; } +/*! \internal + Invoke a method of the object without generating warning if the method does not exist + */ +static void invokeMethod(QObject *obj, const char *methodName) +{ + const QMetaObject *metaObject = obj->metaObject(); + int funcIndex = metaObject->indexOfMethod(methodName); + if (funcIndex >= 0) { + QMetaMethod method = metaObject->method(funcIndex); + method.invoke(obj, Qt::DirectConnection); + } +} + bool Q_TESTLIB_EXPORT defaultKeyVerbose() { if (keyVerbose == -1) { @@ -1213,7 +1226,7 @@ static void qInvokeTestMethodDataEntry(char *slot) bool invokeOk; do { QTestResult::setCurrentTestLocation(QTestResult::InitFunc); - QMetaObject::invokeMethod(QTest::currentTestObject, "init"); + invokeMethod(QTest::currentTestObject, "init()"); if (QTestResult::skipCurrentTest()) break; @@ -1233,7 +1246,7 @@ static void qInvokeTestMethodDataEntry(char *slot) QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__); QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc); - QMetaObject::invokeMethod(QTest::currentTestObject, "cleanup"); + invokeMethod(QTest::currentTestObject, "cleanup()"); QTestResult::setCurrentTestLocation(QTestResult::NoWhere); // If this test method has a benchmark, repeat until all measurements are @@ -1300,8 +1313,9 @@ static bool qInvokeTestMethod(const char *slotName, const char *data=0) if (curGlobalDataIndex == 0) { QTestResult::setCurrentTestLocation(QTestResult::DataFunc); - QTest::qt_snprintf(member, 512, "%s_data", slot); - QMetaObject::invokeMethod(QTest::currentTestObject, member, Qt::DirectConnection); + QTest::qt_snprintf(member, 512, "%s_data()", slot); + invokeMethod(QTest::currentTestObject, member); + // if we encounter a SkipAll in the _data slot, we skip the whole // testfunction, no matter how much global data exists if (QTestResult::skipCurrentTest()) { @@ -1466,11 +1480,11 @@ static void qInvokeTestMethods(QObject *testObject) QTestResult::setCurrentTestFunction("initTestCase"); QTestResult::setCurrentTestLocation(QTestResult::DataFunc); QTestTable::globalTestTable(); - QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection); + invokeMethod(testObject, "initTestCase_data()"); if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { QTestResult::setCurrentTestLocation(QTestResult::InitFunc); - QMetaObject::invokeMethod(testObject, "initTestCase"); + invokeMethod(testObject, "initTestCase()"); // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy. const bool previousFailed = QTestResult::testFailed(); @@ -1498,7 +1512,7 @@ static void qInvokeTestMethods(QObject *testObject) QTestResult::setSkipCurrentTest(false); QTestResult::setCurrentTestFunction("cleanupTestCase"); - QMetaObject::invokeMethod(testObject, "cleanupTestCase"); + invokeMethod(testObject, "cleanupTestCase()"); } QTestResult::finishedCurrentTestFunction(); QTestResult::setCurrentTestFunction(0); diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index 53c63b5..0c166df 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -221,17 +221,17 @@ void tst_qdeclarativeanimations::resume() QVERIFY(animation.from() == 10); animation.start(); - QTest::qWait(100); + QTest::qWait(200); animation.pause(); qreal x = rect.x(); - QVERIFY(x != qreal(200)); + QVERIFY(x != qreal(200) && x != qreal(10)); QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.resume(); QVERIFY(animation.isRunning()); QVERIFY(!animation.isPaused()); - QTest::qWait(100); + QTest::qWait(200); animation.stop(); QVERIFY(rect.x() > x); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.1.qml new file mode 100644 index 0000000..9b11fa9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.1.qml @@ -0,0 +1,13 @@ +import Qt.test 1.0 + +MyQmlObject { + property string result + + Script{ + function f() { + result = b + } + + } + onArgumentSignal: f() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.2.qml new file mode 100644 index 0000000..ec727e2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.2.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 + +MyQmlObject { + property string result + property string aProp: "hello" + + Script{ + source: "scriptScope.js" + } + onBasicSignal: f() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.js b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.js new file mode 100644 index 0000000..5689930 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/scriptScope.js @@ -0,0 +1,5 @@ +var aProp = "world"; + +function f() { + result = aProp; +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 60c380c..8e7944d 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -122,6 +122,7 @@ private slots: void listToVariant(); void multiEngineObject(); void deletedObject(); + void scriptScope(); void bug1(); @@ -1657,6 +1658,33 @@ void tst_qdeclarativeecmascript::deletedObject() delete object; } +void tst_qdeclarativeecmascript::scriptScope() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("scriptScope.1.qml")); + + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + emit object->argumentSignal(19, "Hello world!", 10.3); + QEXPECT_FAIL("", "QTBUG-8641", Continue); + QCOMPARE(object->property("result").toString(), QLatin1String("undefined")); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("scriptScope.2.qml")); + + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + emit object->basicSignal(); + QEXPECT_FAIL("", "QTBUG-8641", Continue); + QCOMPARE(object->property("result").toString(), QLatin1String("world")); + + delete object; + } +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview.qml index 344b4b5..ba6b807 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview.qml @@ -1,6 +1,10 @@ import Qt 4.6 Rectangle { + id: root + property int added: -1 + property var removed + width: 240 height: 320 color: "#ffffff" @@ -33,6 +37,8 @@ Rectangle { text: number } color: GridView.isCurrentItem ? "lightsteelblue" : "white" + GridView.onAdd: root.added = index + GridView.onRemove: root.removed = name } } ] diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index cc65d32..7ade309 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -257,7 +257,7 @@ void tst_QDeclarativeGridView::inserted() model.insertItem(1, "Will", "9876"); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); QCOMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item @@ -268,6 +268,10 @@ void tst_QDeclarativeGridView::inserted() QVERIFY(number != 0); QCOMPARE(number->text(), model.number(1)); + // Checks that onAdd is called + int added = canvas->rootObject()->property("added").toInt(); + QCOMPARE(added, 1); + // Confirm items positioned correctly for (int i = 0; i < model.count(); ++i) { QDeclarativeItem *item = findItem<QDeclarativeItem>(viewport, "wrapper", i); @@ -278,7 +282,7 @@ void tst_QDeclarativeGridView::inserted() model.insertItem(0, "Foo", "1111"); // zero index, and current item // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); QCOMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item @@ -300,14 +304,14 @@ void tst_QDeclarativeGridView::inserted() for (int i = model.count(); i < 30; ++i) model.insertItem(i, "Hello", QString::number(i)); - QTest::qWait(300); + QTest::qWait(100); gridview->setContentY(120); - QTest::qWait(300); + QTest::qWait(100); // Insert item outside visible area model.insertItem(1, "Hello", "1324"); - QTest::qWait(300); + QTest::qWait(100); QVERIFY(gridview->contentY() == 120); @@ -338,7 +342,7 @@ void tst_QDeclarativeGridView::removed() model.removeItem(1); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1); QVERIFY(name != 0); @@ -347,6 +351,10 @@ void tst_QDeclarativeGridView::removed() QVERIFY(number != 0); QCOMPARE(number->text(), model.number(1)); + // Checks that onRemove is called + QString removed = canvas->rootObject()->property("removed").toString(); + QCOMPARE(removed, QString("Item1")); + // Confirm items positioned correctly int itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count(); for (int i = 0; i < model.count() && i < itemCount; ++i) { @@ -361,7 +369,7 @@ void tst_QDeclarativeGridView::removed() model.removeItem(0); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); name = findItem<QDeclarativeText>(viewport, "textName", 0); QVERIFY(name != 0); @@ -383,7 +391,7 @@ void tst_QDeclarativeGridView::removed() // Remove items not visible model.removeItem(25); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Confirm items positioned correctly itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count(); @@ -397,11 +405,11 @@ void tst_QDeclarativeGridView::removed() // Remove items before visible gridview->setContentY(120); - QTest::qWait(500); + QTest::qWait(100); gridview->setCurrentIndex(10); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Setting currentIndex above shouldn't cause view to scroll QCOMPARE(gridview->contentY(), 120.0); @@ -409,7 +417,7 @@ void tst_QDeclarativeGridView::removed() model.removeItem(1); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Confirm items positioned correctly for (int i = 6; i < 18; ++i) { @@ -423,14 +431,14 @@ void tst_QDeclarativeGridView::removed() // Remove currentIndex QDeclarativeItem *oldCurrent = gridview->currentItem(); model.removeItem(9); - QTest::qWait(500); + QTest::qWait(100); QCOMPARE(gridview->currentIndex(), 9); QVERIFY(gridview->currentItem() != oldCurrent); gridview->setContentY(0); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Confirm items positioned correctly itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count(); @@ -444,7 +452,7 @@ void tst_QDeclarativeGridView::removed() // remove item outside current view. gridview->setCurrentIndex(32); - QTest::qWait(500); + QTest::qWait(100); gridview->setContentY(240); model.removeItem(30); @@ -452,21 +460,21 @@ void tst_QDeclarativeGridView::removed() // remove current item beyond visible items. gridview->setCurrentIndex(20); - QTest::qWait(500); + QTest::qWait(100); gridview->setContentY(0); model.removeItem(20); - QTest::qWait(500); + QTest::qWait(100); QCOMPARE(gridview->currentIndex(), 20); QVERIFY(gridview->currentItem() != 0); // remove item before current, but visible gridview->setCurrentIndex(8); - QTest::qWait(500); + QTest::qWait(100); gridview->setContentY(240); oldCurrent = gridview->currentItem(); model.removeItem(6); - QTest::qWait(500); + QTest::qWait(100); QCOMPARE(gridview->currentIndex(), 7); QVERIFY(gridview->currentItem() == oldCurrent); @@ -498,7 +506,7 @@ void tst_QDeclarativeGridView::moved() model.moveItem(1, 8); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); QDeclarativeText *name = findItem<QDeclarativeText>(viewport, "textName", 1); QVERIFY(name != 0); @@ -530,7 +538,7 @@ void tst_QDeclarativeGridView::moved() model.moveItem(1, 25); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Confirm items positioned correctly and indexes correct itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count()-1; @@ -552,7 +560,7 @@ void tst_QDeclarativeGridView::moved() model.moveItem(28, 8); // let transitions settle. - QTest::qWait(300); + QTest::qWait(100); // Confirm items positioned correctly and indexes correct for (int i = 6; i < model.count()-6 && i < itemCount+6; ++i) { @@ -595,7 +603,7 @@ void tst_QDeclarativeGridView::currentIndex() QDeclarativeItem *viewport = gridview->viewport(); QVERIFY(viewport != 0); - QTest::qWait(500); + QTest::qWait(300); // current item should be third item QCOMPARE(gridview->currentIndex(), 5); @@ -622,7 +630,7 @@ void tst_QDeclarativeGridView::currentIndex() QCOMPARE(gridview->currentIndex(), 0); gridview->setCurrentIndex(model.count()-1); - QTest::qWait(500); + QTest::qWait(100); QCOMPARE(gridview->currentIndex(), model.count()-1); gridview->moveCurrentIndexRight(); @@ -681,8 +689,6 @@ void tst_QDeclarativeGridView::currentIndex() // turn off auto highlight gridview->setHighlightFollowsCurrentItem(false); QVERIFY(gridview->highlightFollowsCurrentItem() == false); - - QTest::qWait(500); QVERIFY(gridview->highlightItem()); qreal hlPosX = gridview->highlightItem()->x(); qreal hlPosY = gridview->highlightItem()->y(); @@ -733,7 +739,7 @@ void tst_QDeclarativeGridView::changeFlow() } ctxt->setContextProperty("testTopToBottom", QVariant(true)); - QTest::qWait(500); + QTest::qWait(100); // Confirm items positioned correctly and indexes correct itemCount = findItems<QDeclarativeItem>(viewport, "wrapper").count(); diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml new file mode 100644 index 0000000..be94e00 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/model.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Item { + property alias model: model + + WorkerListModel { id: model } + + function workerModifyModel(cmd) { worker.sendMessage({'command': cmd, 'model': model}) } + + WorkerScript { + id: worker + source: "script.js" + } +} diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js new file mode 100644 index 0000000..8ee62b4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeworkerlistmodel/data/script.js @@ -0,0 +1,6 @@ +WorkerScript.onMessage = function(msg) { + eval("msg.model." + msg.command) + msg.model.sync() +} + + diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro b/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro new file mode 100644 index 0000000..960dbe1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeworkerlistmodel/qdeclarativeworkerlistmodel.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +QT += script +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativeworkerlistmodel.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp b/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp new file mode 100644 index 0000000..11a7447 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeworkerlistmodel/tst_qdeclarativeworkerlistmodel.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qtest.h> +#include <QtCore/qdebug.h> + +#include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeitem.h> + +#include <private/qdeclarativeworkerscript_p.h> +#include <private/qdeclarativelistmodel_p.h> +#include "../../../shared/util.h" + + + +class tst_QDeclarativeWorkerListModel : public QObject +{ + Q_OBJECT +public: + tst_QDeclarativeWorkerListModel() {} +private slots: + void clear(); + void remove(); + void append(); + void insert(); + void get(); + void set(); + +private: + QByteArray modificationWarning() const { + QString file = QUrl::fromLocalFile(SRCDIR "/data/model.qml").toString(); + return QString("QML WorkerListModel (" + file + ":6:5) List can only be modified from a WorkerScript").toUtf8(); + } + + QDeclarativeEngine m_engine; +}; + +void tst_QDeclarativeWorkerListModel::clear() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QCOMPARE(model->count(), 0); + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + + QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); + model->clear(); + QCOMPARE(model->count(), 1); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "clear()"))); + QTRY_COMPARE(model->count(), 0); + + qApp->processEvents(); +} + +void tst_QDeclarativeWorkerListModel::remove() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + + QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); + model->remove(0); + QCOMPARE(model->count(), 1); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "remove(0)"))); + QTRY_COMPARE(model->count(), 0); + + qApp->processEvents(); +} + +void tst_QDeclarativeWorkerListModel::append() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + + QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); + model->append(QScriptValue(1)); + QCOMPARE(model->count(), 1); + + qApp->processEvents(); +} + +void tst_QDeclarativeWorkerListModel::insert() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "insert(0, {'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + + QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); + model->insert(0, QScriptValue(1)); + QCOMPARE(model->count(), 1); + + qApp->processEvents(); +} + +void tst_QDeclarativeWorkerListModel::get() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + QCOMPARE(model->get(0).property("name").toString(), QString("A")); + + qApp->processEvents(); +} + +void tst_QDeclarativeWorkerListModel::set() +{ + QDeclarativeComponent component(&m_engine, SRCDIR "/data/model.qml"); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item != 0); + QDeclarativeWorkerListModel *model = item->property("model").value<QDeclarativeWorkerListModel*>(); + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "append({'name': 'A'})"))); + QTRY_COMPARE(model->count(), 1); + + QTest::ignoreMessage(QtWarningMsg, modificationWarning().constData()); + model->set(0, QScriptValue(1)); + + QVERIFY(QMetaObject::invokeMethod(item, "workerModifyModel", Q_ARG(QVariant, "set(0, {'name': 'Z'})"))); + QTRY_COMPARE(model->get(0).property("name").toString(), QString("Z")); + + qApp->processEvents(); +} + +QTEST_MAIN(tst_QDeclarativeWorkerListModel) + +#include "tst_qdeclarativeworkerlistmodel.moc" + diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index 15b6204..bd54975 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -513,6 +513,19 @@ void tst_QMetaObject::invokeMetaMember() QVERIFY(QMetaObject::invokeMethod(&obj, "sig1", Q_RETURN_ARG(QString, exp), Q_ARG(QString, "hehe"))); QCOMPARE(exp, QString("yessir")); QCOMPARE(obj.slotResult, QString("sl1:hehe")); + + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::doesNotExist()"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "doesNotExist")); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString)(QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1(QString)", Q_ARG(QString, "arg"))); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl3(QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl3", Q_ARG(QString, "arg"))); + QTest::ignoreMessage(QtWarningMsg, "QMetaObject::invokeMethod: No such method QtTestObject::sl1(QString,QString,QString)"); + QVERIFY(!QMetaObject::invokeMethod(&obj, "sl1", Q_ARG(QString, "arg"), Q_ARG(QString, "arg"), Q_ARG(QString, "arg"))); + + //should not have changed since last test. + QCOMPARE(exp, QString("yessir")); + QCOMPARE(obj.slotResult, QString("sl1:hehe")); } void tst_QMetaObject::invokeQueuedMetaMember() diff --git a/tools/assistant/tools/assistant/findwidget.cpp b/tools/assistant/tools/assistant/findwidget.cpp index 2e40ab0..60318d4 100644 --- a/tools/assistant/tools/assistant/findwidget.cpp +++ b/tools/assistant/tools/assistant/findwidget.cpp @@ -72,6 +72,7 @@ FindWidget::FindWidget(QWidget *parent) toolClose = setupToolButton(QLatin1String(""), resourcePath + QLatin1String("/closetab.png")); hboxLayout->addWidget(toolClose); + connect(toolClose, SIGNAL(clicked()), SLOT(hide())); editFind = new QLineEdit(this); hboxLayout->addWidget(editFind); diff --git a/tools/qdoc3/test/qml.qdocconf b/tools/qdoc3/test/qdeclarative.qdocconf index 3b5d8dc..3b5d8dc 100644 --- a/tools/qdoc3/test/qml.qdocconf +++ b/tools/qdoc3/test/qdeclarative.qdocconf diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 9c9c398..9b68dbc 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -41,9 +41,11 @@ INSTALLS += target wince* { QT += scripttools \ xml \ - xmlpatterns \ phonon + contains(QT_CONFIG, xmlpatterns) { + QT += xmlpatterns + } contains(QT_CONFIG, webkit) { QT += webkit } |