diff options
| author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-06-22 16:24:41 +1000 |
|---|---|---|
| committer | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-06-22 16:24:41 +1000 |
| commit | 1aaa43a08f7c6bc979f9e6c89eb5e4346db908c8 (patch) | |
| tree | 37c12b9b66a185e4a869cd5cc0a4e0e43f39acf8 | |
| parent | 5a794a7de0508115efa1ff2b056e3744c8e2afec (diff) | |
Fix errors in model compositing.
Don't set the null flag a split range as that effectively removes the
items from the list. And revert to returning the offset within a range
rather than an absolute model index which doesn't contain any useful
information in the case of a internal range.
| -rw-r--r-- | src/declarative/items/qsgvisualitemmodel.cpp | 60 | ||||
| -rw-r--r-- | src/declarative/items/qsgvisualitemmodel_p.h | 2 | ||||
| -rw-r--r-- | src/declarative/util/qdeclarativelistcompositor.cpp | 62 | ||||
| -rw-r--r-- | src/declarative/util/qdeclarativelistcompositor_p.h | 2 | ||||
| -rw-r--r-- | src/declarative/util/qdeclarativelistmodel.cpp | 12 |
5 files changed, 96 insertions, 42 deletions
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp index 85f97aae7d..01feae769f 100644 --- a/src/declarative/items/qsgvisualitemmodel.cpp +++ b/src/declarative/items/qsgvisualitemmodel.cpp @@ -130,10 +130,8 @@ public: Q_Q(QSGVisualItemModel); foreach (const QDeclarativeChangeSet::Remove &remove, transactionChanges.removes()) emit q->itemsRemoved(remove.start, remove.count()); - foreach (const QDeclarativeChangeSet::Insert &insert, transactionChanges.inserts()) { - qDebug() << "Insert" << insert.start << insert.end; + foreach (const QDeclarativeChangeSet::Insert &insert, transactionChanges.inserts()) emit q->itemsInserted(insert.start, insert.count()); - } foreach (const QDeclarativeChangeSet::Move &move, transactionChanges.moves()) emit q->itemsMoved(move.start, move.to, move.count()); transactionChanges.clear(); @@ -253,12 +251,12 @@ bool QSGVisualItemModel::isValid() const QSGItem *QSGVisualItemModel::item(int index, bool complete) { Q_D(QSGVisualItemModel); - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = d->at(index, &modelIndex, &internalIndex); + QDeclarativeCompositeRange range = d->at(index, &offset, &internalIndex); if (!range.internal()) { QSGVisualDataModel *model = static_cast<QSGVisualDataModel *>(range.list); - QSGItem *item = model->item(modelIndex, complete); + QSGItem *item = model->item(range.index + offset, complete); d->itemModels.insert(item, model); if (model->completePending()) d->pendingModel = model; @@ -340,18 +338,17 @@ QScriptValue QSGVisualItemModel::getItemInfo(int index) const QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this)); QScriptValue info = engine->newObject(); - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = d->at(index, &modelIndex, &internalIndex); + QDeclarativeCompositeRange range = d->at(index, &offset, &internalIndex); if (!range.internal()) { - info.setProperty(QLatin1String("modelItem"), true); info.setProperty(QLatin1String("model"), engine->newVariant(static_cast<QSGVisualDataModel *>(range.list)->model())); - info.setProperty(QLatin1String("index"), modelIndex); + info.setProperty(QLatin1String("index"), range.index + offset); info.setProperty(QLatin1String("start"), range.index); info.setProperty(QLatin1String("end"), range.index + range.count); } else { - info.setProperty(QLatin1String("modelItem"), false); + info.setProperty(QLatin1String("model"), engine->nullValue()); } return info; } @@ -381,16 +378,16 @@ void QSGVisualItemModel::append(QSGVisualItemModel *sourceModel, int sourceIndex } for (int i = 0, difference = 0; i < count; i += difference) { - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex); - difference = range.index + range.count - modelIndex; + QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &offset, &internalIndex); + difference = range.count - offset; if (range.internal()) { - for (int j = 0; j < range.count; ++j) + for (int j = 0; j < qMin(count - i, range.count - offset); ++j) d->appendData(sourceModel->d_func()->children.at(internalIndex + j).item); } else { - d->appendList(range.list, modelIndex, qMin(count - i, range.count), false); + d->appendList(range.list, range.index + offset, qMin(count - i, range.count - offset), false); } } @@ -398,6 +395,7 @@ void QSGVisualItemModel::append(QSGVisualItemModel *sourceModel, int sourceIndex sourceModel->d_func()->removeAt(sourceIndex, count); emit sourceModel->itemsRemoved(sourceIndex, count); + emit sourceModel->countChanged(); } void QSGVisualItemModel::insert(int index, QSGItem *item) @@ -425,16 +423,16 @@ void QSGVisualItemModel::insert(int destinationIndex, QSGVisualItemModel *source } for (int i = 0, difference = 0; i < count; i += difference) { - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex); - difference = range.index + range.count - modelIndex; + QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &offset, &internalIndex); + difference = range.count - offset; if (range.internal()) { - for (int j = 0; j < range.count; ++j) + for (int j = 0; j < qMin(count - i, range.count - offset); ++j) d->insertData(destinationIndex + i + j, sourceModel->d_func()->children.at(internalIndex + j).item); } else { - d->insertList(destinationIndex + i, range.list, modelIndex, qMin(count - i, range.count), false); + d->insertList(destinationIndex + i, range.list, range.index + offset, qMin(count - i, range.count - offset), false); } } @@ -442,6 +440,7 @@ void QSGVisualItemModel::insert(int destinationIndex, QSGVisualItemModel *source sourceModel->d_func()->removeAt(sourceIndex, count); emit sourceModel->itemsRemoved(sourceIndex, count); + emit sourceModel->countChanged(); } void QSGVisualItemModel::remove(int index, int count) @@ -508,18 +507,21 @@ void QSGVisualItemModel::replace(int destinationIndex, QSGVisualItemModel *sourc } else { d->removeAt(destinationIndex, count); for (int i = 0, difference = 0; i < count; i += difference) { - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &modelIndex, &internalIndex); - difference = range.index + range.count - modelIndex; + QDeclarativeCompositeRange range = sourceModel->d_func()->at(sourceIndex, &offset, &internalIndex); + difference = range.count - offset; if (range.internal()) { - for (int j = 0; j < range.count; ++j) + for (int j = 0; j < qMin(count - i, range.count - offset); ++j) d->insertData(destinationIndex + i + j, sourceModel->d_func()->children.at(internalIndex + j).item); } else { - d->insertList(destinationIndex + i, range.list, modelIndex, qMin(count - i, range.count), false); + d->insertList(destinationIndex + i, range.list, range.index + offset, qMin(count - i, range.count - offset), false); } } + sourceModel->d_func()->removeAt(sourceIndex, count); + emit sourceModel->itemsRemoved(sourceIndex, count); + emit sourceModel->countChanged(); } } @@ -533,16 +535,16 @@ void QSGVisualItemModel::_q_itemsInserted(int index, int count) if (inserts.count() > 0) { QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this)); - QScriptValue indexes = engine->newArray(inserts.count()); + QScriptValue insertIndexes = engine->newArray(inserts.count()); for (int i = 0; i < inserts.count(); ++i) { QScriptValue range = engine->newObject(); range.setProperty(QLatin1String("start"), inserts.at(i).start); range.setProperty(QLatin1String("end"), inserts.at(i).end); - indexes.setProperty(i, range); + insertIndexes.setProperty(i, range); } d->transaction = true; d->transactionChanges.append(inserts); - emit itemDataInserted(indexes); + emit updated(insertIndexes); d->transaction = false; d->emitTransactionChanges(); diff --git a/src/declarative/items/qsgvisualitemmodel_p.h b/src/declarative/items/qsgvisualitemmodel_p.h index 9b1711cdcf..bfcb91360d 100644 --- a/src/declarative/items/qsgvisualitemmodel_p.h +++ b/src/declarative/items/qsgvisualitemmodel_p.h @@ -147,7 +147,7 @@ public: Q_SIGNALS: void childrenChanged(); - void itemDataInserted(const QScriptValue &indexes); + void updated(const QScriptValue &inserts); private Q_SLOTS: void _q_itemsInserted(int index, int count); diff --git a/src/declarative/util/qdeclarativelistcompositor.cpp b/src/declarative/util/qdeclarativelistcompositor.cpp index 6510a95a06..ac524b4302 100644 --- a/src/declarative/util/qdeclarativelistcompositor.cpp +++ b/src/declarative/util/qdeclarativelistcompositor.cpp @@ -43,6 +43,39 @@ #include <QtCore/qvarlengtharray.h> +bool qt_verifyIntegrity(const QLinkedList<QDeclarativeCompositeRange> &ranges, int absoluteCount, int internalCount) +{ + bool valid = true; + int actualAbsoluteCount = 0; + int actualInternalCount = 0; + + int index = 0; + foreach (const QDeclarativeCompositeRange &range, ranges) { + if (range.null()) { + if (range.internal()) { + qWarning() << index << "Null Internal Range"; + valid = false; + } + } else { + actualAbsoluteCount += range.count; + if (range.internal()) + actualInternalCount += range.count; + } + ++index; + } + + if (actualAbsoluteCount != absoluteCount) { + qWarning() << "Absolute count invalid" << absoluteCount << actualAbsoluteCount; + valid = false; + } + if (actualInternalCount != internalCount) { + qWarning() << "Internal count invalid" << internalCount << actualInternalCount; + valid = false; + } + + return valid; +} + QDeclarativeListCompositor::QDeclarativeListCompositor(int internalCount) : absoluteCount(internalCount) , internalCount(internalCount) @@ -70,7 +103,7 @@ int QDeclarativeListCompositor::count() const return absoluteCount; } -QDeclarativeCompositeRange QDeclarativeListCompositor::at(int index, int *modelIndex, int *internalIndex) const +QDeclarativeCompositeRange QDeclarativeListCompositor::at(int index, int *offset, int *internalIndex) const { Q_ASSERT(index >=0 && index < absoluteCount); *internalIndex = 0; @@ -78,7 +111,7 @@ QDeclarativeCompositeRange QDeclarativeListCompositor::at(int index, int *modelI if (range->null()) continue; if (index < range->count) { - *modelIndex = range->index + index; + *offset = index; if (range->internal()) *internalIndex += index; return *range; @@ -356,6 +389,7 @@ void QDeclarativeListCompositor::forwardToBackwardMove(int &from, int &to, int & void QDeclarativeListCompositor::move(int from, int to, int count) { + qDebug() << Q_FUNC_INFO << from << to << count; Q_ASSERT(from != to || count == 0); Q_ASSERT(from >=0 && from + count <= absoluteCount); Q_ASSERT(to >=0 && to <= absoluteCount); @@ -374,7 +408,7 @@ void QDeclarativeListCompositor::move(int from, int to, int count) if (relativeTo < range->count || (relativeTo == range->count && range->append())) { if (relativeTo > 0) { range = insert(range, QDeclarativeCompositeRange( - range->list, range->index, relativeTo, Null | Prepend)); + range->list, range->index, relativeTo, range->flags & ~Append)); range->index += relativeTo; range->count -= relativeTo; if (range->internal()) @@ -477,6 +511,10 @@ void QDeclarativeListCompositor::move(int from, int to, int count) for (int i = 0; i < movedRanges.count(); ++i) insertPos = ++ranges.insert(insertPos, movedRanges.at(i)); + + qDebug() << *this; + + Q_ASSERT(qt_verifyIntegrity(ranges, absoluteCount, internalCount)); } bool QDeclarativeListCompositor::merge(int from, int to) @@ -830,6 +868,9 @@ void QDeclarativeListCompositor::listItemsMoved( { int from = start; int count = end - start; + + qDebug() << Q_FUNC_INFO << from << to << count; + Q_ASSERT(from != to); Q_ASSERT(count != 0); @@ -858,6 +899,10 @@ void QDeclarativeListCompositor::listItemsMoved( *it = QDeclarativeChangeSet::Move(from, from + count, to); } } + + qDebug() << *this; + + Q_ASSERT(qt_verifyIntegrity(ranges, absoluteCount, internalCount)); } void QDeclarativeListCompositor::listItemsChanged(void *list, int start, int end, QVector<QDeclarativeChangeSet::Change> *changes) @@ -888,10 +933,12 @@ void QDeclarativeListCompositor::compress() QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list) { + int index = 0; + int internalIndex = 0; debug.nospace() << "QDeclarativeListCompositor(" << list.absoluteCount; foreach (const QDeclarativeCompositeRange &range, list.ranges) { - ((debug.nospace() - << "\n\t(" + (((debug.space() + << "\n" << index << internalIndex << "\t(").nospace() << range.list).space() << range.index << range.count @@ -899,6 +946,11 @@ QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list) << "prepend:" << range.prepend() << "append:" << range.append() << "internal:").nospace() << range.internal() << ")"; + if (!range.null()) { + index += range.count; + if (range.internal()) + internalIndex += range.count; + } } return (debug.nospace() << ")").maybeSpace(); } diff --git a/src/declarative/util/qdeclarativelistcompositor_p.h b/src/declarative/util/qdeclarativelistcompositor_p.h index e1240e7f10..207f9ae4c6 100644 --- a/src/declarative/util/qdeclarativelistcompositor_p.h +++ b/src/declarative/util/qdeclarativelistcompositor_p.h @@ -96,7 +96,7 @@ public: ~QDeclarativeListCompositor(); int count() const; - QDeclarativeCompositeRange at(int index, int *modelIndex, int *internalIndex) const; + QDeclarativeCompositeRange at(int index, int *offset, int *internalIndex) const; void appendList(void *list, int start, int count, bool grow); bool appendData(const void *data); diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 2f53c1cfc4..4d666bb29b 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -325,11 +325,11 @@ QVariant QDeclarativeListModel::data(int index, int role) const return QVariant(); if (m_compositor) { - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = m_compositor->at(index, &modelIndex, &internalIndex); + QDeclarativeCompositeRange range = m_compositor->at(index, &offset, &internalIndex); return range.list - ? static_cast<ModelCompositorList *>(range.list)->data(modelIndex, role) + ? static_cast<ModelCompositorList *>(range.list)->data(range.index + offset, role) : m_nested->data(internalIndex, role); } else { return m_flat ? m_flat->data(index, role) : m_nested->data(index, role); @@ -570,11 +570,11 @@ QScriptValue QDeclarativeListModel::get(int index) const { // the internal flat/nested class checks for bad index if (m_compositor) { - int modelIndex = 0; + int offset = 0; int internalIndex = 0; - QDeclarativeCompositeRange range = m_compositor->at(index, &modelIndex, &internalIndex); + QDeclarativeCompositeRange range = m_compositor->at(index, &offset, &internalIndex); return range.list - ? static_cast<ModelCompositorList *>(range.list)->get(modelIndex) + ? static_cast<ModelCompositorList *>(range.list)->get(range.index + offset) : m_nested->get(internalIndex); } else { return m_flat ? m_flat->get(index) : m_nested->get(index); |
