bc1c6a7c196c06d65921bf9a39411367a830c24e
[profile/ivi/qtdeclarative.git] / src / quick / util / qdeclarativelistcompositor_p.h
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 #ifndef QDECLARATIVELISTCOMPOSITOR_P_H
43 #define QDECLARATIVELISTCOMPOSITOR_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists purely as an
50 // implementation detail.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include <QtCore/qglobal.h>
57 #include <QtCore/qvector.h>
58
59 #include <private/qdeclarativechangeset_p.h>
60
61 #include <QtCore/qdebug.h>
62
63 QT_BEGIN_NAMESPACE
64
65 class Q_AUTOTEST_EXPORT QDeclarativeListCompositor
66 {
67 public:
68     enum { MinimumGroupCount = 3, MaximumGroupCount = 11 };
69
70     enum Group
71     {
72         Cache   = 0,
73         Default = 1,
74         Persisted = 2
75     };
76
77     enum Flag
78     {
79         CacheFlag       = 1 << Cache,
80         DefaultFlag     = 1 << Default,
81         PersistedFlag   = 1 << Persisted,
82         PrependFlag     = 0x10000000,
83         AppendFlag      = 0x20000000,
84         UnresolvedFlag  = 0x40000000,
85         MovedFlag       = 0x80000000,
86         GroupMask       = ~(PrependFlag | AppendFlag | UnresolvedFlag | MovedFlag | CacheFlag)
87     };
88
89     class Range
90     {
91     public:
92         Range() : next(this), previous(this), list(0), index(0), count(0), flags(0) {}
93         Range(Range *next, void *list, int index, int count, uint flags)
94             : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
95             next->previous = this; previous->next = this; }
96
97         Range *next;
98         Range *previous;
99         void *list;
100         int index;
101         int count;
102         uint flags;
103
104         inline int start() const { return index; }
105         inline int end() const { return index + count; }
106
107         inline int groups() const { return flags & GroupMask; }
108
109         inline bool inGroup() const { return flags & GroupMask; }
110         inline bool inCache() const { return flags & CacheFlag; }
111         inline bool inGroup(int group) const { return flags & (1 << group); }
112         inline bool isUnresolved() const { return flags & UnresolvedFlag; }
113
114         inline bool prepend() const { return flags & PrependFlag; }
115         inline bool append() const { return flags & AppendFlag; }
116     };
117
118     class Q_AUTOTEST_EXPORT iterator
119     {
120     public:
121         inline iterator();
122         inline iterator(const iterator &it);
123         inline iterator(Range *range, int offset, Group group, int groupCount);
124         inline ~iterator() {}
125
126         bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; }
127         bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; }
128
129         bool operator ==(Group group) const { return range->flags & (1 << group); }
130         bool operator !=(Group group) const { return !(range->flags & (1 << group)); }
131
132         Range *&operator *() { return range; }
133         Range * const &operator *() const { return range; }
134         Range *operator ->() { return range; }
135         const Range *operator ->() const { return range; }
136
137         iterator &operator +=(int difference);
138         iterator &operator -=(int difference);
139
140         template<typename T> T *list() const { return static_cast<T *>(range->list); }
141         int modelIndex() const { return range->index + offset; }
142
143         void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); }
144         void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); }
145
146         inline void incrementIndexes(int difference, uint flags);
147         inline void decrementIndexes(int difference, uint flags);
148
149         void setGroup(Group g) { group = g; groupFlag = 1 << g; }
150
151         Range *range;
152         int offset;
153         Group group;
154         int groupFlag;
155         int groupCount;
156         union {
157             struct {
158                 int cacheIndex;
159             };
160             int index[MaximumGroupCount];
161         };
162     };
163
164     class Q_AUTOTEST_EXPORT insert_iterator : public iterator
165     {
166     public:
167         inline insert_iterator() {}
168         inline insert_iterator(const iterator &it) : iterator(it) {}
169         inline insert_iterator(Range *, int, Group, int);
170         inline ~insert_iterator() {}
171
172         insert_iterator &operator +=(int difference);
173         insert_iterator &operator -=(int difference);
174     };
175
176     struct Change
177     {
178         inline Change() {}
179         inline Change(iterator it, int count, uint flags, int moveId = -1);
180         int count;
181         uint flags;
182         int moveId;
183         union {
184             struct {
185                 int cacheIndex;
186             };
187             int index[MaximumGroupCount];
188         };
189
190         inline bool isMove() const { return moveId >= 0; }
191         inline bool inCache() const { return flags & CacheFlag; }
192         inline bool inGroup() const { return flags & GroupMask; }
193         inline bool inGroup(int group) const { return flags & (CacheFlag << group); }
194
195         inline int groups() const { return flags & GroupMask; }
196     };
197
198     struct Insert : public Change
199     {
200         Insert() {}
201         Insert(iterator it, int count, uint flags, int moveId = -1)
202             : Change(it, count, flags, moveId) {}
203     };
204
205     struct Remove : public Change
206     {
207         Remove() {}
208         Remove(iterator it, int count, uint flags, int moveId = -1)
209             : Change(it, count, flags, moveId) {}
210     };
211
212     QDeclarativeListCompositor();
213     ~QDeclarativeListCompositor();
214
215     int defaultGroups() const { return m_defaultFlags & ~PrependFlag; }
216     void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; }
217     void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); }
218     void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); }
219     void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; }
220     void setGroupCount(int count);
221
222     int count(Group group) const;
223     iterator find(Group group, int index);
224     iterator find(Group group, int index) const;
225     insert_iterator findInsertPosition(Group group, int index);
226
227     iterator begin(Group group);
228     const iterator &end() { return m_end; }
229
230     void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
231     void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
232     iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
233
234     void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = 0);
235     void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = 0);
236     void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = 0) {
237         setFlags(fromGroup, from, count, fromGroup, flags, inserts); }
238     void setFlags(iterator from, int count, uint flags, QVector<Insert> *inserts = 0) {
239         setFlags(from, count, from.group, flags, inserts); }
240
241     void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
242     void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
243     void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = 0) {
244         clearFlags(fromGroup, from, count, fromGroup, flags, removals); }
245     void clearFlags(iterator from, int count, uint flags, QVector<Remove> *removals = 0) {
246         clearFlags(from, count, from.group, flags, removals); }
247
248     void removeList(void *list, QVector<Remove> *removals, bool destroyed);
249
250     bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const;
251
252     void move(
253             Group fromGroup,
254             int from,
255             Group toGroup,
256             int to,
257             int count,
258             Group group,
259             QVector<Remove> *removals = 0,
260             QVector<Insert> *inserts = 0);
261     void clear();
262
263     void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
264     void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals);
265     void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts);
266     void listItemsChanged(void *list, int index, int count, QVector<Change> *changes);
267     void listChanged(
268             void *list,
269             const QDeclarativeChangeSet &changeSet,
270             QVector<Remove> *removals,
271             QVector<Insert> *inserts,
272             QVector<Change> *changes);
273
274     void transition(
275             Group from,
276             Group to,
277             QVector<QDeclarativeChangeSet::Remove> *removes,
278             QVector<QDeclarativeChangeSet::Insert> *inserts);
279
280 private:
281     Range m_ranges;
282     iterator m_end;
283     iterator m_cacheIt;
284     int m_groupCount;
285     int m_defaultFlags;
286     int m_removeFlags;
287
288     inline Range *insert(Range *before, void *list, int index, int count, uint flags);
289     inline Range *erase(Range *range);
290
291     struct MovedFlags
292     {
293         MovedFlags() {}
294         MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {}
295
296         int moveId;
297         uint flags;
298     };
299
300     void listItemsRemoved(
301             QVector<Remove> *translatedRemovals,
302             void *list,
303             QVector<QDeclarativeChangeSet::Remove> *removals,
304             QVector<QDeclarativeChangeSet::Insert> *insertions = 0,
305             QVector<MovedFlags> *movedFlags = 0,
306             int moveId = 0);
307     void listItemsInserted(
308             QVector<Insert> *translatedInsertions,
309             void *list,
310             const QVector<QDeclarativeChangeSet::Insert> &insertions,
311             const QVector<MovedFlags> *movedFlags = 0);
312     void listItemsChanged(
313             QVector<Change> *translatedChanges,
314             void *list,
315             const QVector<QDeclarativeChangeSet::Change> &changes);
316
317     friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list);
318 };
319
320 inline QDeclarativeListCompositor::iterator::iterator()
321     : range(0), offset(0), group(Default), groupCount(0) {}
322 inline QDeclarativeListCompositor::iterator::iterator(const iterator &it)
323     : range(it.range)
324     , offset(it.offset)
325     , group(it.group)
326     , groupFlag(it.groupFlag)
327     , groupCount(it.groupCount)
328 {
329     for (int i = 0; i < groupCount; ++i)
330         index[i] = it.index[i];
331 }
332
333 inline QDeclarativeListCompositor::iterator::iterator(
334         Range *range, int offset, Group group, int groupCount)
335     : range(range)
336     , offset(offset)
337     , group(group)
338     , groupFlag(1 << group)
339     , groupCount(groupCount)
340 {
341     for (int i = 0; i < groupCount; ++i)
342         index[i] = 0;
343 }
344
345 inline void QDeclarativeListCompositor::iterator::incrementIndexes(int difference, uint flags)
346 {
347     for (int i = 0; i < groupCount; ++i) {
348         if (flags & (1 << i))
349             index[i] += difference;
350     }
351 }
352
353 inline void QDeclarativeListCompositor::iterator::decrementIndexes(int difference, uint flags)
354 {
355     for (int i = 0; i < groupCount; ++i) {
356         if (flags & (1 << i))
357             index[i] -= difference;
358     }
359 }
360
361 inline QDeclarativeListCompositor::insert_iterator::insert_iterator(
362         Range *range, int offset, Group group, int groupCount)
363     : iterator(range, offset, group, groupCount) {}
364
365 inline QDeclarativeListCompositor::Change::Change(iterator it, int count, uint flags, int moveId)
366     : count(count), flags(flags), moveId(moveId)
367 {
368     for (int i = 0; i < MaximumGroupCount; ++i)
369         index[i] = it.index[i];
370 }
371
372 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Group &group);
373 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Range &range);
374 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::iterator &it);
375 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Change &change);
376 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Remove &remove);
377 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Insert &insert);
378 Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list);
379
380 QT_END_NAMESPACE
381
382 #endif