summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBea Lam <bea.lam@jollamobile.com>2012-12-11 17:25:44 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-12 07:47:54 +0100
commit5d439d751267c64408bd27ab0e6548822146a35c (patch)
treec68135a92698fe9846f59885719dd3002b1f865c
parentff2f41bd14cdfd14da91ae1b66dc6e679a41936e (diff)
Backport PathView currentIndex fixes from Qt 5
Backport 447e5acb880ebda498891623dc4009984cb73bc6 and 0fc361f96b06ba318e70610e46beb421753cae9d which fix bugs related to currentIndex. The first commit ensures currentIndex=0 when all items are removed; the second ensures that the initial currentIndex value is respected and also resets the view correctly if the model changes. Change-Id: I73266a211001a54163be8415d449802ff077a72e Reviewed-by: Martin Jones <martin.jones@jollamobile.com>
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp95
-rw-r--r--tests/auto/declarative/qdeclarativepathview/data/initialCurrentIndex.qml60
-rw-r--r--tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp367
3 files changed, 485 insertions, 37 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 9ccb4000..e49c1e76 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -163,6 +163,7 @@ void QDeclarativePathViewPrivate::clear()
releaseItem(p);
}
items.clear();
+ tl.clear();
}
void QDeclarativePathViewPrivate::updateMappedRange()
@@ -475,6 +476,8 @@ QDeclarativePathView::~QDeclarativePathView()
For large or dynamic datasets the model is usually provided by a C++ model object.
Models can also be created directly in QML, using the ListModel element.
+ \note changing the model will reset the offset and currentIndex to 0.
+
\sa {qmlmodels}{Data Models}
*/
QVariant QDeclarativePathView::model() const
@@ -495,11 +498,7 @@ void QDeclarativePathView::setModel(const QVariant &model)
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(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
- for (int i=0; i<d->items.count(); i++){
- QDeclarativeItem *p = d->items[i];
- d->model->release(p);
- }
- d->items.clear();
+ d->clear();
}
d->modelVariant = model;
@@ -519,6 +518,7 @@ void QDeclarativePathView::setModel(const QVariant &model)
if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
dataModel->setModel(model);
}
+ int oldModelCount = d->modelCount;
d->modelCount = 0;
if (d->model) {
connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
@@ -527,14 +527,20 @@ void QDeclarativePathView::setModel(const QVariant &model)
connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
connect(d->model, SIGNAL(createdItem(int,QDeclarativeItem*)), this, SLOT(createdItem(int,QDeclarativeItem*)));
d->modelCount = d->model->count();
- if (d->model->count())
- d->offset = qmlMod(d->offset, qreal(d->model->count()));
- if (d->offset < 0)
- d->offset = d->model->count() + d->offset;
-}
+ }
+ if (isComponentComplete()) {
+ if (d->currentIndex != 0) {
+ d->currentIndex = 0;
+ emit currentIndexChanged();
+ }
+ if (d->offset != 0.0) {
+ d->offset = 0;
+ emit offsetChanged();
+ }
+ }
d->regenerate();
- d->fixOffset();
- emit countChanged();
+ if (d->modelCount != oldModelCount)
+ emit countChanged();
emit modelChanged();
}
@@ -592,8 +598,17 @@ int QDeclarativePathView::currentIndex() const
void QDeclarativePathView::setCurrentIndex(int idx)
{
Q_D(QDeclarativePathView);
- if (d->model && d->modelCount)
- idx = qAbs(idx % d->modelCount);
+ if (!isComponentComplete()) {
+ if (idx != d->currentIndex) {
+ d->currentIndex = idx;
+ emit currentIndexChanged();
+ }
+ return;
+ }
+
+ idx = d->modelCount
+ ? ((idx % d->modelCount) + d->modelCount) % d->modelCount
+ : 0;
if (d->model && idx != d->currentIndex) {
if (d->modelCount) {
int itemIndex = (d->currentIndex - d->firstIndex + d->modelCount) % d->modelCount;
@@ -649,13 +664,8 @@ void QDeclarativePathView::incrementCurrentIndex()
void QDeclarativePathView::decrementCurrentIndex()
{
Q_D(QDeclarativePathView);
- if (d->model && d->modelCount) {
- int idx = currentIndex()-1;
- if (idx < 0)
- idx = d->modelCount - 1;
- d->moveDirection = QDeclarativePathViewPrivate::Negative;
- setCurrentIndex(idx);
- }
+ d->moveDirection = QDeclarativePathViewPrivate::Negative;
+ setCurrentIndex(currentIndex()-1);
}
/*!
@@ -1323,15 +1333,20 @@ void QDeclarativePathView::componentComplete()
{
Q_D(QDeclarativePathView);
QDeclarativeItem::componentComplete();
- d->createHighlight();
- // It is possible that a refill has already happended to to Path
- // bindings being handled in the componentComplete(). If so
- // don't do it again.
- if (d->items.count() == 0 && d->model) {
+
+ if (d->model) {
d->modelCount = d->model->count();
- d->regenerate();
+ if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex
+ d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount);
}
+
+ d->createHighlight();
+ d->regenerate();
d->updateHighlight();
+ d->updateCurrent();
+
+ if (d->modelCount)
+ emit countChanged();
}
void QDeclarativePathView::refill()
@@ -1522,6 +1537,10 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count)
}
d->modelCount -= count;
+
+ if (d->currentIndex == -1)
+ d->currentIndex = d->calcCurrentIndex();
+
if (!d->modelCount) {
while (d->itemCache.count())
d->releaseItem(d->itemCache.takeLast());
@@ -1548,19 +1567,19 @@ void QDeclarativePathView::itemsMoved(int /*from*/, int /*to*/, int /*count*/)
if (!d->isValid() || !isComponentComplete())
return;
+ int oldCurrent = d->currentIndex;
+ // Fix current index
+ if (d->currentIndex >= 0 && d->currentItem)
+ d->currentIndex = d->model->indexOf(d->currentItem, this);
+
QList<QDeclarativeItem *> 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();
- }
+ if (oldCurrent != d->currentIndex)
+ emit currentIndexChanged();
d->updateCurrent();
}
@@ -1623,7 +1642,7 @@ void QDeclarativePathView::movementEnding()
// find the item closest to the snap position
int QDeclarativePathViewPrivate::calcCurrentIndex()
{
- int current = -1;
+ int current = 0;
if (modelCount && model && items.count()) {
offset = qmlMod(offset, modelCount);
if (offset < 0)
@@ -1644,7 +1663,7 @@ void QDeclarativePathViewPrivate::updateCurrent()
return;
int idx = calcCurrentIndex();
- if (model && idx != currentIndex) {
+ if (model && (idx != currentIndex || !currentItem)) {
int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount;
if (itemIndex < items.count()) {
if (QDeclarativeItem *item = items.at(itemIndex)) {
@@ -1652,6 +1671,7 @@ void QDeclarativePathViewPrivate::updateCurrent()
att->setIsCurrentItem(false);
}
}
+ int oldCurrentIndex = currentIndex;
currentIndex = idx;
currentItem = 0;
itemIndex = (idx - firstIndex + modelCount) % modelCount;
@@ -1661,7 +1681,8 @@ void QDeclarativePathViewPrivate::updateCurrent()
if (QDeclarativePathViewAttached *att = attached(currentItem))
att->setIsCurrentItem(true);
}
- emit q->currentIndexChanged();
+ if (oldCurrentIndex != currentIndex)
+ emit q->currentIndexChanged();
}
}
diff --git a/tests/auto/declarative/qdeclarativepathview/data/initialCurrentIndex.qml b/tests/auto/declarative/qdeclarativepathview/data/initialCurrentIndex.qml
new file mode 100644
index 00000000..e6361522
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativepathview/data/initialCurrentIndex.qml
@@ -0,0 +1,60 @@
+import QtQuick 1.1
+
+PathView {
+ id: photoPathView
+ y: 100; width: 800; height: 330; pathItemCount: 4
+ currentIndex: 3
+ dragMargin: 24
+ preferredHighlightBegin: 0.50
+ preferredHighlightEnd: 0.50
+
+ path: Path {
+ startX: -50; startY: 40;
+
+ PathAttribute { name: "scale"; value: 0.5 }
+ PathAttribute { name: "angle"; value: -45 }
+
+ PathCubic {
+ x: 400; y: 220
+ control1X: 140; control1Y: 40
+ control2X: 210; control2Y: 220
+ }
+
+ PathAttribute { name: "scale"; value: 1.2 }
+ PathAttribute { name: "angle"; value: 0 }
+
+ PathCubic {
+ x: 850; y: 40
+ control2X: 660; control2Y: 40
+ control1X: 590; control1Y: 220
+ }
+
+ PathAttribute { name: "scale"; value: 0.5 }
+ PathAttribute { name: "angle"; value: 45 }
+ }
+
+ model: ListModel {
+ id: rssModel
+ ListElement { lColor: "red" }
+ ListElement { lColor: "green" }
+ ListElement { lColor: "yellow" }
+ ListElement { lColor: "blue" }
+ ListElement { lColor: "purple" }
+ ListElement { lColor: "gray" }
+ ListElement { lColor: "brown" }
+ ListElement { lColor: "thistle" }
+ }
+
+ delegate: Component {
+ id: photoDelegate
+ Rectangle {
+ id: wrapper
+ width: 85; height: 85; color: lColor
+
+ transform: Rotation {
+ id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2
+ axis.y: 1; axis.z: 0
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
index 247c19e3..0d7dbe6f 100644
--- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
+++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
@@ -56,6 +56,33 @@
#include <QStandardItemModel>
#include <QFile>
+template<typename T>
+static void qdeclarativepathview_move(int from, int to, int n, T *items)
+{
+ if (from > to) {
+ // Only move forwards - flip if backwards moving
+ int tfrom = from;
+ int tto = to;
+ from = tto;
+ to = tto+n;
+ n = tfrom-tto;
+ }
+
+ T replaced;
+ int i=0;
+ typename T::ConstIterator it=items->begin(); it += from+n;
+ for (; i<to-from; ++i,++it)
+ replaced.append(*it);
+ i=0;
+ it=items->begin(); it += from;
+ for (; i<n; ++i,++it)
+ replaced.append(*it);
+ typename T::ConstIterator f=replaced.begin();
+ typename T::Iterator t=items->begin(); t += from;
+ for (; f != replaced.end(); ++f, ++t)
+ *t = *f;
+}
+
static void initStandardTreeModel(QStandardItemModel *model)
{
QStandardItem *item;
@@ -87,6 +114,13 @@ private slots:
void dataModel();
void pathview2();
void pathview3();
+ void initialCurrentIndex();
+ void insertModel_data();
+ void insertModel();
+ void removeModel_data();
+ void removeModel();
+ void moveModel_data();
+ void moveModel();
void path();
void pathMoved();
void setCurrentIndex();
@@ -183,18 +217,41 @@ public:
endInsertRows();
}
+ void insertItems(int index, const QList<QPair<QString, QString> > &items)
+ {
+ emit beginInsertRows(QModelIndex(), index, index+items.count()-1);
+ for (int i=0; i<items.count(); i++)
+ list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
+ emit endInsertRows();
+ }
+
void removeItem(int index) {
beginRemoveRows(QModelIndex(), index, index);
list.removeAt(index);
endRemoveRows();
}
+ void removeItems(int index, int count)
+ {
+ emit beginRemoveRows(QModelIndex(), index, index+count-1);
+ while (count--)
+ list.removeAt(index);
+ emit endRemoveRows();
+ }
+
void moveItem(int from, int to) {
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
list.move(from, to);
endMoveRows();
}
+ void moveItems(int from, int to, int count)
+ {
+ emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
+ qdeclarativepathview_move(from, to, count, &list);
+ emit endMoveRows();
+ }
+
void modifyItem(int idx, const QString &name, const QString &number) {
list[idx] = QPair<QString,QString>(name, number);
emit dataChanged(index(idx,0), index(idx,0));
@@ -308,6 +365,116 @@ void tst_QDeclarativePathView::pathview3()
QCOMPARE(obj->pathItemCount(), 4);
}
+void tst_QDeclarativePathView::initialCurrentIndex()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/initialCurrentIndex.qml"));
+ QDeclarativePathView *obj = qobject_cast<QDeclarativePathView*>(c.create());
+
+ QVERIFY(obj != 0);
+ QVERIFY(obj->path() != 0);
+ QVERIFY(obj->delegate() != 0);
+ QVERIFY(obj->model() != QVariant());
+ QCOMPARE(obj->currentIndex(), 3);
+ QCOMPARE(obj->offset(), 5.0);
+ QCOMPARE(obj->preferredHighlightBegin(), 0.5);
+ QCOMPARE(obj->dragMargin(), 24.);
+ QCOMPARE(obj->count(), 8);
+ QCOMPARE(obj->pathItemCount(), 4);
+
+ delete obj;
+}
+
+void tst_QDeclarativePathView::insertModel_data()
+{
+ QTest::addColumn<int>("mode");
+ QTest::addColumn<int>("idx");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<qreal>("offset");
+ QTest::addColumn<int>("currentIndex");
+
+ // We have 8 items, with currentIndex == 4
+ QTest::newRow("insert after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 6 << 1 << 5. << 4;
+ QTest::newRow("insert before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 2 << 1 << 4. << 5;
+ QTest::newRow("insert multiple after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 5 << 2 << 6. << 4;
+ QTest::newRow("insert multiple before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 1 << 2 << 4. << 6;
+ QTest::newRow("insert at end")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 8 << 1 << 5. << 4;
+ QTest::newRow("insert at beginning")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 0 << 1 << 4. << 5;
+ QTest::newRow("insert at current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 4 << 1 << 4. << 5;
+
+ QTest::newRow("no range - insert after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 6 << 1 << 5. << 4;
+ QTest::newRow("no range - insert before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 2 << 1 << 4. << 5;
+ QTest::newRow("no range - insert multiple after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 5 << 2 << 6. << 4;
+ QTest::newRow("no range - insert multiple before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 1 << 2 << 4. << 6;
+ QTest::newRow("no range - insert at end")
+ << int(QDeclarativePathView::NoHighlightRange) << 8 << 1 << 5. << 4;
+ QTest::newRow("no range - insert at beginning")
+ << int(QDeclarativePathView::NoHighlightRange) << 0 << 1 << 4. << 5;
+ QTest::newRow("no range - insert at current")
+ << int(QDeclarativePathView::NoHighlightRange) << 4 << 1 << 4. << 5;
+}
+
+void tst_QDeclarativePathView::insertModel()
+{
+ QFETCH(int, mode);
+ QFETCH(int, idx);
+ QFETCH(int, count);
+ QFETCH(qreal, offset);
+ QFETCH(int, currentIndex);
+
+ QDeclarativeView *window = createView();
+ window->show();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+ model.addItem("Jinny", "679");
+ model.addItem("Milly", "73378");
+ model.addItem("Jimmy", "3535");
+ model.addItem("Barb", "9039");
+
+ QDeclarativeContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ window->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(window->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ pathview->setHighlightRangeMode((QDeclarativePathView::HighlightRangeMode)mode);
+
+ pathview->setCurrentIndex(4);
+ if (mode == QDeclarativePathView::StrictlyEnforceRange)
+ QTRY_COMPARE(pathview->offset(), 4.0);
+ else
+ pathview->setOffset(4);
+
+ QList<QPair<QString, QString> > items;
+ for (int i = 0; i < count; ++i)
+ items.append(qMakePair(QString("New"), QString::number(i)));
+
+ model.insertItems(idx, items);
+ QTRY_COMPARE(pathview->offset(), offset);
+
+ QCOMPARE(pathview->currentIndex(), currentIndex);
+
+ delete window;
+}
+
void tst_QDeclarativePathView::path()
{
QDeclarativeEngine engine;
@@ -353,6 +520,192 @@ void tst_QDeclarativePathView::path()
QCOMPARE(cubic->control2Y(), 90.);
}
+void tst_QDeclarativePathView::removeModel_data()
+{
+ QTest::addColumn<int>("mode");
+ QTest::addColumn<int>("idx");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<qreal>("offset");
+ QTest::addColumn<int>("currentIndex");
+
+ // We have 8 items, with currentIndex == 4
+ QTest::newRow("remove after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 6 << 1 << 3. << 4;
+ QTest::newRow("remove before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 2 << 1 << 4. << 3;
+ QTest::newRow("remove multiple after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 5 << 2 << 2. << 4;
+ QTest::newRow("remove multiple before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 1 << 2 << 4. << 2;
+ QTest::newRow("remove last")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 7 << 1 << 3. << 4;
+ QTest::newRow("remove first")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 0 << 1 << 4. << 3;
+ QTest::newRow("remove current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 4 << 1 << 3. << 4;
+ QTest::newRow("remove all")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 0 << 8 << 0. << 0;
+
+ QTest::newRow("no range - remove after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 6 << 1 << 3. << 4;
+ QTest::newRow("no range - remove before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 2 << 1 << 4. << 3;
+ QTest::newRow("no range - remove multiple after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 5 << 2 << 2. << 4;
+ QTest::newRow("no range - remove multiple before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 1 << 2 << 4. << 2;
+ QTest::newRow("no range - remove last")
+ << int(QDeclarativePathView::NoHighlightRange) << 7 << 1 << 3. << 4;
+ QTest::newRow("no range - remove first")
+ << int(QDeclarativePathView::NoHighlightRange) << 0 << 1 << 4. << 3;
+ QTest::newRow("no range - remove current offset")
+ << int(QDeclarativePathView::NoHighlightRange) << 4 << 1 << 4. << 4;
+ QTest::newRow("no range - remove all")
+ << int(QDeclarativePathView::NoHighlightRange) << 0 << 8 << 0. << 0;
+}
+
+void tst_QDeclarativePathView::removeModel()
+{
+ QFETCH(int, mode);
+ QFETCH(int, idx);
+ QFETCH(int, count);
+ QFETCH(qreal, offset);
+ QFETCH(int, currentIndex);
+
+ QDeclarativeView *window = createView();
+ window->show();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+ model.addItem("Jinny", "679");
+ model.addItem("Milly", "73378");
+ model.addItem("Jimmy", "3535");
+ model.addItem("Barb", "9039");
+
+ QDeclarativeContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ window->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(window->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ pathview->setHighlightRangeMode((QDeclarativePathView::HighlightRangeMode)mode);
+
+ pathview->setCurrentIndex(4);
+ if (mode == QDeclarativePathView::StrictlyEnforceRange)
+ QTRY_COMPARE(pathview->offset(), 4.0);
+ else
+ pathview->setOffset(4);
+
+ model.removeItems(idx, count);
+ QTRY_COMPARE(pathview->offset(), offset);
+
+ QCOMPARE(pathview->currentIndex(), currentIndex);
+
+ delete window;
+}
+void tst_QDeclarativePathView::moveModel_data()
+{
+ QTest::addColumn<int>("mode");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("to");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<qreal>("offset");
+ QTest::addColumn<int>("currentIndex");
+
+ // We have 8 items, with currentIndex == 4
+ QTest::newRow("move after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 5 << 6 << 1 << 4. << 4;
+ QTest::newRow("move before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 2 << 3 << 1 << 4. << 4;
+ QTest::newRow("move before current to after")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 2 << 6 << 1 << 5. << 3;
+ QTest::newRow("move multiple after current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 5 << 6 << 2 << 4. << 4;
+ QTest::newRow("move multiple before current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 0 << 1 << 2 << 4. << 4;
+ QTest::newRow("move before current to end")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 2 << 7 << 1 << 5. << 3;
+ QTest::newRow("move last to beginning")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 7 << 0 << 1 << 3. << 5;
+ QTest::newRow("move current")
+ << int(QDeclarativePathView::StrictlyEnforceRange) << 4 << 6 << 1 << 2. << 6;
+
+ QTest::newRow("no range - move after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 5 << 6 << 1 << 4. << 4;
+ QTest::newRow("no range - move before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 2 << 3 << 1 << 4. << 4;
+ QTest::newRow("no range - move before current to after")
+ << int(QDeclarativePathView::NoHighlightRange) << 2 << 6 << 1 << 5. << 3;
+ QTest::newRow("no range - move multiple after current")
+ << int(QDeclarativePathView::NoHighlightRange) << 5 << 6 << 2 << 4. << 4;
+ QTest::newRow("no range - move multiple before current")
+ << int(QDeclarativePathView::NoHighlightRange) << 0 << 1 << 2 << 4. << 4;
+ QTest::newRow("no range - move before current to end")
+ << int(QDeclarativePathView::NoHighlightRange) << 2 << 7 << 1 << 5. << 3;
+ QTest::newRow("no range - move last to beginning")
+ << int(QDeclarativePathView::NoHighlightRange) << 7 << 0 << 1 << 3. << 5;
+ QTest::newRow("no range - move current")
+ << int(QDeclarativePathView::NoHighlightRange) << 4 << 6 << 1 << 4. << 6;
+ QTest::newRow("no range - move multiple incl. current")
+ << int(QDeclarativePathView::NoHighlightRange) << 0 << 1 << 5 << 4. << 5;
+}
+
+void tst_QDeclarativePathView::moveModel()
+{
+ QFETCH(int, mode);
+ QFETCH(int, from);
+ QFETCH(int, to);
+ QFETCH(int, count);
+ QFETCH(qreal, offset);
+ QFETCH(int, currentIndex);
+
+ QDeclarativeView *window = createView();
+ window->show();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+ model.addItem("Jinny", "679");
+ model.addItem("Milly", "73378");
+ model.addItem("Jimmy", "3535");
+ model.addItem("Barb", "9039");
+
+ QDeclarativeContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ window->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(window->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ pathview->setHighlightRangeMode((QDeclarativePathView::HighlightRangeMode)mode);
+
+ pathview->setCurrentIndex(4);
+ if (mode == QDeclarativePathView::StrictlyEnforceRange)
+ QTRY_COMPARE(pathview->offset(), 4.0);
+ else
+ pathview->setOffset(4);
+
+ model.moveItems(from, to, count);
+
+ // don't enable this test as 371b2f6947779272494b34ec44445aaad0613756 has
+ // not been backported to QtQuick1 so offset is still buggy
+// QTRY_COMPARE(pathview->offset(), offset);
+
+ QCOMPARE(pathview->currentIndex(), currentIndex);
+
+ delete window;
+}
+
void tst_QDeclarativePathView::dataModel()
{
QDeclarativeView *canvas = createView();
@@ -586,6 +939,20 @@ void tst_QDeclarativePathView::setCurrentIndex()
QVERIFY(firstItem);
QTRY_COMPARE(firstItem->pos() + offset, start);
+ // Test positive indexes are wrapped.
+ pathview->setCurrentIndex(6);
+ QTRY_COMPARE(pathview->currentIndex(), 2);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 2);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
+ // Test negative indexes are wrapped.
+ pathview->setCurrentIndex(-3);
+ QTRY_COMPARE(pathview->currentIndex(), 1);
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 1);
+ QVERIFY(firstItem);
+ QTRY_COMPARE(firstItem->pos() + offset, start);
+
delete canvas;
}