From 273e5b0bdc1239df77e2e5694fdd5ad068595be3 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 24 May 2016 12:21:39 +0300 Subject: PathView: fix item creation First call of QQuickPathView::refill() did not use currentIndex for item prepending and there was situation when items were not created, e.g.: PathView with current item in center and currentIndex was set so that item with index 0 was after current item and before path end. The result of this situation: items from path begin to current item were not created. The reason was that idx always equaled (modelCount-1) for item prepending. Now first filling uses currentIndex to calculate valid idx. Task-number: QTBUG-53464 Change-Id: I7e343b0712c9c5c5cd56b1d8e020cf8c0f6e6301 Reviewed-by: Shawn Rutledge --- src/quick/items/qquickpathview.cpp | 16 ++++- .../auto/quick/qquickpathview/data/qtbug53464.qml | 77 ++++++++++++++++++++++ .../quick/qquickpathview/tst_qquickpathview.cpp | 24 +++++++ 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 tests/auto/quick/qquickpathview/data/qtbug53464.qml diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 7e1fa95692..1dbdd10303 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1854,6 +1854,14 @@ void QQuickPathView::updatePolish() refill(); } +static inline int currentIndexRemainder(int currentIndex, int modelCount) Q_DECL_NOTHROW +{ + if (currentIndex < 0) + return modelCount + currentIndex % modelCount; + else + return currentIndex % modelCount; +} + void QQuickPathView::componentComplete() { Q_D(QQuickPathView); @@ -1865,7 +1873,7 @@ void QQuickPathView::componentComplete() if (d->model) { d->modelCount = d->model->count(); if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex - d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount); + d->offset = qmlMod(d->modelCount - currentIndexRemainder(d->currentIndex, d->modelCount), d->modelCount); } d->createHighlight(); @@ -1939,7 +1947,8 @@ void QQuickPathView::refill() qreal endPos; int startIdx = 0; qreal startPos = 0.0; - if (d->items.count()) { + const bool wasEmpty = d->items.isEmpty(); + if (!wasEmpty) { //Find the beginning and end, items may not be in sorted order endPos = -1.0; startPos = 2.0; @@ -1998,7 +2007,8 @@ void QQuickPathView::refill() } //Prepend - idx = startIdx - 1; + idx = (wasEmpty ? d->calcCurrentIndex() : startIdx) - 1; + if (idx < 0) idx = d->modelCount - 1; nextPos = d->positionOfIndex(idx); diff --git a/tests/auto/quick/qquickpathview/data/qtbug53464.qml b/tests/auto/quick/qquickpathview/data/qtbug53464.qml new file mode 100644 index 0000000000..d30d404e68 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug53464.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Netris +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 600 + height: 400 + PathView { + objectName: "pathView" + model: 10 + anchors.fill: parent + pathItemCount: 5 + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + currentIndex: 8 + + path: Path { + startX: 0 + startY: 50 + PathLine { + x: 600 + y: 50 + } + } + + delegate: Component { + Text { + width: 50 + height: 50 + text: index + objectName: "delegate" + index + font.pixelSize: 24 + color: PathView.isCurrentItem ? "green" : "black" + } + } + } +} + diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index fc5dd3bbca..2046391d02 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -141,6 +141,7 @@ private slots: void flickableDelegate(); void jsArrayChange(); void qtbug42716(); + void qtbug53464(); void addCustomAttribute(); }; @@ -2381,6 +2382,29 @@ void tst_QQuickPathView::qtbug42716() QVERIFY(!itemMiss); } +void tst_QQuickPathView::qtbug53464() +{ + QScopedPointer window(createView()); + + window->setSource(testFileUrl("qtbug53464.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickPathView *pathView = findItem(window->rootObject(), "pathView"); + QVERIFY(pathView != Q_NULLPTR); + const int currentIndex = pathView->currentIndex(); + QCOMPARE(currentIndex, 8); + + const int pathItemCount = pathView->pathItemCount(); + int totalCount = 0; + foreach (QQuickItem *item, pathView->childItems()) { + if (item->objectName().startsWith(QLatin1String("delegate"))) + ++totalCount; + } + QCOMPARE(pathItemCount, totalCount); +} + void tst_QQuickPathView::addCustomAttribute() { const QScopedPointer window(createView()); -- cgit v1.2.3