diff options
author | Liang Qi <liang.qi@qt.io> | 2016-12-14 19:01:23 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-12-14 19:01:23 +0100 |
commit | 0e80d28aa5892d6bbb4d0017b1bc9a33489f4176 (patch) | |
tree | 0db2e10c8776d172bccaeaa7ee1fab3934b93073 /src/qml/types | |
parent | ed32558d6280cae40578f735fd326327d571d993 (diff) | |
parent | 16c81bb0d493af00bc376784bcb7e03a4a037b04 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts:
src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
src/qml/qml/qqmlimport.cpp
src/quick/items/context2d/qquickcontext2dtexture_p.h
tools/qmleasing/splineeditor.h
Change-Id: I8f6630fcac243824350986c8e9f4bd6483bf20b5
Diffstat (limited to 'src/qml/types')
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 23 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel_p_p.h | 3 | ||||
-rw-r--r-- | src/qml/types/qqmllistmodel.cpp | 48 | ||||
-rw-r--r-- | src/qml/types/qqmllistmodel_p_p.h | 2 | ||||
-rw-r--r-- | src/qml/types/qquickworkerscript.cpp | 16 |
5 files changed, 64 insertions, 28 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index c4fabbedcc..be10b270ae 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -213,6 +213,7 @@ QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt) , m_reset(false) , m_transaction(false) , m_incubatorCleanupScheduled(false) + , m_waitingToFetchMore(false) , m_cacheItems(0) , m_items(0) , m_persistedItems(0) @@ -227,6 +228,15 @@ QQmlDelegateModelPrivate::~QQmlDelegateModelPrivate() m_cacheMetaType->release(); } +void QQmlDelegateModelPrivate::requestMoreIfNecessary() +{ + Q_Q(QQmlDelegateModel); + if (!m_waitingToFetchMore && m_adaptorModel.canFetchMore()) { + m_waitingToFetchMore = true; + QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest)); + } +} + void QQmlDelegateModelPrivate::init() { Q_Q(QQmlDelegateModel); @@ -334,9 +344,7 @@ void QQmlDelegateModel::componentComplete() &inserts); d->itemsInserted(inserts); d->emitChanges(); - - if (d->m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); + d->requestMoreIfNecessary(); } /*! @@ -375,8 +383,7 @@ void QQmlDelegateModel::setModel(const QVariant &model) if (d->m_complete) { _q_itemsInserted(0, d->m_adaptorModel.count()); - if (d->m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); + d->requestMoreIfNecessary(); } } @@ -922,7 +929,6 @@ void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTas QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bool asynchronous) { - Q_Q(QQmlDelegateModel); if (!m_delegate || index < 0 || index >= m_compositor.count(group)) { qWarning() << "DelegateModel::item: index out range" << index << m_compositor.count(group); return 0; @@ -989,8 +995,8 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo QQmlContextData::get(m_context)); } - if (index == m_compositor.count(group) - 1 && m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest)); + if (index == m_compositor.count(group) - 1) + requestMoreIfNecessary(); // Remove the temporary reference count. cacheItem->scriptRef -= 1; @@ -1110,6 +1116,7 @@ bool QQmlDelegateModel::event(QEvent *e) { Q_D(QQmlDelegateModel); if (e->type() == QEvent::UpdateRequest) { + d->m_waitingToFetchMore = false; d->m_adaptorModel.fetchMore(); } else if (e->type() == QEvent::User) { d->m_incubatorCleanupScheduled = false; diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 07e35d3fd7..4c2841b8ba 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -149,7 +149,6 @@ public: int groups; int index; - Q_SIGNALS: void modelIndexChanged(); @@ -261,6 +260,7 @@ public: void init(); void connectModel(QQmlAdaptorModel *model); + void requestMoreIfNecessary(); QObject *object(Compositor::Group group, int index, bool asynchronous); QQmlDelegateModel::ReleaseFlags release(QObject *object); QString stringValue(Compositor::Group group, int index, const QString &name); @@ -329,6 +329,7 @@ public: bool m_reset : 1; bool m_transaction : 1; bool m_incubatorCleanupScheduled : 1; + bool m_waitingToFetchMore : 1; union { struct { diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 062f7a2a74..1a2e4c7f6f 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -45,10 +45,12 @@ #include <private/qqmlcustomparser_p.h> #include <private/qqmlengine_p.h> +#include <private/qqmlnotifier_p.h> #include <private/qv4object_p.h> #include <private/qv4dateobject_p.h> #include <private/qv4objectiterator_p.h> +#include <private/qv4alloca_p.h> #include <qqmlcontext.h> #include <qqmlinfo.h> @@ -57,6 +59,7 @@ #include <QtCore/qstack.h> #include <QXmlStreamReader> #include <QtCore/qdatetime.h> +#include <QScopedValueRollback> QT_BEGIN_NAMESPACE @@ -502,10 +505,10 @@ void ListModel::set(int elementIndex, QV4::Object *object) break; // Add the value now - if (propertyValue->isString()) { + if (QV4::String *s = propertyValue->stringValue()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); if (r.type == ListLayout::Role::String) - e->setStringPropertyFast(r, propertyValue->stringValue()->toQString()); + e->setStringPropertyFast(r, s->toQString()); } else if (propertyValue->isNumber()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); if (r.type == ListLayout::Role::Number) { @@ -1262,9 +1265,14 @@ ModelNodeMetaObject *ModelNodeMetaObject::get(QObject *obj) void ModelNodeMetaObject::updateValues() { - if (!m_initialized) + const int roleCount = m_model->m_listModel->roleCount(); + if (!m_initialized) { + int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int))); + for (int i = 0; i < roleCount; ++i) + changedRoles[i] = i; + emitDirectNotifies(changedRoles, roleCount); return; - int roleCount = m_model->m_listModel->roleCount(); + } for (int i=0 ; i < roleCount ; ++i) { const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i); QByteArray name = role.name.toUtf8(); @@ -1275,8 +1283,10 @@ void ModelNodeMetaObject::updateValues() void ModelNodeMetaObject::updateValues(const QVector<int> &roles) { - if (!m_initialized) + if (!m_initialized) { + emitDirectNotifies(roles.constData(), roles.count()); return; + } int roleCount = roles.count(); for (int i=0 ; i < roleCount ; ++i) { int roleIndex = roles.at(i); @@ -1303,6 +1313,22 @@ void ModelNodeMetaObject::propertyWritten(int index) m_model->emitItemsChanged(m_elementIndex, 1, QVector<int>(1, roleIndex)); } +// Does the emission of the notifiers when we haven't created the meta-object yet +void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCount) +{ + Q_ASSERT(!m_initialized); + QQmlData *ddata = QQmlData::get(object(), /*create*/false); + if (!ddata) + return; + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine(m_model)); + if (!ep) + return; + for (int i = 0; i < roleCount; ++i) { + const int changedRole = changedRoles[i]; + QQmlNotifier::notify(ddata, changedRole); + } +} + namespace QV4 { void ModelObject::put(Managed *m, String *name, const Value &value) @@ -1329,6 +1355,18 @@ ReturnedValue ModelObject::get(const Managed *m, String *name, bool *hasProperty return QObjectWrapper::get(m, name, hasProperty); if (hasProperty) *hasProperty = true; + + if (QQmlEngine *qmlEngine = that->engine()->qmlEngine()) { + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine); + if (ep && ep->propertyCapture) { + QObjectPrivate *op = QObjectPrivate::get(that->object()); + // Temporarily hide the dynamic meta-object, to prevent it from being created when the capture + // triggers a QObject::connectNotify() by calling obj->metaObject(). + QScopedValueRollback<QDynamicMetaObjectData*> metaObjectBlocker(op->metaObject, 0); + ep->propertyCapture->captureProperty(that->object(), -1, role->index); + } + } + const int elementIndex = that->d()->m_elementIndex; QVariant value = that->d()->m_model->data(elementIndex, role->index); return that->engine()->fromVariant(value); diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h index ddf77e52c0..cdce78e542 100644 --- a/src/qml/types/qqmllistmodel_p_p.h +++ b/src/qml/types/qqmllistmodel_p_p.h @@ -153,6 +153,8 @@ private: setValue(name, val); } + void emitDirectNotifies(const int *changedRoles, int roleCount); + void initialize(); bool m_initialized; }; diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index cdcc894da9..5f716da17a 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -42,7 +42,6 @@ #include "qqmllistmodelworkeragent_p.h" #include <private/qqmlengine_p.h> #include <private/qqmlexpression_p.h> -#include <private/qqmlcontextwrapper_p.h> #include <QtCore/qcoreevent.h> #include <QtCore/qcoreapplication.h> @@ -318,19 +317,8 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *scri QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine); QV4::Scope scope(v4); - - QV4::Scoped<QV4::QmlContextWrapper> w(scope, QV4::QmlContextWrapper::urlScope(v4, script->source)); - Q_ASSERT(!!w); - w->setReadOnly(false); - - QV4::ScopedObject api(scope, v4->newObject()); - api->put(QV4::ScopedString(scope, v4->newString(QStringLiteral("sendMessage"))), QV4::ScopedValue(scope, workerEngine->sendFunction(script->id))); - - w->QV4::Object::put(QV4::ScopedString(scope, v4->newString(QStringLiteral("WorkerScript"))), api); - - w->setReadOnly(true); - - script->qmlContext.set(v4, v4->rootContext()->newQmlContext(w)); + QV4::ScopedValue v(scope, workerEngine->sendFunction(script->id)); + script->qmlContext.set(v4, QV4::QmlContext::createWorkerContext(v4->rootContext(), script->source, v)); } return script->qmlContext.value(); |