aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-09-01 15:24:34 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-21 08:23:52 +0200
commit51102228258ed107a255b79606ef855bfa0e460d (patch)
treef34134b772ba45e229cd264a11dba81c0ed77155 /src
parentce7b66871ce342b4cc62969ec0a3a9d90cee49e9 (diff)
Use QDeclarativeChangeSet to communicate changes to views.
Allows QSGVisualDataModel to send multiple changes at a time. Changes sets with multiple changes will be generated by VisualDataModels with items that have been re-ordered or filtered. Task-number: QTBUG-20107 Change-Id: I28f2620431cc89c61e1061635ffb68dc5801675c Reviewed-on: http://codereview.qt-project.org/4034 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Bea Lam <bea.lam@nokia.com> Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/items/qsgitemview.cpp179
-rw-r--r--src/declarative/items/qsgitemview_p.h8
-rw-r--r--src/declarative/items/qsgitemview_p_p.h5
-rw-r--r--src/declarative/items/qsgpathview.cpp158
-rw-r--r--src/declarative/items/qsgpathview_p.h7
-rw-r--r--src/declarative/items/qsgrepeater.cpp120
-rw-r--r--src/declarative/items/qsgrepeater_p.h7
-rw-r--r--src/declarative/items/qsgvisualdatamodel.cpp53
-rw-r--r--src/declarative/items/qsgvisualitemmodel.cpp5
-rw-r--r--src/declarative/items/qsgvisualitemmodel_p.h7
10 files changed, 229 insertions, 320 deletions
diff --git a/src/declarative/items/qsgitemview.cpp b/src/declarative/items/qsgitemview.cpp
index 2b3f51b648..291592b871 100644
--- a/src/declarative/items/qsgitemview.cpp
+++ b/src/declarative/items/qsgitemview.cpp
@@ -70,68 +70,48 @@ bool QSGItemViewChangeSet::hasPendingChanges() const
return !pendingChanges.isEmpty();
}
-void QSGItemViewChangeSet::doInsert(int index, int count)
-{
- pendingChanges.insert(index, count);
-
- if (newCurrentIndex >= index) {
- // adjust current item index
- newCurrentIndex += count;
- currentChanged = true;
- } else if (newCurrentIndex < 0) {
- newCurrentIndex = 0;
- currentChanged = true;
- }
-
- itemCount += count;
-}
-
-void QSGItemViewChangeSet::doRemove(int index, int count)
-{
- itemCount -= count;
- pendingChanges.remove(index, count);
-
- if (newCurrentIndex >= index + count) {
- newCurrentIndex -= count;
- currentChanged = true;
- } else if (newCurrentIndex >= index && newCurrentIndex < index + count) {
- // current item has been removed.
- currentRemoved = true;
- newCurrentIndex = -1;
- if (itemCount)
- newCurrentIndex = qMin(index, itemCount-1);
- currentChanged = true;
- }
-}
-
-void QSGItemViewChangeSet::doMove(int from, int to, int count)
-{
- pendingChanges.move(from, to, count);
-
- if (to > from) {
- if (newCurrentIndex >= from) {
- if (newCurrentIndex < from + count)
- newCurrentIndex += (to-from);
- else if (newCurrentIndex < to + count)
- newCurrentIndex -= count;
+void QSGItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet)
+{
+ pendingChanges.apply(changeSet);
+
+ int moveId = -1;
+ int moveOffset;
+
+ foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
+ itemCount -= r.count;
+ if (moveId == -1 && newCurrentIndex >= r.index + r.count) {
+ newCurrentIndex -= r.count;
+ currentChanged = true;
+ } else if (moveId == -1 && newCurrentIndex >= r.index && newCurrentIndex < r.index + r.count) {
+ // current item has been removed.
+ if (r.isMove()) {
+ moveId = r.moveId;
+ moveOffset = newCurrentIndex - r.index;
+ } else {
+ currentRemoved = true;
+ newCurrentIndex = -1;
+ if (itemCount)
+ newCurrentIndex = qMin(r.index, itemCount - 1);
+ }
+ currentChanged = true;
}
- currentChanged = true;
- } else if (to < from) {
- if (newCurrentIndex >= to) {
- if (newCurrentIndex >= from && newCurrentIndex < from + count)
- newCurrentIndex -= (from-to);
- else if (newCurrentIndex < from)
- newCurrentIndex += count;
+ }
+ foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
+ itemCount += i.count;
+ if (moveId == -1) {
+ if (newCurrentIndex >= i.index) {
+ newCurrentIndex += i.count;
+ currentChanged = true;
+ } else if (newCurrentIndex < 0) {
+ newCurrentIndex = 0;
+ currentChanged = true;
+ }
+ } else if (moveId == i.moveId) {
+ newCurrentIndex = i.index + moveOffset;
}
- currentChanged = true;
}
}
-void QSGItemViewChangeSet::QSGItemViewChangeSet::doChange(int index, int count)
-{
- pendingChanges.change(index, count);
-}
-
void QSGItemViewChangeSet::prepare(int currentIndex, int count)
{
if (active)
@@ -193,11 +173,8 @@ void QSGItemView::setModel(const QVariant &model)
if (d->modelVariant == model)
return;
if (d->model) {
- disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- disconnect(d->model, SIGNAL(itemsChanged(int,int)), this, SLOT(itemsChanged(int,int)));
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
disconnect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
}
@@ -247,11 +224,8 @@ void QSGItemView::setModel(const QVariant &model)
}
d->updateViewport();
}
- connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- connect(d->model, SIGNAL(itemsChanged(int,int)), this, SLOT(itemsChanged(int,int)));
- connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
connect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
emit countChanged();
@@ -788,66 +762,25 @@ void QSGItemView::destroyRemoved()
d->layout();
}
-void QSGItemView::itemsInserted(int index, int count)
-{
- Q_D(QSGItemView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- d->currentChanges.prepare(d->currentIndex, d->itemCount);
- d->currentChanges.doInsert(index, count);
- polish();
-}
-
-void QSGItemView::itemsRemoved(int index, int count)
+void QSGItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
{
Q_D(QSGItemView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- d->currentChanges.prepare(d->currentIndex, d->itemCount);
- d->currentChanges.doRemove(index, count);
- polish();
-}
-
-void QSGItemView::itemsMoved(int from, int to, int count)
-{
- Q_D(QSGItemView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- if (from == to || count <= 0 || from < 0 || to < 0)
- return;
-
- d->currentChanges.prepare(d->currentIndex, d->itemCount);
- d->currentChanges.doMove(from, to, count);
- polish();
-}
-
-void QSGItemView::itemsChanged(int index, int count)
-{
- Q_D(QSGItemView);
- if (!isComponentComplete() || !d->model || !d->model->isValid())
- return;
-
- d->currentChanges.prepare(d->currentIndex, d->itemCount);
- d->currentChanges.doChange(index, count);
- polish();
-}
+ if (reset) {
+ d->moveReason = QSGItemViewPrivate::SetIndex;
+ d->regenerate();
+ if (d->highlight && d->currentItem) {
+ if (d->autoHighlight)
+ d->resetHighlightPosition();
+ d->updateTrackedItem();
+ }
+ d->moveReason = QSGItemViewPrivate::Other;
-void QSGItemView::modelReset()
-{
- Q_D(QSGItemView);
- d->moveReason = QSGItemViewPrivate::SetIndex;
- d->regenerate();
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
+ emit countChanged();
+ } else {
+ d->currentChanges.prepare(d->currentIndex, d->itemCount);
+ d->currentChanges.applyChanges(changeSet);
+ polish();
}
- d->moveReason = QSGItemViewPrivate::Other;
-
- emit countChanged();
}
void QSGItemView::createdItem(int index, QSGItem *item)
diff --git a/src/declarative/items/qsgitemview_p.h b/src/declarative/items/qsgitemview_p.h
index b1093ffdbe..9d25eab914 100644
--- a/src/declarative/items/qsgitemview_p.h
+++ b/src/declarative/items/qsgitemview_p.h
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QDeclarativeChangeSet;
class QSGItemViewPrivate;
@@ -192,15 +193,12 @@ protected slots:
virtual void updateSections() {}
void destroyRemoved();
void createdItem(int index, QSGItem *item);
- void modelReset();
+ void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
void destroyingItem(QSGItem *item);
void animStopped();
void trackedPositionChanged();
- void itemsInserted(int index, int count);
- void itemsRemoved(int index, int count);
- void itemsMoved(int from, int to, int count);
- void itemsChanged(int index, int count);
+
private:
Q_DECLARE_PRIVATE(QSGItemView)
diff --git a/src/declarative/items/qsgitemview_p_p.h b/src/declarative/items/qsgitemview_p_p.h
index afa50af952..73cb68c50b 100644
--- a/src/declarative/items/qsgitemview_p_p.h
+++ b/src/declarative/items/qsgitemview_p_p.h
@@ -83,10 +83,7 @@ public:
void prepare(int currentIndex, int count);
void reset();
- void doInsert(int index, int count);
- void doRemove(int index, int count);
- void doMove(int from, int to, int count);
- void doChange(int index, int count);
+ void applyChanges(const QDeclarativeChangeSet &changeSet);
int itemCount;
int newCurrentIndex;
diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp
index 11733df53e..a1038ad5e5 100644
--- a/src/declarative/items/qsgpathview.cpp
+++ b/src/declarative/items/qsgpathview.cpp
@@ -46,6 +46,7 @@
#include <private/qdeclarativestate_p.h>
#include <private/qdeclarativeopenmetaobject_p.h>
#include <private/qlistmodelinterface_p.h>
+#include <private/qdeclarativechangeset_p.h>
#include <QtGui/qevent.h>
#include <QtGui/qevent.h>
@@ -493,10 +494,8 @@ void QSGPathView::setModel(const QVariant &model)
return;
if (d->model) {
- disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
for (int i=0; i<d->items.count(); i++){
QSGItem *p = d->items[i];
@@ -524,10 +523,8 @@ void QSGPathView::setModel(const QVariant &model)
}
d->modelCount = 0;
if (d->model) {
- connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
d->modelCount = d->model->count();
if (d->model->count())
@@ -1479,121 +1476,98 @@ void QSGPathView::refill()
d->releaseItem(d->itemCache.takeLast());
}
-void QSGPathView::itemsInserted(int modelIndex, int count)
+void QSGPathView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
{
- //XXX support animated insertion
Q_D(QSGPathView);
- if (!d->isValid() || !isComponentComplete())
+ if (!d->model || !d->model->isValid() || !d->path || !isComponentComplete())
return;
- if (d->modelCount) {
- d->itemCache += d->items;
- d->items.clear();
- if (modelIndex <= d->currentIndex) {
- d->currentIndex += count;
- emit currentIndexChanged();
- } else if (d->offset != 0) {
- d->offset += count;
- d->offsetAdj += count;
- }
- }
-
- d->modelCount += count;
- if (d->flicking || d->moving) {
+ if (reset) {
+ d->modelCount = d->model->count();
d->regenerate();
- d->updateCurrent();
- } else {
- d->firstIndex = -1;
- d->updateMappedRange();
- d->scheduleLayout();
+ emit countChanged();
+ return;
}
- emit countChanged();
-}
-void QSGPathView::itemsRemoved(int modelIndex, int count)
-{
- //XXX support animated removal
- Q_D(QSGPathView);
- if (!d->model || !d->modelCount || !d->model->isValid() || !d->path || !isComponentComplete())
+ if (changeSet.removes().isEmpty() && changeSet.inserts().isEmpty())
return;
- // fix current
+ const int modelCount = d->modelCount;
+ int moveId = -1;
+ int moveOffset;
bool currentChanged = false;
- if (d->currentIndex >= modelIndex + count) {
- d->currentIndex -= count;
- currentChanged = true;
- } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
- // current item has been removed.
- d->currentIndex = qMin(modelIndex, d->modelCount-count-1);
- if (d->currentItem) {
- if (QSGPathViewAttached *att = d->attached(d->currentItem))
- att->setIsCurrentItem(true);
- d->releaseItem(d->currentItem);
- d->currentItem = 0;
+ bool changedOffset = false;
+ bool removed = false;
+ bool inserted = false;
+ foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
+ removed = true;
+ if (moveId == -1 && d->currentIndex >= r.index + r.count) {
+ d->currentIndex -= r.count;
+ currentChanged = true;
+ } else if (moveId == -1 && d->currentIndex >= r.index && d->currentIndex < r.index + r.count) {
+ // current item has been removed.
+ d->currentIndex = qMin(r.index, d->modelCount - r.count - 1);
+ if (r.isMove()) {
+ moveId = r.moveId;
+ moveOffset = d->currentIndex - r.index;
+ } else if (d->currentItem) {
+ if (QSGPathViewAttached *att = d->attached(d->currentItem))
+ att->setIsCurrentItem(true);
+ d->releaseItem(d->currentItem);
+ d->currentItem = 0;
+ }
+ currentChanged = true;
+ }
+
+ if (r.index > d->currentIndex) {
+ if (d->offset >= r.count) {
+ changedOffset = true;
+ d->offset -= r.count;
+ d->offsetAdj -= r.count;
+ }
+ }
+ d->modelCount -= r.count;
+ }
+ foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
+ inserted = true;
+ if (d->modelCount) {
+ if (moveId == -1 && i.index <= d->currentIndex) {
+ d->currentIndex += i.count;
+ } else if (d->offset != 0) {
+ if (moveId != -1 && moveId == i.moveId)
+ d->currentIndex = i.index + moveOffset;
+ d->offset += i.count;
+ d->offsetAdj += i.count;
+ }
}
- currentChanged = true;
+ d->modelCount += i.count;
}
d->itemCache += d->items;
d->items.clear();
- bool changedOffset = false;
- if (modelIndex > d->currentIndex) {
- if (d->offset >= count) {
- changedOffset = true;
- d->offset -= count;
- d->offsetAdj -= count;
- }
- }
-
- d->modelCount -= count;
if (!d->modelCount) {
while (d->itemCache.count())
d->releaseItem(d->itemCache.takeLast());
d->offset = 0;
changedOffset = true;
d->tl.reset(d->moveOffset);
- } else {
+ } else if (removed) {
d->regenerate();
d->updateCurrent();
if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange)
d->snapToCurrent();
+ } else if (inserted) {
+ d->firstIndex = -1;
+ d->updateMappedRange();
+ d->scheduleLayout();
}
if (changedOffset)
emit offsetChanged();
if (currentChanged)
emit currentIndexChanged();
- emit countChanged();
-}
-
-void QSGPathView::itemsMoved(int /*from*/, int /*to*/, int /*count*/)
-{
- Q_D(QSGPathView);
- if (!d->isValid() || !isComponentComplete())
- return;
-
- QList<QSGItem *> removedItems = d->items;
- d->items.clear();
- d->regenerate();
- while (removedItems.count())
- d->releaseItem(removedItems.takeLast());
-
- // Fix current index
- if (d->currentIndex >= 0 && d->currentItem) {
- int oldCurrent = d->currentIndex;
- d->currentIndex = d->model->indexOf(d->currentItem, this);
- if (oldCurrent != d->currentIndex)
- emit currentIndexChanged();
- }
- d->updateCurrent();
-}
-
-void QSGPathView::modelReset()
-{
- Q_D(QSGPathView);
- d->modelCount = d->model->count();
- d->regenerate();
- emit countChanged();
+ if (d->modelCount != modelCount)
+ emit countChanged();
}
void QSGPathView::createdItem(int index, QSGItem *item)
diff --git a/src/declarative/items/qsgpathview_p.h b/src/declarative/items/qsgpathview_p.h
index fa00294c0b..b70745ebcb 100644
--- a/src/declarative/items/qsgpathview_p.h
+++ b/src/declarative/items/qsgpathview_p.h
@@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QDeclarativeChangeSet;
+
class QSGPathViewPrivate;
class QSGPathViewAttached;
class Q_AUTOTEST_EXPORT QSGPathView : public QSGItem
@@ -186,10 +188,7 @@ private Q_SLOTS:
void refill();
void ticked();
void movementEnding();
- void itemsInserted(int index, int count);
- void itemsRemoved(int index, int count);
- void itemsMoved(int,int,int);
- void modelReset();
+ void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
void createdItem(int index, QSGItem *item);
void destroyingItem(QSGItem *item);
void pathUpdated();
diff --git a/src/declarative/items/qsgrepeater.cpp b/src/declarative/items/qsgrepeater.cpp
index 4e2fa63548..0037ea10eb 100644
--- a/src/declarative/items/qsgrepeater.cpp
+++ b/src/declarative/items/qsgrepeater.cpp
@@ -46,6 +46,7 @@
#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativelistaccessor_p.h>
#include <private/qlistmodelinterface_p.h>
+#include <private/qdeclarativechangeset_p.h>
QT_BEGIN_NAMESPACE
@@ -185,10 +186,8 @@ void QSGRepeater::setModel(const QVariant &model)
clear();
if (d->model) {
- disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
/*
disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
disconnect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
@@ -212,10 +211,8 @@ void QSGRepeater::setModel(const QVariant &model)
dataModel->setModel(model);
}
if (d->model) {
- connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
- connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
- connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
- connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
+ connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
/*
connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
connect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
@@ -368,72 +365,67 @@ void QSGRepeater::regenerate()
}
}
-void QSGRepeater::itemsInserted(int index, int count)
+void QSGRepeater::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
{
Q_D(QSGRepeater);
+
if (!isComponentComplete())
return;
- for (int i = 0; i < count; ++i) {
- int modelIndex = index + i;
- QSGItem *item = d->model->item(modelIndex);
- if (item) {
- QDeclarative_setParent_noEvent(item, parentItem());
- item->setParentItem(parentItem());
- if (modelIndex < d->deletables.count())
- item->stackBefore(d->deletables.at(modelIndex));
- else
- item->stackBefore(this);
- d->deletables.insert(modelIndex, item);
- emit itemAdded(modelIndex, item);
- }
- }
- emit countChanged();
-}
-void QSGRepeater::itemsRemoved(int index, int count)
-{
- Q_D(QSGRepeater);
- if (!isComponentComplete() || count <= 0)
- return;
- while (count--) {
- QSGItem *item = d->deletables.takeAt(index);
- emit itemRemoved(index, item);
- if (item)
- d->model->release(item);
- else
- break;
+ if (reset) {
+ regenerate();
+ emit countChanged();
}
- emit countChanged();
-}
-void QSGRepeater::itemsMoved(int from, int to, int count)
-{
- Q_D(QSGRepeater);
- if (!isComponentComplete() || count <= 0)
- return;
- if (from + count > d->deletables.count()) {
- regenerate();
- return;
+ int difference = 0;
+ QHash<int, QList<QPointer<QSGItem> > > moved;
+ foreach (const QDeclarativeChangeSet::Remove &remove, changeSet.removes()) {
+ int index = qMin(remove.index, d->deletables.count());
+ int count = qMin(remove.index + remove.count, d->deletables.count()) - index;
+ if (remove.isMove()) {
+ moved.insert(remove.moveId, d->deletables.mid(index, count));
+ d->deletables.erase(
+ d->deletables.begin() + index,
+ d->deletables.begin() + index + count);
+ } else while (count--) {
+ QSGItem *item = d->deletables.takeAt(index);
+ emit itemRemoved(index, item);
+ if (item)
+ d->model->release(item);
+ }
+
+ difference -= remove.count;
}
- QList<QSGItem*> removed;
- int removedCount = count;
- while (removedCount--)
- removed << d->deletables.takeAt(from);
- for (int i = 0; i < count; ++i)
- d->deletables.insert(to + i, removed.at(i));
- d->deletables.last()->stackBefore(this);
- for (int i = d->model->count()-1; i > 0; --i) {
- QSGItem *item = d->deletables.at(i-1);
- item->stackBefore(d->deletables.at(i));
+
+ foreach (const QDeclarativeChangeSet::Insert &insert, changeSet.inserts()) {
+ int index = qMin(insert.index, d->deletables.count());
+ if (insert.isMove()) {
+ QList<QPointer<QSGItem> > items = moved.value(insert.moveId);
+ d->deletables = d->deletables.mid(0, index) + items + d->deletables.mid(index);
+ QSGItem *stackBefore = index + items.count() < d->deletables.count()
+ ? d->deletables.at(index + items.count())
+ : this;
+ for (int i = index; i < index + items.count(); ++i)
+ d->deletables.at(i)->stackBefore(stackBefore);
+ } else for (int i = 0; i < insert.count; ++i) {
+ int modelIndex = index + i;
+ QSGItem *item = d->model->item(modelIndex);
+ if (item) {
+ QDeclarative_setParent_noEvent(item, parentItem());
+ item->setParentItem(parentItem());
+ if (modelIndex < d->deletables.count())
+ item->stackBefore(d->deletables.at(modelIndex));
+ else
+ item->stackBefore(this);
+ d->deletables.insert(modelIndex, item);
+ emit itemAdded(modelIndex, item);
+ }
+ }
+ difference += insert.count;
}
-}
-void QSGRepeater::modelReset()
-{
- if (!isComponentComplete())
- return;
- regenerate();
- emit countChanged();
+ if (difference != 0)
+ emit countChanged();
}
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgrepeater_p.h b/src/declarative/items/qsgrepeater_p.h
index 497f54c4e3..2094d94993 100644
--- a/src/declarative/items/qsgrepeater_p.h
+++ b/src/declarative/items/qsgrepeater_p.h
@@ -51,6 +51,8 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QDeclarativeChangeSet;
+
class QSGRepeaterPrivate;
class Q_AUTOTEST_EXPORT QSGRepeater : public QSGItem
{
@@ -92,10 +94,7 @@ protected:
void itemChange(ItemChange change, const ItemChangeData &value);
private Q_SLOTS:
- void itemsInserted(int,int);
- void itemsRemoved(int,int);
- void itemsMoved(int,int,int);
- void modelReset();
+ void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
private:
Q_DISABLE_COPY(QSGRepeater)
diff --git a/src/declarative/items/qsgvisualdatamodel.cpp b/src/declarative/items/qsgvisualdatamodel.cpp
index 219d1dc495..09f5d5d917 100644
--- a/src/declarative/items/qsgvisualdatamodel.cpp
+++ b/src/declarative/items/qsgvisualdatamodel.cpp
@@ -58,6 +58,7 @@
#include <private/qdeclarativeglobal_p.h>
#include <private/qmetaobjectbuilder_p.h>
#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativechangeset_p.h>
#include <private/qsgvisualadaptormodel_p.h>
#include <private/qobject_p.h>
@@ -90,6 +91,8 @@ public:
void emitDestroyingPackage(QDeclarativePackage *package) {
emit q_func()->destroyingPackage(package); }
+ void emitChanges();
+
QSGVisualAdaptorModel *m_adaptorModel;
QDeclarativeComponent *m_delegate;
QDeclarativeGuard<QDeclarativeContext> m_context;
@@ -145,6 +148,9 @@ public:
friend class QSGVisualDataModelData;
bool m_delegateValidated : 1;
bool m_completePending : 1;
+ bool m_reset : 1;
+
+ QDeclarativeChangeSet m_absoluteChangeSet;
QList<QByteArray> watchedRoles;
};
@@ -229,6 +235,7 @@ QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
, m_parts(0)
, m_delegateValidated(false)
, m_completePending(false)
+ , m_reset(false)
{
}
@@ -340,14 +347,10 @@ void QSGVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
bool wasValid = d->m_delegate != 0;
d->m_delegate = delegate;
d->m_delegateValidated = false;
- if (!wasValid && d->m_adaptorModel->count() && d->m_delegate) {
- emit itemsInserted(0, d->m_adaptorModel->count());
- emit countChanged();
- }
- if (wasValid && !d->m_delegate && d->m_adaptorModel->count()) {
+ if (!wasValid && d->m_adaptorModel->count() && d->m_delegate)
+ _q_itemsInserted(0, d->m_adaptorModel->count());
+ if (wasValid && !d->m_delegate && d->m_adaptorModel->count())
_q_itemsRemoved(0, d->m_adaptorModel->count());
- emit countChanged();
- }
}
/*!
@@ -620,7 +623,8 @@ void QSGVisualDataModel::_q_itemsChanged(int index, int count)
Q_D(QSGVisualDataModel);
if (!d->m_delegate)
return;
- emit itemsChanged(index, count);
+ d->m_absoluteChangeSet.change(index, count);
+ d->emitChanges();
}
void QSGVisualDataModel::_q_itemsInserted(int index, int count)
@@ -646,7 +650,8 @@ void QSGVisualDataModel::_q_itemsInserted(int index, int count)
}
d->m_cache.unite(items);
- emit itemsInserted(index, count);
+ d->m_absoluteChangeSet.insert(index, count);
+ d->emitChanges();
emit countChanged();
}
@@ -674,7 +679,8 @@ void QSGVisualDataModel::_q_itemsRemoved(int index, int count)
}
d->m_cache.unite(items);
- emit itemsRemoved(index, count);
+ d->m_absoluteChangeSet.remove(index, count);
+ d->emitChanges();
emit countChanged();
}
@@ -710,15 +716,29 @@ void QSGVisualDataModel::_q_itemsMoved(int from, int to, int count)
}
}
d->m_cache.unite(items);
- emit itemsMoved(from, to, count);
+ d->m_absoluteChangeSet.move(from, to, count);
+ d->emitChanges();
+}
+
+void QSGVisualDataModelPrivate::emitChanges()
+{
+ Q_Q(QSGVisualDataModel);
+ if (!m_absoluteChangeSet.isEmpty()) {
+ emit q->modelUpdated(m_absoluteChangeSet, m_reset);
+ m_absoluteChangeSet.clear();
+ m_reset = false;
+ }
}
-void QSGVisualDataModel::_q_modelReset(int, int)
+void QSGVisualDataModel::_q_modelReset(int oldCount, int newCount)
{
Q_D(QSGVisualDataModel);
if (!d->m_delegate)
return;
- emit modelReset();
+ d->m_absoluteChangeSet.remove(0, oldCount);
+ d->m_absoluteChangeSet.insert(0, newCount);
+ d->m_reset = true;
+ d->emitChanges();
emit countChanged();
}
@@ -729,11 +749,8 @@ QSGVisualPartsModel::QSGVisualPartsModel(QSGVisualDataModel *model, const QStrin
, m_model(model)
, m_part(part)
{
- connect(m_model, SIGNAL(modelReset()), this, SIGNAL(modelReset()));
- connect(m_model, SIGNAL(itemsInserted(int,int)), this, SIGNAL(itemsInserted(int,int)));
- connect(m_model, SIGNAL(itemsRemoved(int,int)), this, SIGNAL(itemsRemoved(int,int)));
- connect(m_model, SIGNAL(itemsChanged(int,int)), this, SIGNAL(itemsChanged(int,int)));
- connect(m_model, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int)));
+ connect(m_model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+ this, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
connect(m_model, SIGNAL(createdPackage(int,QDeclarativePackage*)),
this, SLOT(createdPackage(int,QDeclarativePackage*)));
connect(m_model, SIGNAL(destroyingPackage(QDeclarativePackage*)),
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
index fbc8a1abf2..90d008e618 100644
--- a/src/declarative/items/qsgvisualitemmodel.cpp
+++ b/src/declarative/items/qsgvisualitemmodel.cpp
@@ -46,6 +46,7 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeengine.h>
+#include <private/qdeclarativechangeset_p.h>
#include <private/qdeclarativeglobal_p.h>
#include <private/qobject_p.h>
@@ -82,7 +83,9 @@ public:
Q_Q(QSGVisualItemModel);
QSGVisualItemModelAttached *attached = QSGVisualItemModelAttached::properties(children.last().item);
attached->setIndex(children.count()-1);
- emit q->itemsInserted(children.count()-1, 1);
+ QDeclarativeChangeSet changeSet;
+ changeSet.insert(children.count() - 1, 1);
+ emit q->modelUpdated(changeSet, false);
emit q->countChanged();
}
diff --git a/src/declarative/items/qsgvisualitemmodel_p.h b/src/declarative/items/qsgvisualitemmodel_p.h
index 2eeff3c9c2..6e8606cc6b 100644
--- a/src/declarative/items/qsgvisualitemmodel_p.h
+++ b/src/declarative/items/qsgvisualitemmodel_p.h
@@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QSGItem;
+class QDeclarativeChangeSet;
class Q_DECLARATIVE_EXPORT QSGVisualModel : public QObject
{
@@ -79,11 +80,7 @@ public:
Q_SIGNALS:
void countChanged();
- void itemsInserted(int index, int count);
- void itemsRemoved(int index, int count);
- void itemsMoved(int from, int to, int count);
- void itemsChanged(int index, int count);
- void modelReset();
+ void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
void createdItem(int index, QSGItem *item);
void destroyingItem(QSGItem *item);