70ec7079df9e6d7d76ec678de0a675a98f59781a
[profile/ivi/qtdeclarative.git] / src / qtquick1 / util / qdeclarativelistmodelworkeragent.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "QtQuick1/private/qdeclarativelistmodelworkeragent_p.h"
43 #include "QtQuick1/private/qdeclarativelistmodel_p_p.h"
44 #include <QtDeclarative/private/qdeclarativedata_p.h>
45 #include <QtDeclarative/private/qdeclarativeengine_p.h>
46 #include <QtDeclarative/qdeclarativeinfo.h>
47
48 #include <QtCore/qcoreevent.h>
49 #include <QtCore/qcoreapplication.h>
50 #include <QtCore/qdebug.h>
51
52
53 QT_BEGIN_NAMESPACE
54
55
56
57
58 void QDeclarative1ListModelWorkerAgent::Data::clearChange() 
59
60     changes.clear(); 
61 }
62
63 void QDeclarative1ListModelWorkerAgent::Data::insertChange(int index, int count) 
64 {
65     Change c = { Change::Inserted, index, count, 0, QList<int>() };
66     changes << c;
67 }
68
69 void QDeclarative1ListModelWorkerAgent::Data::removeChange(int index, int count) 
70 {
71     Change c = { Change::Removed, index, count, 0, QList<int>() };
72     changes << c;
73 }
74
75 void QDeclarative1ListModelWorkerAgent::Data::moveChange(int index, int count, int to)
76 {
77     Change c = { Change::Moved, index, count, to, QList<int>() };
78     changes << c;
79 }
80
81 void QDeclarative1ListModelWorkerAgent::Data::changedChange(int index, int count, const QList<int> &roles)
82 {
83     Change c = { Change::Changed, index, count, 0, roles };
84     changes << c;
85 }
86
87 QDeclarative1ListModelWorkerAgent::QDeclarative1ListModelWorkerAgent(QDeclarative1ListModel *model)
88     : m_engine(0), 
89       m_ref(1), 
90       m_orig(model), 
91       m_copy(new QDeclarative1ListModel(model, this))
92 {
93 }
94
95 QDeclarative1ListModelWorkerAgent::~QDeclarative1ListModelWorkerAgent()
96 {
97 }
98
99 void QDeclarative1ListModelWorkerAgent::setScriptEngine(QScriptEngine *eng)
100 {
101     m_engine = eng;
102     if (m_copy->m_flat)
103         m_copy->m_flat->m_scriptEngine = eng;
104 }
105
106 QScriptEngine *QDeclarative1ListModelWorkerAgent::scriptEngine() const
107 {
108     return m_engine;
109 }
110
111 void QDeclarative1ListModelWorkerAgent::addref()
112 {
113     m_ref.ref();
114 }
115
116 void QDeclarative1ListModelWorkerAgent::release()
117 {
118     bool del = !m_ref.deref();
119
120     if (del)
121         delete this;
122 }
123
124 int QDeclarative1ListModelWorkerAgent::count() const
125 {
126     return m_copy->count();
127 }
128
129 void QDeclarative1ListModelWorkerAgent::clear()
130 {
131     data.clearChange();
132     data.removeChange(0, m_copy->count());
133     m_copy->clear();
134 }
135
136 void QDeclarative1ListModelWorkerAgent::remove(int index)
137 {
138     int count = m_copy->count();
139     m_copy->remove(index);
140
141     if (m_copy->count() != count)
142         data.removeChange(index, 1);
143 }
144
145 void QDeclarative1ListModelWorkerAgent::append(const QScriptValue &value)
146 {
147     int count = m_copy->count();
148     m_copy->append(value);
149
150     if (m_copy->count() != count)
151         data.insertChange(m_copy->count() - 1, 1);
152 }
153
154 void QDeclarative1ListModelWorkerAgent::insert(int index, const QScriptValue &value)
155 {
156     int count = m_copy->count();
157     m_copy->insert(index, value);
158
159     if (m_copy->count() != count)
160         data.insertChange(index, 1);
161 }
162
163 QScriptValue QDeclarative1ListModelWorkerAgent::get(int index) const
164 {
165     return m_copy->get(index);
166 }
167
168 void QDeclarative1ListModelWorkerAgent::set(int index, const QScriptValue &value)
169 {
170     QList<int> roles;
171     m_copy->set(index, value, &roles);
172     if (!roles.isEmpty())
173         data.changedChange(index, 1, roles);
174 }
175
176 void QDeclarative1ListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
177 {
178     QList<int> roles;
179     m_copy->setProperty(index, property, value, &roles);
180     if (!roles.isEmpty())
181         data.changedChange(index, 1, roles);
182 }
183
184 void QDeclarative1ListModelWorkerAgent::move(int from, int to, int count)
185 {
186     m_copy->move(from, to, count);
187     data.moveChange(from, to, count);
188 }
189
190 void QDeclarative1ListModelWorkerAgent::sync()
191 {
192     Sync *s = new Sync;
193     s->data = data;
194     s->list = m_copy;
195     data.changes.clear();
196
197     mutex.lock();
198     QCoreApplication::postEvent(this, s);
199     syncDone.wait(&mutex);
200     mutex.unlock();
201 }
202
203 void QDeclarative1ListModelWorkerAgent::changedData(int index, int count, const QList<int> &roles)
204 {
205     data.changedChange(index, count, roles);
206 }
207
208 bool QDeclarative1ListModelWorkerAgent::event(QEvent *e)
209 {
210     if (e->type() == QEvent::User) {
211         QMutexLocker locker(&mutex);
212         Sync *s = static_cast<Sync *>(e);
213
214         const QList<Change> &changes = s->data.changes;
215
216         if (m_copy) {
217             bool cc = m_orig->count() != s->list->count();
218
219             FlatListModel_1 *orig = m_orig->m_flat;
220             FlatListModel_1 *copy = s->list->m_flat;
221             if (!orig || !copy) {
222                 syncDone.wakeAll();
223                 return QObject::event(e);
224             }
225
226             orig->m_roles = copy->m_roles;
227             orig->m_strings = copy->m_strings;
228             orig->m_values = copy->m_values;
229
230             // update the orig->m_nodeData list
231             for (int ii = 0; ii < changes.count(); ++ii) {
232                 const Change &change = changes.at(ii);
233                 switch (change.type) {
234                 case Change::Inserted:
235                     orig->insertedNode(change.index);
236                     break;
237                 case Change::Removed:
238                     orig->removedNode(change.index);
239                     break;
240                 case Change::Moved:
241                     orig->moveNodes(change.index, change.to, change.count);
242                     break;
243                 case Change::Changed:
244                     break;
245                 }
246             }
247
248             syncDone.wakeAll();
249             locker.unlock();
250
251             for (int ii = 0; ii < changes.count(); ++ii) {
252                 const Change &change = changes.at(ii);
253                 switch (change.type) {
254                 case Change::Inserted:
255                     emit m_orig->itemsInserted(change.index, change.count);
256                     break;
257                 case Change::Removed:
258                     emit m_orig->itemsRemoved(change.index, change.count);
259                     break;
260                 case Change::Moved:
261                     emit m_orig->itemsMoved(change.index, change.to, change.count);
262                     break;
263                 case Change::Changed:
264                     emit m_orig->itemsChanged(change.index, change.count, change.roles);
265                     break;
266                 }
267             }
268
269             if (cc)
270                 emit m_orig->countChanged();
271         } else {
272             syncDone.wakeAll();
273         }
274     }
275
276     return QObject::event(e);
277 }
278
279
280
281 QT_END_NAMESPACE
282