aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-06-22 16:24:41 +1000
committerAndrew den Exter <andrew.den-exter@nokia.com>2011-06-22 16:24:41 +1000
commit1aaa43a08f7c6bc979f9e6c89eb5e4346db908c8 (patch)
tree37c12b9b66a185e4a869cd5cc0a4e0e43f39acf8
parent5a794a7de0508115efa1ff2b056e3744c8e2afec (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.cpp60
-rw-r--r--src/declarative/items/qsgvisualitemmodel_p.h2
-rw-r--r--src/declarative/util/qdeclarativelistcompositor.cpp62
-rw-r--r--src/declarative/util/qdeclarativelistcompositor_p.h2
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp12
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);