aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-12-13 17:17:56 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-14 04:57:30 +0100
commit13eb07b3a63d53abcabfa60659fd829051db66a3 (patch)
tree240855ed20e16aff046bee7d7808fbf4452d2710 /src/quick/util
parentfe52727baea9986882461e2ea15e9e64b96e4c61 (diff)
Fix crash when items are moved in model.
When erasing an item we need to backtrack to the previous item so the next iteration doesn't skip an item. In the worst case the next item is the last and a failure to backtrack will cause the loop to wrap around and run over the list again. Task-number: QTBUG-23107 Change-Id: I82156f6fc1f7973ba11f09a4694230c77c293757 Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src/quick/util')
-rw-r--r--src/quick/util/qdeclarativelistcompositor.cpp35
1 files changed, 16 insertions, 19 deletions
diff --git a/src/quick/util/qdeclarativelistcompositor.cpp b/src/quick/util/qdeclarativelistcompositor.cpp
index d73d76e386..e43a8a771f 100644
--- a/src/quick/util/qdeclarativelistcompositor.cpp
+++ b/src/quick/util/qdeclarativelistcompositor.cpp
@@ -872,9 +872,7 @@ void QDeclarativeListCompositor::listItemsRemoved(
{
QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << *removals)
- for (iterator it(m_ranges.next, 0, Default, m_groupCount);
- *it != &m_ranges && !removals->isEmpty();
- *it = it->next) {
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
if (it->list != list || it->flags == CacheFlag) {
it.incrementIndexes(it->count);
continue;
@@ -920,21 +918,20 @@ void QDeclarativeListCompositor::listItemsRemoved(
translatedRemoval.moveId = ++moveId;
movedFlags->append(MovedFlags(moveId, it->flags & ~AppendFlag));
- removal = removals->insert(removal, QDeclarativeChangeSet::Remove(
- removal->index, removeCount, translatedRemoval.moveId));
- ++removal;
- insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert(
- insertion->index, removeCount, translatedRemoval.moveId));
- ++insertion;
-
- removal->count -= removeCount;
- insertion->index += removeCount;
- insertion->count -= removeCount;
- if (removal->count == 0) {
- removal = removals->erase(removal);
- insertion = insertions->erase(insertion);
- --removal;
- --insertion;
+ if (removeCount < removal->count) {
+ removal = removals->insert(removal, QDeclarativeChangeSet::Remove(
+ removal->index, removeCount, translatedRemoval.moveId));
+ ++removal;
+ insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert(
+ insertion->index, removeCount, translatedRemoval.moveId));
+ ++insertion;
+
+ removal->count -= removeCount;
+ insertion->index += removeCount;
+ insertion->count -= removeCount;
+ } else {
+ removal->moveId = translatedRemoval.moveId;
+ insertion->moveId = translatedRemoval.moveId;
}
} else {
if (offset > 0) {
@@ -989,7 +986,7 @@ void QDeclarativeListCompositor::listItemsRemoved(
it->previous->count += it->count;
it->previous->flags = it->flags;
it.incrementIndexes(it->count);
- *it = erase(*it);
+ *it = erase(*it)->previous;
removed = true;
}
}