7#include <QtCore/qvarlengtharray.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
70#ifdef QT_QML_VERIFY_MINIMAL
71#define QT_QML_VERIFY_INTEGRITY
73
74
75
76
77
78
79
80
81
83static bool qt_verifyMinimal(
84 const QQmlListCompositor::iterator &begin,
85 const QQmlListCompositor::iterator &end)
90 for (
const QQmlListCompositor::Range *range = begin->next; range != *end; range = range->next, ++index) {
91 if (range->previous->list == range->list
92 && range->previous->flags == (range->flags & ~QQmlListCompositor::AppendFlag)
93 && range->previous->end() == range->index) {
94 qWarning() << index <<
"Consecutive ranges";
95 qWarning() << *range->previous;
106#ifdef QT_QML_VERIFY_INTEGRITY
107static bool qt_printInfo(
const QQmlListCompositor &compositor)
109 qWarning() << compositor;
114
115
116
117
118
119
120
121
123static bool qt_verifyIntegrity(
124 const QQmlListCompositor::iterator &begin,
125 const QQmlListCompositor::iterator &end,
126 const QQmlListCompositor::iterator &cachedIt)
131 QQmlListCompositor::iterator it;
132 for (it = begin; *it != *end; *it = it->next) {
133 if (it->count == 0 && !it->append()) {
134 qWarning() << index <<
"Empty non-append range";
138 qWarning() << index <<
"Negative count";
141 if (it->list && it->flags != QQmlListCompositor::CacheFlag && it->index < 0) {
142 qWarning() << index <<
"Negative index";
145 if (it->previous->next != it.range) {
146 qWarning() << index <<
"broken list: it->previous->next != it.range";
149 if (it->next->previous != it.range) {
150 qWarning() << index <<
"broken list: it->next->previous != it.range";
153 if (*it == *cachedIt) {
154 for (
int i = 0; i < end.groupCount; ++i) {
155 int groupIndex = it.index[i];
156 if (cachedIt->flags & (1 << i))
157 groupIndex += cachedIt.offset;
158 if (groupIndex != cachedIt.index[i]) {
160 <<
"invalid cached index"
161 << QQmlListCompositor::Group(i)
171 it.incrementIndexes(it->count);
175 for (
int i = 0; i < end.groupCount; ++i) {
176 if (end.index[i] != it.index[i]) {
177 qWarning() <<
"Group" << i <<
"count invalid. Expected:" << end.index[i] <<
"Actual:" << it.index[i];
185#if defined(QT_QML_VERIFY_MINIMAL)
186# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0
, Default, m_groupCount), m_end, m_cacheIt)
187 && qt_verifyMinimal(iterator(m_ranges.next, 0
, Default, m_groupCount), m_end))
188 && qt_printInfo(*this)));
189#elif defined(QT_QML_VERIFY_INTEGRITY)
190# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0
, Default, m_groupCount), m_end, m_cacheIt)
191 && qt_printInfo(*this)));
193# define QT_QML_VERIFY_LISTCOMPOSITOR
197#define QT_QML_TRACE_LISTCOMPOSITOR(args)
199QQmlListCompositor::iterator &QQmlListCompositor::iterator::operator +=(
int difference)
202 decrementIndexes(offset);
205 if (!(range->flags & groupFlag))
208 offset += difference;
211 while (offset <= 0 && range->previous->flags) {
212 range = range->previous;
213 if (range->flags & groupFlag)
214 offset += range->count;
215 decrementIndexes(range->count);
220 while (range->flags && (offset >= range->count || !(range->flags & groupFlag))) {
221 if (range->flags & groupFlag)
222 offset -= range->count;
223 incrementIndexes(range->count);
228 incrementIndexes(offset);
233QQmlListCompositor::insert_iterator &QQmlListCompositor::insert_iterator::operator +=(
int difference)
235 iterator::operator +=(difference);
239 if (offset == 0 && range->previous->append()) {
240 range = range->previous;
241 offset = range->inGroup() ? range->count : 0;
249
250
252QQmlListCompositor::QQmlListCompositor()
253 : m_end(m_ranges.next, 0, Default, 2)
256 , m_defaultFlags(PrependFlag | DefaultFlag)
257 , m_removeFlags(AppendFlag | PrependFlag | GroupMask)
263
264
266QQmlListCompositor::~QQmlListCompositor()
268 for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) {
275
276
277
279inline QQmlListCompositor::Range *QQmlListCompositor::insert(
280 Range *before,
void *list,
int index,
int count, uint flags)
282 return new Range(before, list, index, count, flags);
286
287
288
289
291inline QQmlListCompositor::Range *QQmlListCompositor::erase(
294 Range *next = range->next;
295 next->previous = range->previous;
296 next->previous->next = range->next;
302
303
305void QQmlListCompositor::setGroupCount(
int count)
307 m_groupCount = count;
308 m_end = iterator(&m_ranges, 0, Default, m_groupCount);
313
314
316int QQmlListCompositor::count(Group group)
const
318 return m_end.index[group];
322
323
324
325
327QQmlListCompositor::iterator QQmlListCompositor::find(Group group,
int index)
330 Q_ASSERT(index >=0 && index < count(group));
331 if (m_cacheIt == m_end) {
332 m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
335 const int offset = index - m_cacheIt.index[group];
336 m_cacheIt.setGroup(group);
339 Q_ASSERT(m_cacheIt.index[group] == index);
340 Q_ASSERT(m_cacheIt->inGroup(group));
346
347
348
349
351QQmlListCompositor::iterator QQmlListCompositor::find(Group group,
int index)
const
353 return const_cast<QQmlListCompositor *>(
this)->find(group, index);
357
358
359
360
361
362
363
364
365
366
368QQmlListCompositor::insert_iterator QQmlListCompositor::findInsertPosition(Group group,
int index)
371 Q_ASSERT(index >=0 && index <= count(group));
373 if (m_cacheIt == m_end) {
374 it = iterator(m_ranges.next, 0, group, m_groupCount);
377 const int offset = index - m_cacheIt.index[group];
382 Q_ASSERT(it.index[group] == index);
387
388
389
390
391
392
394void QQmlListCompositor::append(
395 void *list,
int index,
int count, uint flags, QVector<Insert> *inserts)
398 insert(m_end, list, index, count, flags, inserts);
402
403
404
405
406
407
409void QQmlListCompositor::insert(
410 Group group,
int before,
void *list,
int index,
int count, uint flags, QVector<Insert> *inserts)
413 insert(findInsertPosition(group, before), list, index, count, flags, inserts);
417
418
419
420
421
422
424QQmlListCompositor::iterator QQmlListCompositor::insert(
425 iterator before,
void *list,
int index,
int count, uint flags, QVector<Insert> *inserts)
429 inserts->append(Insert(before, count, flags & GroupMask));
431 if (before.offset > 0) {
435 *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next;
436 before->index += before.offset;
437 before->count -= before.offset;
442 if (!(flags & AppendFlag) && *before != m_ranges.next
443 && before->previous->list == list
444 && before->previous->flags == flags
445 && (!list || before->previous->end() == index)) {
448 before->previous->count += count;
449 before.incrementIndexes(count, flags);
451 *before = insert(*before, list, index, count, flags);
455 if (!(flags & AppendFlag) && before->next != &m_ranges
456 && before->list == before->next->list
457 && before->flags == before->next->flags
458 && (!list || before->end() == before->next->index)) {
460 before->next->index = before->index;
461 before->next->count += before->count;
462 *before = erase(*before);
465 m_end.incrementIndexes(count, flags);
472
473
474
475
476
478void QQmlListCompositor::setFlags(
479 Group fromGroup,
int from,
int count, Group group,
int flags, QVector<Insert> *inserts)
482 setFlags(find(fromGroup, from), count, group, flags, inserts);
486
487
488
489
490
492void QQmlListCompositor::setFlags(
493 iterator from,
int count, Group group, uint flags, QVector<Insert> *inserts)
496 if (!flags || !count)
501 from.incrementIndexes(from->count - from.offset);
504 }
else if (from.offset > 0) {
506 *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
507 from->index += from.offset;
508 from->count -= from.offset;
512 for (; count > 0; *from = from->next) {
513 if (from != from.group) {
515 from.incrementIndexes(from->count);
519 const int difference = qMin(count, from->count);
523 const uint insertFlags = ~from->flags & flags;
524 const uint setFlags = (from->flags | flags) & ~AppendFlag;
525 if (insertFlags && inserts)
526 inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag)));
527 m_end.incrementIndexes(difference, insertFlags);
528 from.incrementIndexes(difference, setFlags);
530 if (from->previous != &m_ranges
531 && from->previous->list == from->list
532 && (!from->list || from->previous->end() == from->index)
533 && from->previous->flags == setFlags) {
536 from->previous->count += difference;
537 from->index += difference;
538 from->count -= difference;
539 if (from->count == 0) {
543 from->previous->flags |= AppendFlag;
544 *from = erase(*from)->previous;
549 }
else if (!insertFlags) {
551 from.incrementIndexes(from->count - difference);
553 }
else if (difference < from->count) {
556 *from = insert(*from, from->list, from->index, difference, setFlags)->next;
557 from->index += difference;
558 from->count -= difference;
561 from->flags |= flags;
564 from.incrementIndexes(from->count);
567 if (from->previous != &m_ranges
568 && from->previous->list == from->list
569 && (!from->list || from->previous->end() == from->index)
570 && from->previous->flags == (from->flags & ~AppendFlag)) {
572 from.offset = from->previous->count;
573 from->previous->count += from->count;
574 from->previous->flags = from->flags;
575 *from = erase(*from)->previous;
582
583
584
585
586
588void QQmlListCompositor::clearFlags(
589 Group fromGroup,
int from,
int count, Group group, uint flags, QVector<Remove> *removes)
592 clearFlags(find(fromGroup, from), count, group, flags, removes);
596
597
598
599
600
602void QQmlListCompositor::clearFlags(
603 iterator from,
int count, Group group, uint flags, QVector<Remove> *removes)
606 if (!flags || !count)
609 const bool clearCache = flags & CacheFlag;
613 from.incrementIndexes(from->count - from.offset);
616 }
else if (from.offset > 0) {
618 *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
619 from->index += from.offset;
620 from->count -= from.offset;
624 for (; count > 0; *from = from->next) {
627 from.incrementIndexes(from->count);
631 const int difference = qMin(count, from->count);
636 const uint removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag);
637 const uint clearedFlags = from->flags & ~(flags | AppendFlag | UnresolvedFlag);
638 if (removeFlags && removes) {
639 const int maskedFlags = clearCache
640 ? (removeFlags & ~CacheFlag)
641 : (removeFlags | (from->flags & CacheFlag));
643 removes->append(Remove(from, difference, maskedFlags));
645 m_end.decrementIndexes(difference, removeFlags);
646 from.incrementIndexes(difference, clearedFlags);
648 if (from->previous != &m_ranges
649 && from->previous->list == from->list
650 && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index)
651 && from->previous->flags == clearedFlags) {
654 from->previous->count += difference;
655 from->index += difference;
656 from->count -= difference;
657 if (from->count == 0) {
660 from->previous->flags |= AppendFlag;
661 *from = erase(*from)->previous;
663 from.incrementIndexes(from->count);
665 }
else if (difference < from->count) {
669 *from = insert(*from, from->list, from->index, difference, clearedFlags)->next;
670 from->index += difference;
671 from->count -= difference;
672 from.incrementIndexes(from->count);
673 }
else if (clearedFlags) {
675 from->flags &= ~flags;
678 *from = erase(*from)->previous;
682 if (*from != &m_ranges && from->previous != &m_ranges
683 && from->previous->list == from->list
684 && (!from->list || from->previous->end() == from->index)
685 && from->previous->flags == (from->flags & ~AppendFlag)) {
687 from.offset = from->previous->count;
688 from->previous->count += from->count;
689 from->previous->flags = from->flags;
690 *from = erase(*from)->previous;
696bool QQmlListCompositor::verifyMoveTo(
697 Group fromGroup,
int from, Group toGroup,
int to,
int count, Group group)
const
699 if (group != toGroup) {
701 iterator fromIt = find(fromGroup, from);
703 int intersectingCount = 0;
705 for (; count > 0; *fromIt = fromIt->next) {
706 if (*fromIt == &m_ranges)
708 if (!fromIt->inGroup(group))
710 if (fromIt->inGroup(toGroup))
711 intersectingCount += qMin(count, fromIt->count - fromIt.offset);
712 count -= fromIt->count - fromIt.offset;
715 count = intersectingCount;
718 return to >= 0 && to + count <= m_end.index[toGroup];
722
723
724
725
726
727
728
729
731void QQmlListCompositor::move(
738 QVector<Remove> *removes,
739 QVector<Insert> *inserts)
744 Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count, moveGroup));
747 iterator fromIt = find(fromGroup, from);
749 if (fromIt != moveGroup) {
752 fromIt.incrementIndexes(fromIt->count - fromIt.offset);
754 *fromIt = fromIt->next;
755 }
else if (fromIt.offset > 0) {
760 *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next;
761 fromIt->index += fromIt.offset;
762 fromIt->count -= fromIt.offset;
768 for (
int moveId = m_moveId; count > 0;) {
769 if (fromIt != moveGroup) {
771 fromIt.incrementIndexes(fromIt->count);
772 *fromIt = fromIt->next;
775 int difference = qMin(count, fromIt->count);
783 fromIt->flags & ~(PrependFlag | AppendFlag));
786 removes->append(Remove(fromIt, difference, fromIt->flags, ++moveId));
788 fromIt->count -= difference;
792 int removeIndex = fromIt->index;
793 if (fromIt->prepend()
794 && fromIt->previous != &m_ranges
795 && fromIt->previous->flags == PrependFlag
796 && fromIt->previous->list == fromIt->list
797 && fromIt->previous->end() == fromIt->index) {
799 fromIt->previous->count += difference;
800 }
else if (fromIt->prepend()) {
801 *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next;
803 fromIt->index += difference;
805 if (fromIt->count == 0) {
807 if (fromIt->append())
808 fromIt->previous->flags |= AppendFlag;
809 *fromIt = erase(*fromIt);
812 if (*fromIt != m_ranges.next && fromIt->flags == PrependFlag
813 && fromIt->previous != &m_ranges
814 && fromIt->previous->flags == PrependFlag
815 && fromIt->previous->list == fromIt->list
816 && fromIt->previous->end() == fromIt->index) {
817 fromIt.incrementIndexes(fromIt->count);
818 fromIt->previous->count += fromIt->count;
819 *fromIt = erase(*fromIt);
821 }
else if (count > 0) {
822 *fromIt = fromIt->next;
827 if (*fromIt != m_ranges.next
828 && *fromIt != &m_ranges
829 && fromIt->previous->list == fromIt->list
830 && (!fromIt->list || fromIt->previous->end() == fromIt->index)
831 && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) {
832 if (fromIt == fromIt.group)
833 fromIt.offset = fromIt->previous->count;
834 fromIt.offset = fromIt->previous->count;
835 fromIt->previous->count += fromIt->count;
836 fromIt->previous->flags = fromIt->flags;
837 *fromIt = erase(*fromIt)->previous;
841 insert_iterator toIt = fromIt;
842 toIt.setGroup(toGroup);
844 const int difference = to - toIt.index[toGroup];
849 if (toIt.offset > 0) {
850 *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next;
851 toIt->index += toIt.offset;
852 toIt->count -= toIt.offset;
858 for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) {
859 if (*toIt != &m_ranges
860 && range->list == toIt->list
861 && (!range->list || range->end() == toIt->index)
862 && range->flags == (toIt->flags & ~AppendFlag)) {
863 toIt->index -= range->count;
864 toIt->count += range->count;
866 *toIt = insert(*toIt, range->list, range->index, range->count, range->flags);
871 if (*toIt != m_ranges.next
872 && toIt->previous->list == toIt->list
873 && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) {
874 toIt.offset = toIt->previous->count;
875 toIt->previous->count += toIt->count;
876 toIt->previous->flags = toIt->flags;
877 *toIt = erase(*toIt)->previous;
880 Insert insert(toIt, 0, 0, 0);
881 for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) {
882 insert.count = range->count;
883 insert.flags = range->flags;
885 insert.moveId = ++m_moveId;
886 inserts->append(insert);
888 for (
int i = 0; i < m_groupCount; ++i) {
889 if (insert.inGroup(i))
890 insert.index[i] += range->count;
903
904
906void QQmlListCompositor::clear()
909 for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {}
910 m_end = iterator(m_ranges.next, 0, Default, m_groupCount);
914void QQmlListCompositor::listItemsInserted(
915 QVector<Insert> *translatedInsertions,
917 const QVector<QQmlChangeSet::Change> &insertions,
918 const QVector<MovedFlags> *movedFlags)
921 for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
922 if (it->list != list || it->flags == CacheFlag) {
924 it.incrementIndexes(it->count);
926 }
else if (it->flags & MovedFlag) {
928 it->flags &= ~MovedFlag;
929 it.incrementIndexes(it->count);
932 for (
const QQmlChangeSet::Change &insertion : insertions) {
933 int offset = insertion.index - it->index;
934 if ((offset > 0 && offset < it->count)
935 || (offset == 0 && it->prepend())
936 || (offset == it->count && it->append())) {
940 uint flags = m_defaultFlags;
941 if (insertion.isMove()) {
944 for (QVector<MovedFlags>::const_iterator move = movedFlags->begin();
945 move != movedFlags->end();
947 if (move->moveId == insertion.moveId) {
953 if (flags & ~(AppendFlag | PrependFlag)) {
955 Insert translatedInsert(it, insertion.count, flags, insertion.moveId);
956 for (
int i = 0; i < m_groupCount; ++i) {
958 translatedInsert.index[i] += offset;
960 translatedInsertions->append(translatedInsert);
962 if ((it->flags & ~AppendFlag) == flags) {
965 it->count += insertion.count;
966 }
else if (offset == 0
967 && it->previous != &m_ranges
968 && it->previous->list == list
969 && it->previous->end() == insertion.index
970 && it->previous->flags == flags) {
973 it->previous->count += insertion.count;
974 it->index += insertion.count;
975 it.incrementIndexes(insertion.count);
979 it.incrementIndexes(offset);
980 *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
983 *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next;
984 it.incrementIndexes(insertion.count, flags);
985 it->index += offset + insertion.count;
988 m_end.incrementIndexes(insertion.count, flags);
993 *it = insert(*it, it->list, it->index, offset, it->flags)->next;
997 it->index += insertion.count;
999 }
else if (offset <= 0) {
1001 it->index += insertion.count;
1004 it.incrementIndexes(it->count);
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1024void QQmlListCompositor::listItemsInserted(
1025 void *list,
int index,
int count, QVector<Insert> *translatedInsertions)
1028 Q_ASSERT(count > 0);
1030 QVector<QQmlChangeSet::Change> insertions;
1031 insertions.append(QQmlChangeSet::Change(index, count));
1033 listItemsInserted(translatedInsertions, list, insertions);
1036void QQmlListCompositor::listItemsRemoved(
1037 QVector<Remove> *translatedRemovals,
1039 QVector<QQmlChangeSet::Change> *removals,
1040 QVector<QQmlChangeSet::Change> *insertions,
1041 QVector<MovedFlags> *movedFlags)
1045 for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
1046 if (it->list != list || it->flags == CacheFlag) {
1048 it.incrementIndexes(it->count);
1051 bool removed =
false;
1052 for (QVector<QQmlChangeSet::Change>::iterator removal = removals->begin();
1053 !removed && removal != removals->end();
1055 int relativeIndex = removal->index - it->index;
1056 int itemsRemoved = removal->count;
1057 if (relativeIndex + removal->count > 0 && relativeIndex < it->count) {
1059 const int offset = qMax(0, relativeIndex);
1060 int removeCount = qMin(it->count, relativeIndex + removal->count) - offset;
1061 it->count -= removeCount;
1062 int removeFlags = it->flags & m_removeFlags;
1063 Remove translatedRemoval(it, removeCount, it->flags);
1064 for (
int i = 0; i < m_groupCount; ++i) {
1066 translatedRemoval.index[i] += offset;
1068 if (removal->isMove()) {
1070 QVector<QQmlChangeSet::Change>::iterator insertion = insertions->begin();
1071 for (; insertion != insertions->end() && insertion->moveId != removal->moveId;
1073 Q_ASSERT(insertion != insertions->end());
1074 Q_ASSERT(insertion->count == removal->count);
1076 if (relativeIndex < 0) {
1079 int splitMoveId = ++m_moveId;
1080 removal = removals->insert(removal, QQmlChangeSet::Change(
1081 removal->index, -relativeIndex, splitMoveId));
1083 removal->count -= -relativeIndex;
1084 insertion = insertions->insert(insertion, QQmlChangeSet::Change(
1085 insertion->index, -relativeIndex, splitMoveId));
1087 insertion->index += -relativeIndex;
1088 insertion->count -= -relativeIndex;
1091 if (it->prepend()) {
1094 removeFlags |= it->flags & CacheFlag;
1095 translatedRemoval.moveId = ++m_moveId;
1096 movedFlags->append(MovedFlags(m_moveId, it->flags & ~AppendFlag));
1098 if (removeCount < removal->count) {
1101 removal = removals->insert(removal, QQmlChangeSet::Change(
1102 removal->index, removeCount, translatedRemoval.moveId));
1104 insertion = insertions->insert(insertion, QQmlChangeSet::Change(
1105 insertion->index, removeCount, translatedRemoval.moveId));
1108 removal->count -= removeCount;
1109 insertion->index += removeCount;
1110 insertion->count -= removeCount;
1114 removal->moveId = translatedRemoval.moveId;
1115 insertion->moveId = translatedRemoval.moveId;
1122 *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
1123 it->index += offset;
1124 it->count -= offset;
1125 it.incrementIndexes(offset);
1127 if (it->previous != &m_ranges
1128 && it->previous->list == it->list
1129 && it->end() == insertion->index
1130 && it->previous->flags == (it->flags | MovedFlag)) {
1131 it->previous->count += removeCount;
1133 *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next;
1136 translatedRemoval.flags = 0;
1139 }
else if (it->inCache()) {
1144 *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
1145 it->index += offset;
1146 it->count -= offset;
1147 it.incrementIndexes(offset);
1149 if (it->previous != &m_ranges
1150 && it->previous->list == it->list
1151 && it->previous->flags == CacheFlag) {
1152 it->previous->count += removeCount;
1154 *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next;
1156 it.index[Cache] += removeCount;
1158 if (removeFlags & GroupMask)
1159 translatedRemovals->append(translatedRemoval);
1160 m_end.decrementIndexes(removeCount, removeFlags);
1161 if (it->count == 0 && !it->append()) {
1163 *it = erase(*it)->previous;
1165 }
else if (relativeIndex <= 0) {
1168 it->index = removal->index;
1170 }
else if (relativeIndex < 0) {
1173 it->index -= itemsRemoved;
1175 if (it->previous != &m_ranges
1176 && it->previous->list == it->list
1177 && it->previous->end() == it->index
1178 && it->previous->flags == (it->flags & ~AppendFlag)) {
1180 it.decrementIndexes(it->previous->count);
1181 it->previous->count += it->count;
1182 it->previous->flags = it->flags;
1183 *it = erase(*it)->previous;
1187 if (it->flags == CacheFlag && it->next->flags == CacheFlag && it->next->list == it->list) {
1189 it.index[Cache] += it->next->count;
1190 it->count += it->next->count;
1192 }
else if (!removed) {
1193 it.incrementIndexes(it->count);
1202
1203
1204
1205
1206
1207
1208
1209
1210
1213void QQmlListCompositor::listItemsRemoved(
1214 void *list,
int index,
int count, QVector<Remove> *translatedRemovals)
1217 Q_ASSERT(count >= 0);
1219 QVector<QQmlChangeSet::Change> removals;
1220 removals.append(QQmlChangeSet::Change(index, count));
1221 listItemsRemoved(translatedRemovals, list, &removals,
nullptr,
nullptr);
1225
1226
1227
1228
1229
1230
1231
1232
1233
1235void QQmlListCompositor::listItemsMoved(
1240 QVector<Remove> *translatedRemovals,
1241 QVector<Insert> *translatedInsertions)
1244 Q_ASSERT(count >= 0);
1246 QVector<QQmlChangeSet::Change> removals;
1247 QVector<QQmlChangeSet::Change> insertions;
1248 QVector<MovedFlags> movedFlags;
1249 removals.append(QQmlChangeSet::Change(from, count, 0));
1250 insertions.append(QQmlChangeSet::Change(to, count, 0));
1252 listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags);
1253 listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
1256void QQmlListCompositor::listItemsChanged(
1257 QVector<Change> *translatedChanges,
1259 const QVector<QQmlChangeSet::Change> &changes)
1262 for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
1263 if (it->list != list || it->flags == CacheFlag) {
1264 it.incrementIndexes(it->count);
1266 }
else if (!it->inGroup()) {
1269 for (
const QQmlChangeSet::Change &change : changes) {
1270 const int offset = change.index - it->index;
1271 if (offset + change.count > 0 && offset < it->count) {
1272 const int changeOffset = qMax(0, offset);
1273 const int changeCount = qMin(it->count, offset + change.count) - changeOffset;
1275 Change translatedChange(it, changeCount, it->flags);
1276 for (
int i = 0; i < m_groupCount; ++i) {
1278 translatedChange.index[i] += changeOffset;
1280 translatedChanges->append(translatedChange);
1283 it.incrementIndexes(it->count);
1289
1290
1291
1292
1293
1295void QQmlListCompositor::listItemsChanged(
1296 void *list,
int index,
int count, QVector<Change> *translatedChanges)
1299 Q_ASSERT(count >= 0);
1300 QVector<QQmlChangeSet::Change> changes;
1301 changes.append(QQmlChangeSet::Change(index, count));
1302 listItemsChanged(translatedChanges, list, changes);
1305void QQmlListCompositor::transition(
1308 QVector<QQmlChangeSet::Change> *removes,
1309 QVector<QQmlChangeSet::Change> *inserts)
1311 int removeCount = 0;
1312 for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
1313 if (it == from && it != to) {
1314 removes->append(QQmlChangeSet::Change(it.index[from]- removeCount, it->count));
1315 removeCount += it->count;
1316 }
else if (it != from && it == to) {
1317 inserts->append(QQmlChangeSet::Change(it.index[to], it->count));
1319 it.incrementIndexes(it->count);
1324
1325
1326
1331 case QQmlListCompositor::Cache:
return debug <<
"Cache";
1332 case QQmlListCompositor::Default:
return debug <<
"Default";
1333 default:
return (debug.nospace() <<
"Group" <<
int(group)).space();
1339
1340
1341
1347 << range.list) <<
' '
1348 << range.index <<
' '
1349 << range.count <<
' '
1350 << (range.isUnresolved() ?
'U' :
'0')
1351 << (range.append() ?
'A' :
'0')
1352 << (range.prepend() ?
'P' :
'0');
1353 for (
int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
1354 debug << (range.inGroup(i) ?
'1' :
'0');
1356 << (range.inGroup(QQmlListCompositor::Default) ?
'D' :
'0')
1357 << (range.inGroup(QQmlListCompositor::Cache) ?
'C' :
'0'));
1362 for (
int i = count - 1; i >= 0; --i)
1363 debug << indexes[i];
1367
1368
1369
1373 (debug.nospace() <<
"iterator(" << it.group).space() <<
"offset:" << it.offset;
1375 return ((debug << **it).nospace() <<
')').space();
1380 debug.nospace() << name <<
'(' << change.moveId <<
' ' << change.count <<
' ';
1381 for (
int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
1382 debug << (change.inGroup(i) ?
'1' :
'0');
1383 debug << (change.inGroup(QQmlListCompositor::Default) ?
'D' :
'0')
1384 << (change.inGroup(QQmlListCompositor::Cache) ?
'C' :
'0');
1385 int i = QQmlListCompositor::MaximumGroupCount - 1;
1386 for (; i >= 0 && !change.inGroup(i); --i) {}
1388 debug <<
' ' << change.index[i];
1389 return (debug <<
')').maybeSpace();
1393
1394
1395
1399 return qt_print_change(debug,
"Change", change);
1403
1404
1405
1409 return qt_print_change(debug,
"Remove", remove);
1413
1414
1415
1419 return qt_print_change(debug,
"Insert", insert);
1423
1424
1425
1429 int indexes[QQmlListCompositor::MaximumGroupCount];
1430 for (
int i = 0; i < QQmlListCompositor::MaximumGroupCount; ++i)
1432 debug.nospace() <<
"QQmlListCompositor(";
1434 for (QQmlListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) {
1435 (debug <<
'\n').space();
1437 debug <<
' ' << *range;
1439 for (
int i = 0; i < list.m_groupCount; ++i) {
1440 if (range->inGroup(i))
1441 indexes[i] += range->count;
1444 return (debug <<
')').maybeSpace();
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
#define QT_QML_VERIFY_LISTCOMPOSITOR
static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
#define QT_QML_TRACE_LISTCOMPOSITOR(args)