aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/types
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-12-14 19:01:23 +0100
committerLiang Qi <liang.qi@qt.io>2016-12-14 19:01:23 +0100
commit0e80d28aa5892d6bbb4d0017b1bc9a33489f4176 (patch)
tree0db2e10c8776d172bccaeaa7ee1fab3934b93073 /src/qml/types
parented32558d6280cae40578f735fd326327d571d993 (diff)
parent16c81bb0d493af00bc376784bcb7e03a4a037b04 (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.cpp23
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h3
-rw-r--r--src/qml/types/qqmllistmodel.cpp48
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h2
-rw-r--r--src/qml/types/qquickworkerscript.cpp16
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();