1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qdeclarativechangeset_p.h"
44 void QDeclarativeChangeSet::insertInsert(int start, int end)
46 const int count = end - start;
49 QVector<Move>::iterator move = m_moves.begin();
50 for (; move != m_moves.end() && start >= move->maximum(); ++move) {}
51 for (; move != m_moves.end() && end >= move->minimum(); ++move) {
52 if (start <= move->tstart) {
53 move->tstart += count;
55 } else if (start < move->tend) {
56 int relativeStart = start - move->tstart;
58 move = m_moves.insert(move, Move(
59 move->fstart + count, move->fstart + count + relativeStart, move->tstart));
61 move->fstart += relativeStart;
62 move->tstart += count + relativeStart;
65 start -= relativeStart;
68 start -= move->count();
72 if (start <= move->fstart) {
73 move->fstart += count;
75 } else if (start < move->tstart) {
76 start += move->count();
81 for (; move != m_moves.end(); ++move) {
82 move->fstart += count;
84 move->tstart += count;
89 QVector<Insert>::iterator insert = m_inserts.begin();
90 for (; insert != m_inserts.end(); ++insert) {
91 if (start < insert->start) {
92 insert = m_inserts.insert(insert, Insert(start, end));
94 } else if (start <= insert->end) {
99 if (insert == m_inserts.end()) {
100 m_inserts.append(Insert(start, end));
101 } else for (++insert; insert != m_inserts.end(); ++insert) {
102 insert->start += count;
103 insert->end += count;
108 QVector<Change>::iterator change = m_changes.begin();
109 for (; change != m_changes.end() && start != change->start && start < change->end; ++change) {
110 if (start > change->start) {
111 int relativeStart = start - change->start;
112 change = m_changes.insert(change, Change(change->start, change->start + relativeStart));
114 change->start += count + relativeStart;
115 change->end += count - relativeStart;
119 for (; change != m_changes.end(); ++change) {
120 change->start += count;
121 change->end += count;
125 void QDeclarativeChangeSet::insertRemove(int start, int end)
128 QVector<Change>::iterator change = m_changes.begin();
129 for (; change != m_changes.end() && start >= change->end; ++change) {}
130 for (; change != m_changes.end() && end < change->start; ++change) {
131 const int removeCount = qMin(change->end, end) - qMax(change->start, start);
132 change->end -= removeCount;
133 if (change->start == change->end) {
134 change = m_changes.erase(change);
135 } else if (start < change->start) {
136 change->start = start;
139 const int count = end - start;
140 for (; change != m_changes.end(); ++change) {
141 change->start -= count;
142 change->end -= count;
145 QVector<Remove> removeChanges;
148 QVector<Move>::iterator move = m_moves.begin();
149 for (; move != m_moves.end() && start >= move->maximum(); ++move) {}
150 for (; move != m_moves.end() && end >= move->minimum(); ++move) {
151 if (move->fstart < move->tstart) {
152 if (start < move->fstart) {
153 const int difference = move->fstart - start;
154 move->fend -= difference;
155 move->fstart = start;
156 move->tstart -= difference;
157 move->tend -= difference;
159 removeChanges.append(Remove(start, start + difference));
162 if (end < move->tstart) {
163 move->tstart -= end - start;
164 move->tend -= end - start;
165 } else if (start < move->tend) {
166 const int difference = qMin(move->tend, end) - move->tstart;
167 removeChanges.append(Remove(
168 move->fstart , move->fstart + difference));
171 move->fend -= difference;
172 move->tstart -= end - start;
173 move->tend -= end - start + difference;
175 start += move->count();
176 end += move->count();
178 if (start < move->tend) {
179 const int offset = qMax(0, start - move->tstart);
180 const int difference = qMin(move->tend, end) - qMax(move->tstart, start);
182 removeChanges.append(Remove(
183 move->fstart + offset, move->fstart + offset + difference));
185 end -= offset + difference;
187 move->fend -= difference;
188 move->tstart = start;
189 move->tend = start + move->fend - move->fstart;
191 start -= move->count();
192 end -= move->count();
195 move->fstart -= end - start;
196 move->fend -= end - start;
198 if (start > move->fstart) {
199 const int offset = start - move->fstart;
200 const int difference = qMin(move->fend, end) - start;
201 removeChanges.append(Remove(
202 move->fstart + end - start + offset + difference ,
203 move->fend + end - start + offset));
205 move->fstart += offset;
206 move->fend += offset;
210 if (move->tstart == move->tend || move->fstart == move->tstart) {
211 move = m_moves.erase(move);
215 for (; move != m_moves.end(); ++move) {
216 move->fstart -= count;
218 move->tstart -= count;
223 removeChanges.append(Remove(start, end));
225 foreach (const Remove &r, removeChanges) {
229 QVector<Insert>::iterator insert = m_inserts.end() - 1;
230 for (const int count = end - start; insert != m_inserts.begin() - 1 && insert->start >= end; --insert) {
231 insert->start -= count;
232 insert->end -= count;
234 for (; insert != m_inserts.begin() - 1 && insert->end > start; --insert) {
235 const int removeCount = qMin(insert->end, end) - qMax(insert->start, start);
236 insert->end -= removeCount;
237 if (insert->start == insert->end) {
238 insert = m_inserts.erase(insert);
239 } else if (start < insert->start) {
240 insert->end -= insert->start - start;
241 insert->start = start;
243 start -= insert->count();
244 end -= insert->count();
250 // Adjust the index to compensate for any inserts prior to the remove position..
251 for (; insert != m_inserts.begin() - 1; --insert) {
252 start -= insert->count();
253 end -= insert->count();
257 QVector<Remove>::iterator remove = m_removes.begin();
258 for (; remove != m_removes.end(); ++remove) {
259 if (end < remove->start) {
260 remove = m_removes.insert(remove, Remove(start, end));
262 } else if (start <= remove->start) {
263 remove->end += end - remove->start;
264 remove->start = start;
266 QVector<Remove>::iterator rbegin = remove;
267 QVector<Remove>::iterator rend = ++rbegin;
268 for (; rend != m_removes.end() && rend->start <= remove->end; ++rend)
269 remove->end += rend->count();
270 if (rbegin != rend) {
271 remove = m_removes.erase(rbegin, rend);
276 if (remove != m_removes.end()) {
277 const int count = end - start;
278 for (++remove; remove != m_removes.end(); ++remove) {
279 remove->start -= count;
280 remove->end -= count;
283 m_removes.append(Remove(start, end));
288 void QDeclarativeChangeSet::insertMove(int start, int end, int to)
290 QVector<Insert> insertChanges;
291 QVector<Move> moveChanges;
297 int bEnd = to + end - start;
300 qSwap(fStart, bStart);
305 QVector<Insert>::iterator insert = m_inserts.begin();
307 for (; insert != m_inserts.end() && fStart >= insert->end; ++insert) {}
308 for (; insert != m_inserts.end() && fEnd > insert->start; ++insert) {
309 const int removeCount = qMin(insert->end, fEnd) - qMax(insert->start, fStart);
310 const int relativeStart = fStart - insert->start;
311 const int relativeEnd = qMax(0, fEnd - insert->end);
313 insert->end -= removeCount;
314 if (insert->start == insert->end) {
315 insert = m_inserts.erase(insert);
319 if (relativeStart < 0) {
320 moveChanges.append(Move(fStart, fStart - relativeStart, fTo + relativeEnd));
321 fTo -= relativeStart;
325 insertChanges.append(Insert(bEnd - removeCount, bEnd));
328 for (; insert != m_inserts.end() && bStart >= insert->end; ++insert) {}
329 for (; insert != m_inserts.end() && bEnd > insert->start; ++insert) {
330 const int removeCount = qMin(insert->end, bEnd) - qMax(insert->start, bStart);
331 const int relativeStart = bStart - insert->start;
333 insert->start += removeCount;
334 if (insert->start == insert->end) {
335 insert->start = fStart;
336 insert->end = insert->start + removeCount;
338 insert = m_inserts.insert(insert, Insert(fStart, fStart + removeCount));
341 if (relativeStart < 0) {
342 moveChanges.append(Move(fStart, fStart - relativeStart, fTo + removeCount));
343 fStart -= relativeStart;
344 fTo -= relativeStart;
346 fStart += removeCount;
352 moveChanges.append(Move(fStart, fStart + bEnd - fTo, fTo));
354 QVector<Insert>::iterator it = insertChanges.begin();
355 for (insert = m_inserts.begin(); it != insertChanges.end() && insert != m_inserts.end();++insert) {
356 if (it->start < insert->start) {
357 insert = m_inserts.insert(insert, *it);
359 } else if (it->start <= insert->end) {
360 insert->end += it->count();
364 for (; it != insertChanges.end(); ++it)
365 m_inserts.append(*it);
367 // Insert queued moved signals ordered by destination position.
368 QVector<Move>::iterator move = m_moves.begin();
370 for (QVector<Move>::iterator it = moveChanges.begin(); it != moveChanges.end(); ++it) {
371 it->fend += it->tstart - it->fstart;
372 it->tend -=it->tstart - it->fstart;
373 qSwap(it->fstart, it->tstart);
374 for (; move != m_moves.end() && it->to >= qMin(move->fstart, move->tstart); ++move) {}
375 move = m_moves.insert(move, *it);
378 for (QVector<Move>::iterator it = moveChanges.begin(); it != moveChanges.end(); ++it) {
379 for (; move != m_moves.end() && it->start >= qMin(move->fstart, move->tstart); ++move) {}
380 move = m_moves.insert(move, *it);
385 void QDeclarativeChangeSet::insertChange(int start, int end)
387 QVector<Change> filteredChanges;
389 // Inserted signals (don't emit change signals on new items).
390 QVector<Insert>::iterator insert = m_inserts.begin();
391 for (; insert != m_inserts.end() && start >= insert->end; ++insert) {}
392 for (; insert != m_inserts.end() && end > insert->start; ++insert) {
393 if (start < insert->start)
394 filteredChanges.append(Change(start, insert->start));
398 filteredChanges.append(Change(start, end));
400 // Find the union of the existing and filtered sets of change signals.
401 QVector<Change>::iterator change = m_changes.begin();
402 for (QVector<Change>::iterator it = filteredChanges.begin(); it != filteredChanges.end(); ++it) {
403 for (; change != m_changes.end() && change->end < it->start; ++change) {}
404 if (change == m_changes.end() || change->start > it->end) {
405 change = m_changes.insert(change, *it);
407 if (it->start < change->start)
408 change->start = it->start;
410 if (it->end > change->end) {
411 change->end = it->end;
412 QVector<Change>::iterator rbegin = change;
413 QVector<Change>::iterator rend = ++rbegin;
414 for (; rend != m_changes.end() && rend->start <= change->end; ++rend) {
415 if (rend->end > change->end)
416 change->end = rend->end;
418 if (rbegin != rend) {
419 change = m_changes.erase(rbegin, rend);
428 QDebug operator <<(QDebug debug, const QDeclarativeChangeSet &set)
430 foreach (const QDeclarativeChangeSet::Remove &remove, set.removes())
431 debug.nospace() << "QDeclarativeChangeSet::Remove(" << remove.start << "," << remove.end << ")";
432 foreach (const QDeclarativeChangeSet::Insert &insert, set.inserts())
433 debug.nospace() << "QDeclarativeChangeSet::Insert(" << insert.start << "," << insert.end << ")";
434 foreach (const QDeclarativeChangeSet::Move &move, set.moves())
435 debug.nospace() << "QDeclarativeChangeSet::Move(" << move.start << "," << move.end << "," << move.to << ")";
436 foreach (const QDeclarativeChangeSet::Change &change, set.changes())
437 debug.nospace() << "QDeclarativeChangeSet::Change(" << change.start << "," << change.end << ")";