delete this;
}
+void QDeclarativeListModelWorkerAgent::modelDestroyed()
+{
+ m_orig = 0;
+}
+
int QDeclarativeListModelWorkerAgent::count() const
{
return m_copy->count();
bool QDeclarativeListModelWorkerAgent::event(QEvent *e)
{
if (e->type() == QEvent::User) {
-
+ bool cc = false;
QMutexLocker locker(&mutex);
- Sync *s = static_cast<Sync *>(e);
-
- const QList<Change> &changes = s->data.changes;
-
- bool cc = m_orig->count() != s->list->count();
-
- QHash<int, QDeclarativeListModel *> targetModelDynamicHash;
- QHash<int, ListModel *> targetModelStaticHash;
-
- Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
- if (m_orig->m_dynamicRoles)
- QDeclarativeListModel::sync(s->list, m_orig, &targetModelDynamicHash);
- else
- ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
-
- for (int ii = 0; ii < changes.count(); ++ii) {
- const Change &change = changes.at(ii);
-
- QDeclarativeListModel *model = 0;
- if (m_orig->m_dynamicRoles) {
- model = targetModelDynamicHash.value(change.modelUid);
- } else {
- ListModel *lm = targetModelStaticHash.value(change.modelUid);
- if (lm)
- model = lm->m_modelCache;
- }
+ if (m_orig) {
+ Sync *s = static_cast<Sync *>(e);
+ const QList<Change> &changes = s->data.changes;
+
+ cc = m_orig->count() != s->list->count();
+
+ QHash<int, QDeclarativeListModel *> targetModelDynamicHash;
+ QHash<int, ListModel *> targetModelStaticHash;
+
+ Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
+ if (m_orig->m_dynamicRoles)
+ QDeclarativeListModel::sync(s->list, m_orig, &targetModelDynamicHash);
+ else
+ ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
+
+ for (int ii = 0; ii < changes.count(); ++ii) {
+ const Change &change = changes.at(ii);
+
+ QDeclarativeListModel *model = 0;
+ if (m_orig->m_dynamicRoles) {
+ model = targetModelDynamicHash.value(change.modelUid);
+ } else {
+ ListModel *lm = targetModelStaticHash.value(change.modelUid);
+ if (lm)
+ model = lm->m_modelCache;
+ }
- if (model) {
- switch (change.type) {
- case Change::Inserted:
- emit model->itemsInserted(change.index, change.count);
- break;
- case Change::Removed:
- emit model->itemsRemoved(change.index, change.count);
- break;
- case Change::Moved:
- emit model->itemsMoved(change.index, change.to, change.count);
- break;
- case Change::Changed:
- emit model->itemsChanged(change.index, change.count, change.roles);
- break;
+ if (model) {
+ switch (change.type) {
+ case Change::Inserted:
+ emit model->itemsInserted(change.index, change.count);
+ break;
+ case Change::Removed:
+ emit model->itemsRemoved(change.index, change.count);
+ break;
+ case Change::Moved:
+ emit model->itemsMoved(change.index, change.to, change.count);
+ break;
+ case Change::Changed:
+ emit model->itemsChanged(change.index, change.count, change.roles);
+ break;
+ }
}
}
}
bool QDeclarativeWorkerScriptEnginePrivate::event(QEvent *event)
{
- // XXX must handle remove request
if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
processMessage(workerEvent->workerId(), workerEvent->data());
} else if (event->type() == (QEvent::Type)WorkerDestroyEvent) {
emit stopThread();
return true;
+ } else if (event->type() == (QEvent::Type)WorkerRemoveEvent::WorkerRemove) {
+ WorkerRemoveEvent *workerEvent = static_cast<WorkerRemoveEvent *>(event);
+ workers.remove(workerEvent->workerId());
+ return true;
} else {
return QObject::event(event);
}
void QDeclarativeWorkerScriptEngine::removeWorkerScript(int id)
{
- QCoreApplication::postEvent(d, new WorkerRemoveEvent(id));
+ QDeclarativeWorkerScriptEnginePrivate::WorkerScript* script = d->workers.value(id);
+ if (script) {
+ script->owner = 0;
+ QCoreApplication::postEvent(d, new WorkerRemoveEvent(id));
+ }
}
void QDeclarativeWorkerScriptEngine::executeUrl(int id, const QUrl &url)
delete item;
qApp->processEvents();
+
+ {
+ //don't crash if model was deleted earlier
+ QDeclarativeListModel* model = new QDeclarativeListModel;
+ model->setDynamicRoles(dynamicRoles);
+ QDeclarativeEngine eng;
+ QDeclarativeComponent component(&eng, testFileUrl("workerremoveelement.qml"));
+ QQuickItem *item = createWorkerTest(&eng, &component, model);
+ QVERIFY(item != 0);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "addItem"));
+
+ QVERIFY(model->count() == 1);
+
+ QVERIFY(QMetaObject::invokeMethod(item, "removeItemViaWorker"));
+ QVERIFY(QMetaObject::invokeMethod(item, "doSync"));
+ delete model;
+ qApp->processEvents(); //must not crash here
+ waitForWorker(item);
+
+ delete item;
+ }
}
void tst_qdeclarativelistmodel::worker_remove_list_data()