1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquicklistmodelworkeragent_p.h"
43 #include "qquicklistmodel_p_p.h"
44 #include <private/qqmldata_p.h>
45 #include <private/qqmlengine_p.h>
48 #include <QtCore/qcoreevent.h>
49 #include <QtCore/qcoreapplication.h>
50 #include <QtCore/qdebug.h>
56 void QQuickListModelWorkerAgent::Data::clearChange(int uid)
58 for (int i=0 ; i < changes.count() ; ++i) {
59 if (changes[i].modelUid == uid) {
66 void QQuickListModelWorkerAgent::Data::insertChange(int uid, int index, int count)
68 Change c = { uid, Change::Inserted, index, count, 0, QVector<int>() };
72 void QQuickListModelWorkerAgent::Data::removeChange(int uid, int index, int count)
74 Change c = { uid, Change::Removed, index, count, 0, QVector<int>() };
78 void QQuickListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to)
80 Change c = { uid, Change::Moved, index, count, to, QVector<int>() };
84 void QQuickListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles)
86 Change c = { uid, Change::Changed, index, count, 0, roles };
90 QQuickListModelWorkerAgent::QQuickListModelWorkerAgent(QQuickListModel *model)
91 : m_ref(1), m_orig(model), m_copy(new QQuickListModel(model, this))
95 QQuickListModelWorkerAgent::~QQuickListModelWorkerAgent()
102 void QQuickListModelWorkerAgent::setV8Engine(QV8Engine *eng)
104 m_copy->m_engine = eng;
107 void QQuickListModelWorkerAgent::addref()
112 void QQuickListModelWorkerAgent::release()
114 bool del = !m_ref.deref();
120 void QQuickListModelWorkerAgent::modelDestroyed()
125 int QQuickListModelWorkerAgent::count() const
127 return m_copy->count();
130 void QQuickListModelWorkerAgent::clear()
135 void QQuickListModelWorkerAgent::remove(QQmlV8Function *args)
137 m_copy->remove(args);
140 void QQuickListModelWorkerAgent::append(QQmlV8Function *args)
142 m_copy->append(args);
145 void QQuickListModelWorkerAgent::insert(QQmlV8Function *args)
147 m_copy->insert(args);
150 QQmlV8Handle QQuickListModelWorkerAgent::get(int index) const
152 return m_copy->get(index);
155 void QQuickListModelWorkerAgent::set(int index, const QQmlV8Handle &value)
157 m_copy->set(index, value);
160 void QQuickListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
162 m_copy->setProperty(index, property, value);
165 void QQuickListModelWorkerAgent::move(int from, int to, int count)
167 m_copy->move(from, to, count);
170 void QQuickListModelWorkerAgent::sync()
175 data.changes.clear();
178 QCoreApplication::postEvent(this, s);
179 syncDone.wait(&mutex);
183 bool QQuickListModelWorkerAgent::event(QEvent *e)
185 if (e->type() == QEvent::User) {
187 QMutexLocker locker(&mutex);
189 Sync *s = static_cast<Sync *>(e);
190 const QList<Change> &changes = s->data.changes;
192 cc = m_orig->count() != s->list->count();
194 QHash<int, QQuickListModel *> targetModelDynamicHash;
195 QHash<int, ListModel *> targetModelStaticHash;
197 Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
198 if (m_orig->m_dynamicRoles)
199 QQuickListModel::sync(s->list, m_orig, &targetModelDynamicHash);
201 ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
203 for (int ii = 0; ii < changes.count(); ++ii) {
204 const Change &change = changes.at(ii);
206 QQuickListModel *model = 0;
207 if (m_orig->m_dynamicRoles) {
208 model = targetModelDynamicHash.value(change.modelUid);
210 ListModel *lm = targetModelStaticHash.value(change.modelUid);
212 model = lm->m_modelCache;
216 switch (change.type) {
217 case Change::Inserted:
218 model->beginInsertRows(
219 QModelIndex(), change.index, change.index + change.count - 1);
220 model->endInsertRows();
222 case Change::Removed:
223 model->beginRemoveRows(
224 QModelIndex(), change.index, change.index + change.count - 1);
225 model->endRemoveRows();
228 model->beginMoveRows(
231 change.index + change.count - 1,
233 change.to > change.index ? change.to + change.count : change.to);
234 model->endMoveRows();
236 case Change::Changed:
237 emit model->dataChanged(
238 model->createIndex(change.index, 0),
239 model->createIndex(change.index + change.count - 1, 0),
251 emit m_orig->countChanged();
255 return QObject::event(e);