From: Andrew den Exter Date: Mon, 1 Aug 2011 03:09:10 +0000 (+1000) Subject: Add a currentItem property to PathView. X-Git-Tag: qt-v5.0.0-alpha1~1990 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6494f5c5aaec82cc5bcfd42de559d723edef57b1;p=profile%2Fivi%2Fqtdeclarative.git Add a currentItem property to PathView. Task-number: QTBUG-16347 Change-Id: I6df4b2d7c5f325e84d54ed5befd66e20b64cc7e0 Reviewed-on: http://codereview.qt.nokia.com/2421 Reviewed-by: Qt Sanity Bot Reviewed-by: Martin Jones --- diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc index 1eb64f9..d3db134 100644 --- a/doc/src/declarative/whatsnew.qdoc +++ b/doc/src/declarative/whatsnew.qdoc @@ -65,6 +65,13 @@ QDeclarativeView and QDeclarativeItem headers are now in the QtQuick 1 module, i the library (lib/libQtQuick1*) and plugin (imports/QtQuick/) must be installed. +\section2 PathView + +Added the following properties: +\list +\o \l {PathView::}{currentItem} +\endlist + \section1 Qt 4.7.4 includes QtQuick 1.1 QtQuick 1.1 is a minor feature update. \e {import QtQuick 1.1} to use the new diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp index 9fae40f..4a0496c 100644 --- a/src/declarative/items/qsgpathview.cpp +++ b/src/declarative/items/qsgpathview.cpp @@ -111,7 +111,7 @@ void QSGPathViewPrivate::init() q, movementEndingIdx, Qt::DirectConnection); } -QSGItem *QSGPathViewPrivate::getItem(int modelIndex) +QSGItem *QSGPathViewPrivate::getItem(int modelIndex, bool onPath) { Q_Q(QSGPathView); requestedIndex = modelIndex; @@ -128,7 +128,7 @@ QSGItem *QSGPathViewPrivate::getItem(int modelIndex) qPathViewAttachedType = 0; if (att) { att->m_view = q; - att->setOnPath(true); + att->setOnPath(onPath); } item->setParentItem(q); QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item); @@ -158,6 +158,10 @@ QSGPathViewAttached *QSGPathViewPrivate::attached(QSGItem *item) void QSGPathViewPrivate::clear() { + if (currentItem) { + releaseItem(currentItem); + currentItem = 0; + } for (int i=0; imodel && d->modelCount) idx = qAbs(idx % d->modelCount); if (d->model && idx != d->currentIndex) { - if (d->modelCount) { - int itemIndex = (d->currentIndex - d->firstIndex + d->modelCount) % d->modelCount; - if (itemIndex < d->items.count()) { - if (QSGItem *item = d->items.at(itemIndex)) { - if (QSGPathViewAttached *att = d->attached(item)) - att->setIsCurrentItem(false); - } - } + if (d->currentItem) { + if (QSGPathViewAttached *att = d->attached(d->currentItem)) + att->setIsCurrentItem(false); + d->releaseItem(d->currentItem); } d->currentItem = 0; d->moveReason = QSGPathViewPrivate::SetIndex; d->currentIndex = idx; if (d->modelCount) { - if (d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange) - d->snapToCurrent(); int itemIndex = (idx - d->firstIndex + d->modelCount) % d->modelCount; if (itemIndex < d->items.count()) { - d->currentItem = d->items.at(itemIndex); + d->currentItem = d->model->item(d->currentIndex, true); d->currentItem->setFocus(true); if (QSGPathViewAttached *att = d->attached(d->currentItem)) att->setIsCurrentItem(true); + } else { + d->currentItem = d->getItem(d->currentIndex, false); + d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0); + if (QSGPathViewAttached *att = d->attached(d->currentItem)) + att->setIsCurrentItem(true); + if (d->model->completePending()) + d->model->completeItem(); } + if (d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange) + d->snapToCurrent(); d->currentItemOffset = d->positionOfIndex(d->currentIndex); d->updateHighlight(); } @@ -499,6 +506,12 @@ void QSGPathView::setCurrentIndex(int idx) } } +QSGItem *QSGPathView::currentItem() const +{ + Q_D(const QSGPathView); + return d->currentItem; +} + void QSGPathView::incrementCurrentIndex() { Q_D(QSGPathView); @@ -1092,12 +1105,8 @@ void QSGPathView::refill() if (d->model->completePending()) item->setZ(idx+1); if (d->currentIndex == idx) { - item->setFocus(true); - if (QSGPathViewAttached *att = d->attached(item)) - att->setIsCurrentItem(true); currentVisible = true; d->currentItemOffset = pos; - d->currentItem = item; } if (d->items.count() == 0) d->firstIndex = idx; @@ -1121,12 +1130,8 @@ void QSGPathView::refill() if (d->model->completePending()) item->setZ(idx+1); if (d->currentIndex == idx) { - item->setFocus(true); - if (QSGPathViewAttached *att = d->attached(item)) - att->setIsCurrentItem(true); currentVisible = true; d->currentItemOffset = pos; - d->currentItem = item; } d->items.prepend(item); d->updateItem(item, pos); @@ -1141,8 +1146,25 @@ void QSGPathView::refill() } } - if (!currentVisible) + if (!currentVisible) { d->currentItemOffset = 1.0; + if (d->currentItem) { + if (QSGPathViewAttached *att = d->attached(d->currentItem)) + att->setOnPath(false); + } else if (d->currentIndex >= 0 && d->currentIndex < d->modelCount) { + d->currentItem = d->getItem(d->currentIndex, false); + d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0); + if (QSGPathViewAttached *att = d->attached(d->currentItem)) + att->setIsCurrentItem(true); + if (d->model->completePending()) + d->model->completeItem(); + } + } else if (!d->currentItem) { + d->currentItem = d->model->item(d->currentIndex, true); + d->currentItem->setFocus(true); + if (QSGPathViewAttached *att = d->attached(d->currentItem)) + att->setIsCurrentItem(true); + } if (d->highlightItem && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange) { d->updateItem(d->highlightItem, d->highlightRangeStart); @@ -1206,6 +1228,8 @@ void QSGPathView::itemsRemoved(int modelIndex, int count) if (d->currentItem) { if (QSGPathViewAttached *att = d->attached(d->currentItem)) att->setIsCurrentItem(true); + d->releaseItem(d->currentItem); + d->currentItem = 0; } currentChanged = true; } @@ -1345,21 +1369,26 @@ void QSGPathViewPrivate::updateCurrent() int idx = calcCurrentIndex(); if (model && idx != currentIndex) { - int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount; - if (itemIndex < items.count()) { - if (QSGItem *item = items.at(itemIndex)) { - if (QSGPathViewAttached *att = attached(item)) - att->setIsCurrentItem(false); - } + if (currentItem) { + if (QSGPathViewAttached *att = attached(currentItem)) + att->setIsCurrentItem(false); + releaseItem(currentItem); } currentIndex = idx; currentItem = 0; - itemIndex = (idx - firstIndex + modelCount) % modelCount; + int itemIndex = (idx - firstIndex + modelCount) % modelCount; if (itemIndex < items.count()) { - currentItem = items.at(itemIndex); + currentItem = model->item(currentIndex, true); currentItem->setFocus(true); if (QSGPathViewAttached *att = attached(currentItem)) att->setIsCurrentItem(true); + } else if (currentIndex >= 0 && currentIndex < modelCount) { + currentItem = getItem(currentIndex, false); + updateItem(currentItem, currentIndex < firstIndex ? 0.0 : 1.0); + if (QSGPathViewAttached *att = attached(currentItem)) + att->setIsCurrentItem(true); + if (model->completePending()) + model->completeItem(); } emit q->currentIndexChanged(); } diff --git a/src/declarative/items/qsgpathview_p.h b/src/declarative/items/qsgpathview_p.h index c91c4b6..a271e32 100644 --- a/src/declarative/items/qsgpathview_p.h +++ b/src/declarative/items/qsgpathview_p.h @@ -62,6 +62,7 @@ class Q_AUTOTEST_EXPORT QSGPathView : public QSGItem Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(QDeclarativePath *path READ path WRITE setPath NOTIFY pathChanged) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(QSGItem *currentItem READ currentItem NOTIFY currentIndexChanged) Q_PROPERTY(qreal offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(QDeclarativeComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged) @@ -98,6 +99,8 @@ public: int currentIndex() const; void setCurrentIndex(int idx); + QSGItem *currentItem() const; + qreal offset() const; void setOffset(qreal offset); diff --git a/src/declarative/items/qsgpathview_p_p.h b/src/declarative/items/qsgpathview_p_p.h index a133e80..1575c6c 100644 --- a/src/declarative/items/qsgpathview_p_p.h +++ b/src/declarative/items/qsgpathview_p_p.h @@ -111,7 +111,7 @@ public: } } - QSGItem *getItem(int modelIndex); + QSGItem *getItem(int modelIndex, bool onPath = true); void releaseItem(QSGItem *item); QSGPathViewAttached *attached(QSGItem *item); void clear(); diff --git a/tests/auto/declarative/qsgpathview/data/pathview0.qml b/tests/auto/declarative/qsgpathview/data/pathview0.qml index 72b71a3..8b93781 100644 --- a/tests/auto/declarative/qsgpathview/data/pathview0.qml +++ b/tests/auto/declarative/qsgpathview/data/pathview0.qml @@ -17,6 +17,7 @@ Rectangle { Rectangle { id: wrapper objectName: "wrapper" + property bool onPath: PathView.onPath height: root.delegateHeight width: root.delegateWidth scale: root.delegateScale diff --git a/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp b/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp index 91f6491..00202f7 100644 --- a/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp +++ b/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp @@ -423,6 +423,7 @@ void tst_QSGPathView::dataModel() QTRY_COMPARE(findItems(pathview, "wrapper").count(), 14); QVERIFY(pathview->currentIndex() == 0); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); QSGText *text = findItem(pathview, "myText", 4); QVERIFY(text); @@ -433,6 +434,7 @@ void tst_QSGPathView::dataModel() text = findItem(pathview, "myText", 2); QVERIFY(text); QCOMPARE(text->text(), model.name(2)); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); testObject->setPathItemCount(5); QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); @@ -446,12 +448,15 @@ void tst_QSGPathView::dataModel() QVERIFY(testItem == 0); pathview->setCurrentIndex(1); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); + QTest::qWait(100); model.insertItem(2, "pink", "2"); QTest::qWait(100); QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); QVERIFY(pathview->currentIndex() == 1); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); text = findItem(pathview, "myText", 2); QVERIFY(text); @@ -462,6 +467,7 @@ void tst_QSGPathView::dataModel() text = findItem(pathview, "myText", 3); QVERIFY(text); QCOMPARE(text->text(), model.name(3)); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); model.moveItem(3, 5); QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); @@ -469,6 +475,7 @@ void tst_QSGPathView::dataModel() foreach (QSGItem *item, items) { QVERIFY(item->property("onPath").toBool()); } + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); // QTBUG-14199 pathview->setOffset(7); @@ -578,30 +585,81 @@ void tst_QSGPathView::setCurrentIndex() QTRY_COMPARE(firstItem->pos() + offset, start); QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2); QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); pathview->decrementCurrentIndex(); QTRY_COMPARE(pathview->currentIndex(), 1); firstItem = findItem(pathview, "wrapper", 1); QVERIFY(firstItem); QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); pathview->decrementCurrentIndex(); QTRY_COMPARE(pathview->currentIndex(), 0); firstItem = findItem(pathview, "wrapper", 0); QVERIFY(firstItem); QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); pathview->decrementCurrentIndex(); QTRY_COMPARE(pathview->currentIndex(), 3); firstItem = findItem(pathview, "wrapper", 3); QVERIFY(firstItem); QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); pathview->incrementCurrentIndex(); QTRY_COMPARE(pathview->currentIndex(), 0); firstItem = findItem(pathview, "wrapper", 0); QVERIFY(firstItem); QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + // Check the current item is still created when outside the bounds of pathItemCount. + pathview->setPathItemCount(2); + pathview->setHighlightRangeMode(QSGPathView::NoHighlightRange); + QVERIFY(findItem(pathview, "wrapper", 0)); + QVERIFY(findItem(pathview, "wrapper", 1)); + QVERIFY(!findItem(pathview, "wrapper", 2)); + QVERIFY(!findItem(pathview, "wrapper", 3)); + + pathview->setCurrentIndex(2); + firstItem = findItem(pathview, "wrapper", 2); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(false)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 1); + firstItem = findItem(pathview, "wrapper", 1); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 3); + firstItem = findItem(pathview, "wrapper", 3); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(false)); + + pathview->incrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); delete canvas; }