aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquicktableview/tst_qquicktableview.cpp')
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp663
1 files changed, 608 insertions, 55 deletions
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index ecea4adfd5..56dee4b585 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
#include <QtQuickTest/quicktest.h>
@@ -87,6 +87,7 @@ private slots:
void checkZeroSizedDelegate();
void checkImplicitSizeDelegate();
void checkZeroSizedTableView();
+ void checkZeroSizedViewPort();
void checkColumnWidthWithoutProvider();
void checkColumnWidthAndRowHeightFunctions();
void checkDelegateWithAnchors();
@@ -103,7 +104,7 @@ private slots:
void isColumnLoadedAndIsRowLoaded();
void checkForceLayoutFunction();
void checkForceLayoutEndUpDoingALayout();
- void checkForceLayoutDuringModelChange();
+ void checkForceLayoutInbetweenAddingRowsToModel();
void checkForceLayoutWhenAllItemsAreHidden();
void checkLayoutChangedSignal();
void checkContentWidthAndHeight();
@@ -167,6 +168,7 @@ private slots:
void checkSyncView_pageFlicking();
void checkSyncView_emptyModel();
void checkSyncView_topLeftChanged();
+ void checkSyncView_unloadHeader();
void delegateWithRequiredProperties();
void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable();
void replaceModel();
@@ -188,6 +190,10 @@ private slots:
void positionViewAtCellForLargeCells_data();
void positionViewAtCellForLargeCells();
void positionViewAtCellForLargeCellsUsingSubrect();
+ void positionViewAtLastRow_data();
+ void positionViewAtLastRow();
+ void positionViewAtLastColumn_data();
+ void positionViewAtLastColumn();
void itemAtCell_data();
void itemAtCell();
void leftRightTopBottomProperties_data();
@@ -208,6 +214,7 @@ private slots:
void testSelectableStartPosEndPosOutsideView();
void testSelectableScrollTowardsPos();
void setCurrentIndexFromSelectionModel();
+ void clearSelectionOnTap_data();
void clearSelectionOnTap();
void moveCurrentIndexUsingArrowKeys();
void moveCurrentIndexUsingHomeAndEndKeys();
@@ -244,6 +251,7 @@ private slots:
void deletedDelegate();
void columnResizing_data();
void columnResizing();
+ void tableViewInteractive();
void rowResizing_data();
void rowResizing();
void rowAndColumnResizing_data();
@@ -267,6 +275,17 @@ private slots:
void editWarning_nonEditableModelItem();
void attachedPropertiesOnEditDelegate();
void requiredPropertiesOnEditDelegate();
+ void resettingRolesRespected();
+ void checkScroll_data();
+ void checkScroll();
+ void checkRebuildJsModel();
+
+ // Row and column reordering
+ void checkVisualRowColumnAfterReorder();
+ void checkColumnRowSizeAfterReorder();
+ void checkCellModelIdxAfterReorder();
+ void checkEditAfterReorder();
+ void checkSelectionAfterReorder();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -300,6 +319,18 @@ QPoint tst_QQuickTableView::getContextRowAndColumn(const QQuickItem *item) const
return QPoint(column, row);
}
+static void sendWheelEvent(QQuickWindow *window, QPoint pos, QPoint angleDelta,
+ QPoint pixelDelta,
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier,
+ Qt::ScrollPhase phase = Qt::NoScrollPhase,
+ bool inverted = false) {
+ QWheelEvent wheelEvent(pos, window->mapToGlobal(pos), pixelDelta,
+ angleDelta, Qt::NoButton, modifiers, phase,
+ inverted);
+ QGuiApplication::sendEvent(window, &wheelEvent);
+ qApp->processEvents();
+}
+
void tst_QQuickTableView::setAndGetModel_data()
{
QTest::addColumn<QVariant>("model");
@@ -443,7 +474,7 @@ void tst_QQuickTableView::checkZeroSizedTableView()
WAIT_UNTIL_POLISHED;
QCOMPARE(tableViewPrivate->loadedItems.size(), 2);
- const auto item = tableView->itemAtCell(0, 0);
+ const auto item = tableView->itemAtIndex(tableView->index(0, 0));
QVERIFY(item);
QCOMPARE(item->width(), 200);
@@ -457,6 +488,17 @@ void tst_QQuickTableView::checkZeroSizedTableView()
QCOMPARE(tableViewPrivate->loadedItems.size(), 1);
}
+void tst_QQuickTableView::checkZeroSizedViewPort()
+{
+ LOAD_TABLEVIEW("zerosizedviewport.qml");
+
+ auto model = TestModelAsVariant(20, 20);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ QVERIFY(!tableViewPrivate->loadedItems.isEmpty());
+}
void tst_QQuickTableView::checkColumnWidthWithoutProvider()
{
@@ -794,10 +836,11 @@ void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout()
QCOMPARE(tableView->contentHeight(), (9 * (newDelegateSize + rowSpacing)) - rowSpacing);
}
-void tst_QQuickTableView::checkForceLayoutDuringModelChange()
+void tst_QQuickTableView::checkForceLayoutInbetweenAddingRowsToModel()
{
- // Check that TableView doesn't assert if we call
- // forceLayout() in the middle of a model change.
+ // Check that TableView doesn't assert if we call forceLayout() while waiting
+ // for a callback from the model that the row count has changed. Also make sure
+ // that we don't move the contentItem while doing so.
LOAD_TABLEVIEW("plaintableview.qml");
const int initialRowCount = 10;
@@ -812,9 +855,13 @@ void tst_QQuickTableView::checkForceLayoutDuringModelChange()
WAIT_UNTIL_POLISHED;
+ const int contentY = 10;
+ tableView->setContentY(contentY);
QCOMPARE(tableView->rows(), initialRowCount);
+ QCOMPARE(tableView->contentY(), contentY);
model.addRow(0);
QCOMPARE(tableView->rows(), initialRowCount + 1);
+ QCOMPARE(tableView->contentY(), contentY);
}
void tst_QQuickTableView::checkForceLayoutWhenAllItemsAreHidden()
@@ -2451,7 +2498,7 @@ void tst_QQuickTableView::checkChangingModelFromDelegate()
// And since the QML code tried to add another row as well, we
// expect rebuildScheduled to be true, and a polish event to be pending.
QVERIFY(tableViewPrivate->scheduledRebuildOptions);
- QCOMPARE(tableViewPrivate->polishScheduled, true);
+ QVERIFY(tableViewPrivate->polishScheduled);
WAIT_UNTIL_POLISHED;
// After handling the polish event, we expect also the third row to now be added
@@ -3253,6 +3300,21 @@ void tst_QQuickTableView::checkSyncView_emptyModel()
QCOMPARE(tableViewVPrivate->loadedTableOuterRect.left(), 0);
}
+void tst_QQuickTableView::checkSyncView_unloadHeader()
+{
+ // Check that we don't get a crash in TableView if one
+ // of the sync children is suddenly deleted (from e.g a Loader).
+ LOAD_TABLEVIEW("unloadheader.qml");
+
+ const auto loader = view->rootObject()->property("loader").value<QQuickLoader *>();
+ QVERIFY(loader);
+ QVERIFY(loader->item());
+ loader->setActive(false);
+ QVERIFY(!loader->item());
+ gc(*qmlEngine(tableView));
+ tableView->forceLayout();
+}
+
void tst_QQuickTableView::checkSyncView_topLeftChanged()
{
LOAD_TABLEVIEW("syncviewsimple.qml");
@@ -3770,14 +3832,15 @@ void tst_QQuickTableView::positionViewAtCellWithAnimation()
QPoint cell(tableView->rightColumn(), tableView->bottomRow());
const QRectF cellGeometry = tableViewPrivate->loadedTableItem(cell)->geometry();
- const int modelIndex = tableViewPrivate->modelIndexAtCell(cell);
+ const int serializedIndex = tableViewPrivate->modelIndexAtCell(cell);
+ const QModelIndex index = tableView->index(cell.y(), cell.x());
- QVERIFY(tableViewPrivate->loadedItems.contains(modelIndex));
+ QVERIFY(tableViewPrivate->loadedItems.contains(serializedIndex));
QVERIFY(!tableViewPrivate->positionXAnimation.isRunning());
QVERIFY(!tableViewPrivate->positionYAnimation.isRunning());
// Animate the cell to the top left location in the view
- tableView->positionViewAtCell(cell, QQuickTableView::AlignTop | QQuickTableView::AlignLeft);
+ tableView->positionViewAtIndex(index, QQuickTableView::AlignTop | QQuickTableView::AlignLeft);
// Wait for animation to finish
QVERIFY(tableViewPrivate->positionXAnimation.isRunning());
@@ -3786,13 +3849,13 @@ void tst_QQuickTableView::positionViewAtCellWithAnimation()
QTRY_COMPARE(tableViewPrivate->positionYAnimation.isRunning(), false);
// Check that the cell is now placed in the top left corner
- QVERIFY(tableViewPrivate->loadedItems.contains(modelIndex));
+ QVERIFY(tableViewPrivate->loadedItems.contains(serializedIndex));
QPointF expectedPos = tableView->mapToItem(tableView->contentItem(), QPointF(0, 0));
QCOMPARE(cellGeometry.x(), expectedPos.x());
QCOMPARE(cellGeometry.y(), expectedPos.y());
// Animate the cell to the top right location in the view
- tableView->positionViewAtCell(cell, QQuickTableView::AlignTop | QQuickTableView::AlignRight);
+ tableView->positionViewAtIndex(index, QQuickTableView::AlignTop | QQuickTableView::AlignRight);
// Wait for animation to finish
QVERIFY(tableViewPrivate->positionXAnimation.isRunning());
@@ -3800,13 +3863,13 @@ void tst_QQuickTableView::positionViewAtCellWithAnimation()
QTRY_COMPARE(tableViewPrivate->positionXAnimation.isRunning(), false);
// Check that the cell is now placed in the top right corner
- QVERIFY(tableViewPrivate->loadedItems.contains(modelIndex));
+ QVERIFY(tableViewPrivate->loadedItems.contains(serializedIndex));
expectedPos = tableView->mapToItem(tableView->contentItem(), QPointF(tableView->width(), 0));
QCOMPARE(cellGeometry.right(), expectedPos.x());
QCOMPARE(cellGeometry.y(), expectedPos.y());
// Animate the cell to the bottom left location in the view
- tableView->positionViewAtCell(cell, QQuickTableView::AlignBottom | QQuickTableView::AlignLeft);
+ tableView->positionViewAtIndex(index, QQuickTableView::AlignBottom | QQuickTableView::AlignLeft);
// Wait for animation to finish
QVERIFY(tableViewPrivate->positionXAnimation.isRunning());
@@ -3815,7 +3878,7 @@ void tst_QQuickTableView::positionViewAtCellWithAnimation()
QTRY_COMPARE(tableViewPrivate->positionYAnimation.isRunning(), false);
// Check that the cell is now placed in the bottom left corner
- QVERIFY(tableViewPrivate->loadedItems.contains(modelIndex));
+ QVERIFY(tableViewPrivate->loadedItems.contains(serializedIndex));
expectedPos = tableView->mapToItem(tableView->contentItem(), QPointF(0, tableView->height()));
QCOMPARE(cellGeometry.x(), expectedPos.x());
QCOMPARE(cellGeometry.bottom(), expectedPos.y());
@@ -3829,7 +3892,7 @@ void tst_QQuickTableView::positionViewAtCellWithAnimation()
QTRY_COMPARE(tableViewPrivate->positionXAnimation.isRunning(), false);
// Check that the cell is now placed in the bottom right corner
- QVERIFY(tableViewPrivate->loadedItems.contains(modelIndex));
+ QVERIFY(tableViewPrivate->loadedItems.contains(serializedIndex));
expectedPos = tableView->mapToItem(tableView->contentItem(), QPointF(tableView->width(), tableView->height()));
QCOMPARE(cellGeometry.right(), expectedPos.x());
QCOMPARE(cellGeometry.bottom(), expectedPos.y());
@@ -4070,6 +4133,122 @@ void tst_QQuickTableView::positionViewAtCellForLargeCellsUsingSubrect()
QCOMPARE(tableView->contentY(), -(tableView->height() - subRect.bottom()));
}
+void tst_QQuickTableView::positionViewAtLastRow_data()
+{
+ QTest::addColumn<QString>("signalToTest");
+ QTest::addColumn<bool>("animate");
+
+ QTest::newRow("positionOnRowsChanged, animate=false") << "positionOnRowsChanged" << false;
+ QTest::newRow("positionOnRowsChanged, animate=true") << "positionOnRowsChanged" << true;
+ QTest::newRow("positionOnContentHeightChanged, animate=false") << "positionOnContentHeightChanged" << false;
+ QTest::newRow("positionOnContentHeightChanged, animate=true") << "positionOnContentHeightChanged" << true;
+}
+
+void tst_QQuickTableView::positionViewAtLastRow()
+{
+ // Check that we can make TableView always scroll to the
+ // last row in the model by positioning the view upon
+ // a rowsChanged callback
+ QFETCH(QString, signalToTest);
+ QFETCH(bool, animate);
+
+ LOAD_TABLEVIEW("positionlast.qml");
+
+ // Use a very large model to indirectly test that we "fast-flick" to
+ // the end at start-up (instead of loading and unloading rows, which
+ // would take forever).
+ TestModel model(2000000, 2000000);
+ tableView->setModel(QVariant::fromValue(&model));
+ tableView->setAnimate(animate);
+
+ view->rootObject()->setProperty(signalToTest.toUtf8().constData(), true);
+
+ WAIT_UNTIL_POLISHED;
+
+ const qreal delegateSize = 100.;
+ const qreal viewportRowCount = tableView->height() / delegateSize;
+
+ // Check that the viewport is positioned at the last row at start-up
+ QCOMPARE(tableView->rows(), model.rowCount());
+ QCOMPARE(tableView->bottomRow(), model.rowCount() - 1);
+ QCOMPARE(tableView->contentY(), (model.rowCount() - viewportRowCount) * delegateSize);
+
+ // Check that the viewport is positioned at the last
+ // row after more rows are added.
+ for (int row = 0; row < 2; ++row) {
+ model.addRow(model.rowCount() - 1);
+
+ WAIT_UNTIL_POLISHED;
+
+ if (tableView->animate()) {
+ QVERIFY(tableViewPrivate->positionYAnimation.isRunning());
+ QTRY_VERIFY(!tableViewPrivate->positionYAnimation.isRunning());
+ }
+
+ QCOMPARE(tableView->rows(), model.rowCount());
+ QCOMPARE(tableView->bottomRow(), model.rowCount() - 1);
+ QCOMPARE(tableView->contentY(), (model.rowCount() - viewportRowCount) * delegateSize);
+ }
+}
+
+void tst_QQuickTableView::positionViewAtLastColumn_data()
+{
+ QTest::addColumn<QString>("signalToTest");
+ QTest::addColumn<bool>("animate");
+
+ QTest::newRow("positionOnColumnsChanged, animate=false") << "positionOnColumnsChanged" << false;
+ QTest::newRow("positionOnColumnsChanged, animate=true") << "positionOnColumnsChanged" << true;
+ QTest::newRow("positionOnContentWidthChanged, animate=false") << "positionOnContentWidthChanged" << false;
+ QTest::newRow("positionOnContentWidthChanged, animate=true") << "positionOnContentWidthChanged" << true;
+}
+
+void tst_QQuickTableView::positionViewAtLastColumn()
+{
+ // Check that we can make TableView always scroll to the
+ // last column in the model by positioning the view upon
+ // a columnsChanged callback
+ QFETCH(QString, signalToTest);
+ QFETCH(bool, animate);
+
+ LOAD_TABLEVIEW("positionlast.qml");
+
+ // Use a very large model to indirectly test that we "fast-flick" to
+ // the end at start-up (instead of loading and unloading columns, which
+ // would take forever).
+ TestModel model(2000000, 2000000);
+ tableView->setModel(QVariant::fromValue(&model));
+ tableView->setAnimate(animate);
+
+ view->rootObject()->setProperty(signalToTest.toUtf8().constData(), true);
+
+ WAIT_UNTIL_POLISHED;
+
+ const qreal delegateSize = 100.;
+ const qreal viewportColumnCount = tableView->width() / delegateSize;
+
+ // Check that the viewport is positioned at the last column at start-up
+ QCOMPARE(tableView->columns(), model.columnCount());
+ QCOMPARE(tableView->rightColumn(), model.columnCount() - 1);
+ QCOMPARE(tableView->contentX(), (model.columnCount() - viewportColumnCount) * delegateSize);
+
+ // Check that the viewport is positioned at the last
+ // column after more columns are added.
+ for (int column = 0; column < 2; ++column) {
+ model.addColumn(model.columnCount() - 1);
+
+ WAIT_UNTIL_POLISHED;
+
+ if (tableView->animate()) {
+ QVERIFY(tableViewPrivate->positionXAnimation.isRunning());
+ QTRY_VERIFY(!tableViewPrivate->positionXAnimation.isRunning());
+ }
+
+ QCOMPARE(tableView->columns(), model.columnCount());
+ QCOMPARE(tableView->rightColumn(), model.columnCount() - 1);
+ QCOMPARE(tableView->contentX(), (model.columnCount() - viewportColumnCount) * delegateSize);
+ }
+}
+
void tst_QQuickTableView::itemAtCell_data()
{
QTest::addColumn<QPoint>("cell");
@@ -4378,7 +4557,7 @@ void tst_QQuickTableView::warnOnWrongModelInSelectionModel()
selectionModel.setModel(&model2);
// And change currentIndex. This will produce a warning.
- QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*model differs.*"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*TableView.selectionModel.model.*"));
selectionModel.setCurrentIndex(model2.index(0, 0), QItemSelectionModel::NoUpdate);
}
@@ -4410,9 +4589,10 @@ void tst_QQuickTableView::selectionBehaviorCells_data()
void tst_QQuickTableView::selectionBehaviorCells()
{
- // Check that the TableView implement QQuickSelectableInterface setSelectionStartPos, setSelectionEndPos
- // and clearSelection correctly. Do this by calling setSelectionStartPos/setSelectionEndPos on top of
- // different cells, and see that we end up with the expected selections.
+ // Check that the TableView implement QQuickSelectableInterface startSelection,
+ // setSelectionStartPos, setSelectionEndPos and clearSelection correctly. Do this by
+ // calling setSelectionStartPos/setSelectionEndPos on top of different cells, and see
+ // that we end up with the expected selections.
QFETCH(QPoint, endCellDist);
LOAD_TABLEVIEW("tableviewwithselected1.qml");
@@ -4442,6 +4622,7 @@ void tst_QQuickTableView::selectionBehaviorCells()
const QPointF endPos(endItem->x(), endItem->y());
const QPointF endPosWrapped(endItemWrapped->x(), endItemWrapped->y());
+ QVERIFY(tableViewPrivate->startSelection(startPos, Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(startPos);
tableViewPrivate->setSelectionEndPos(endPos);
@@ -4482,8 +4663,9 @@ void tst_QQuickTableView::selectionBehaviorCells()
void tst_QQuickTableView::selectionBehaviorRows()
{
- // Check that the TableView implement QQuickSelectableInterface setSelectionStartPos, setSelectionEndPos
- // and clearSelection correctly for QQuickTableView::SelectRows.
+ // Check that the TableView implement QQuickSelectableInterface startSelection,
+ // setSelectionStartPos, setSelectionEndPos and clearSelection correctly for
+ // QQuickTableView::SelectRows.
LOAD_TABLEVIEW("tableviewwithselected1.qml");
TestModel model(10, 10);
@@ -4498,6 +4680,7 @@ void tst_QQuickTableView::selectionBehaviorRows()
QCOMPARE(selectionModel.hasSelection(), false);
// Drag from row 0 to row 3
+ QVERIFY(tableViewPrivate->startSelection(QPointF(0, 0), Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(QPointF(0, 0));
tableViewPrivate->setSelectionEndPos(QPointF(60, 60));
@@ -4518,6 +4701,7 @@ void tst_QQuickTableView::selectionBehaviorRows()
QCOMPARE(selectionModel.hasSelection(), false);
// Drag from row 3 to row 0 (and overshoot mouse)
+ QVERIFY(tableViewPrivate->startSelection(QPointF(60, 60), Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(QPointF(60, 60));
tableViewPrivate->setSelectionEndPos(QPointF(-10, -10));
@@ -4536,8 +4720,9 @@ void tst_QQuickTableView::selectionBehaviorRows()
void tst_QQuickTableView::selectionBehaviorColumns()
{
- // Check that the TableView implement QQuickSelectableInterface setSelectionStartPos, setSelectionEndPos
- // and clearSelection correctly for QQuickTableView::SelectColumns.
+ // Check that the TableView implement QQuickSelectableInterface startSelection,
+ // setSelectionStartPos, setSelectionEndPos and clearSelection correctly for
+ // QQuickTableView::SelectColumns.
LOAD_TABLEVIEW("tableviewwithselected1.qml");
TestModel model(10, 10);
@@ -4552,6 +4737,7 @@ void tst_QQuickTableView::selectionBehaviorColumns()
QCOMPARE(selectionModel.hasSelection(), false);
// Drag from column 0 to column 3
+ QVERIFY(tableViewPrivate->startSelection(QPointF(60, 60), Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(QPointF(0, 0));
tableViewPrivate->setSelectionEndPos(QPointF(60, 60));
@@ -4572,6 +4758,7 @@ void tst_QQuickTableView::selectionBehaviorColumns()
QCOMPARE(selectionModel.hasSelection(), false);
// Drag from column 3 to column 0 (and overshoot mouse)
+ QVERIFY(tableViewPrivate->startSelection(QPointF(60, 60), Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(QPointF(60, 60));
tableViewPrivate->setSelectionEndPos(QPointF(-10, -10));
@@ -4590,8 +4777,8 @@ void tst_QQuickTableView::selectionBehaviorColumns()
void tst_QQuickTableView::selectionBehaviorDisabled()
{
- // Check that the TableView implement QQuickSelectableInterface setSelectionStartPos, setSelectionEndPos
- // and clearSelection correctly for QQuickTableView::SelectionDisabled.
+ // Check that the TableView implement QQuickSelectableInterface startSelection
+ // correctly for QQuickTableView::SelectionDisabled.
LOAD_TABLEVIEW("tableviewwithselected1.qml");
TestModel model(10, 10);
@@ -4605,18 +4792,18 @@ void tst_QQuickTableView::selectionBehaviorDisabled()
QCOMPARE(selectionModel.hasSelection(), false);
- // Drag from column 0 to column 3
- tableViewPrivate->setSelectionStartPos(QPointF(0, 0));
- tableViewPrivate->setSelectionEndPos(QPointF(60, 60));
+ // Try to start a selection
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*TableView.SelectionDisabled"));
+ QVERIFY(!tableViewPrivate->startSelection(QPointF(0, 0), Qt::NoModifier));
QCOMPARE(selectionModel.hasSelection(), false);
}
void tst_QQuickTableView::testSelectableStartPosEndPosOutsideView()
{
- // Call setSelectionStartPos and setSelectionEndPos with positions outside the view.
- // This should first of all not crash, but instead just clamp the selection to the
- // cells that are visible inside the view.
+ // Call startSelection, setSelectionStartPos and setSelectionEndPos with positions
+ // outside the view. This should first of all not crash, but instead just clamp the
+ // selection to the cells that are visible inside the view.
LOAD_TABLEVIEW("tableviewwithselected1.qml");
TestModel model(10, 10);
@@ -4637,6 +4824,7 @@ void tst_QQuickTableView::testSelectableStartPosEndPosOutsideView()
const QPointF outsideTop(centerPos.x(), -100);
const QPointF outsideBottom(centerPos.x(), tableView->height() + 100);
+ QVERIFY(tableViewPrivate->startSelection(centerPos, Qt::NoModifier));
tableViewPrivate->setSelectionStartPos(centerPos);
tableViewPrivate->setSelectionEndPos(outsideLeft);
@@ -4687,23 +4875,23 @@ void tst_QQuickTableView::testSelectableScrollTowardsPos()
const QPointF bottomLeft(-100, tableView->height() + 100);
const QPointF bottomRight(tableView->width() + 100, tableView->height() + 100);
- tableViewPrivate->scrollTowardsSelectionPoint(topRight, step);
+ tableViewPrivate->scrollTowardsPoint(topRight, step);
QCOMPARE(tableView->contentX(), step.width());
QCOMPARE(tableView->contentY(), 0);
- tableViewPrivate->scrollTowardsSelectionPoint(bottomRight, step);
+ tableViewPrivate->scrollTowardsPoint(bottomRight, step);
QCOMPARE(tableView->contentX(), step.width() * 2);
QCOMPARE(tableView->contentY(), step.height());
- tableViewPrivate->scrollTowardsSelectionPoint(bottomLeft, step);
+ tableViewPrivate->scrollTowardsPoint(bottomLeft, step);
QCOMPARE(tableView->contentX(), step.width());
QCOMPARE(tableView->contentY(), step.height() * 2);
- tableViewPrivate->scrollTowardsSelectionPoint(topLeft, step);
+ tableViewPrivate->scrollTowardsPoint(topLeft, step);
QCOMPARE(tableView->contentX(), 0);
QCOMPARE(tableView->contentY(), step.height());
- tableViewPrivate->scrollTowardsSelectionPoint(topLeft, step);
+ tableViewPrivate->scrollTowardsPoint(topLeft, step);
QCOMPARE(tableView->contentX(), 0);
QCOMPARE(tableView->contentY(), 0);
}
@@ -4743,12 +4931,25 @@ void tst_QQuickTableView::setCurrentIndexFromSelectionModel()
QVERIFY(tableView->itemAtCell(cellAtEnd)->property(kCurrent).toBool());
}
+void tst_QQuickTableView::clearSelectionOnTap_data()
+{
+ QTest::addColumn<bool>("selectionEnabled");
+ QTest::newRow("selections enabled") << true;
+ QTest::newRow("selections disabled") << false;
+}
+
void tst_QQuickTableView::clearSelectionOnTap()
{
+ // Check that we clear the current selection when tapping
+ // inside TableView. But only if TableView has selections
+ // enabled. Otherwise, TableView should not touch the selection model.
+ QFETCH(bool, selectionEnabled);
LOAD_TABLEVIEW("tableviewwithselected2.qml");
TestModel model(40, 40);
tableView->setModel(QVariant::fromValue(&model));
+ if (!selectionEnabled)
+ tableView->setSelectionBehavior(QQuickTableView::SelectionDisabled);
WAIT_UNTIL_POLISHED;
@@ -4757,13 +4958,14 @@ void tst_QQuickTableView::clearSelectionOnTap()
tableView->selectionModel()->select(index, QItemSelectionModel::Select);
QCOMPARE(tableView->selectionModel()->selectedIndexes().size(), 1);
- // Click on a cell. This should remove the selection
- const auto item = tableView->itemAtCell(0, 0);
+ // Click on a cell
+ const auto item = tableView->itemAtIndex(tableView->index(0, 0));
QVERIFY(item);
QPoint localPos = QPoint(item->width() / 2, item->height() / 2);
QPoint pos = item->window()->contentItem()->mapFromItem(item, localPos).toPoint();
QTest::mouseClick(item->window(), Qt::LeftButton, Qt::NoModifier, pos);
- QCOMPARE(tableView->selectionModel()->selectedIndexes().size(), 0);
+
+ QCOMPARE(tableView->selectionModel()->hasSelection(), !selectionEnabled);
}
void tst_QQuickTableView::moveCurrentIndexUsingArrowKeys()
@@ -5358,7 +5560,7 @@ void tst_QQuickTableView::disablePointerNavigation()
// Enable navigation, and try again
tableView->setPointerNavigationEnabled(true);
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, pos);
- QCOMPARE(selectionModel.currentIndex(), tableView->modelIndex(0, 0));
+ QCOMPARE(selectionModel.currentIndex(), tableView->index(0, 0));
QVERIFY(item0_0->property("current").toBool());
QCOMPARE(tableView->currentColumn(), cell0_0.x());
QCOMPARE(tableView->currentRow(), cell0_0.y());
@@ -5754,7 +5956,7 @@ void tst_QQuickTableView::boundDelegateComponent()
QVERIFY(inner != nullptr);
QQuickTableView *tableView = qobject_cast<QQuickTableView *>(inner);
QVERIFY(tableView != nullptr);
- QObject *item = tableView->itemAtCell(0, 0);
+ QObject *item = tableView->itemAtCell({0, 0});
QVERIFY(item);
QCOMPARE(item->objectName(), QLatin1String("fooouterundefined"));
@@ -5762,7 +5964,7 @@ void tst_QQuickTableView::boundDelegateComponent()
QVERIFY(inner2 != nullptr);
QQuickTableView *tableView2 = qobject_cast<QQuickTableView *>(inner2);
QVERIFY(tableView2 != nullptr);
- QObject *item2 = tableView2->itemAtCell(0, 0);
+ QObject *item2 = tableView2->itemAtCell({0, 0});
QVERIFY(item2);
QCOMPARE(item2->objectName(), QLatin1String("fooouter0"));
@@ -5784,7 +5986,7 @@ void tst_QQuickTableView::boundDelegateComponent()
QVERIFY(innerTableView != nullptr);
QCOMPARE(innerTableView->rows(), 3);
for (int i = 0; i < 3; ++i)
- QVERIFY(innerTableView->itemAtCell(0, i)->objectName().isEmpty());
+ QVERIFY(innerTableView->itemAtIndex(innerTableView->index(i, 0))->objectName().isEmpty());
}
void tst_QQuickTableView::setColumnWidth_data()
@@ -6127,6 +6329,47 @@ void tst_QQuickTableView::deletedDelegate()
QTRY_COMPARE(tv->delegate(), nullptr);
}
+void tst_QQuickTableView::tableViewInteractive()
+{
+ LOAD_TABLEVIEW("tableviewinteractive.qml");
+
+ auto *root = view->rootObject();
+ QVERIFY(root);
+ auto *window = root->window();
+ QVERIFY(window);
+
+ int eventCount = root->property("eventCount").toInt();
+ QCOMPARE(eventCount, 0);
+
+ // Event though we make 'interactive' as false, the TableView has
+ // pointerNacigationEnabled set as true by default, which allows it to consume
+ // mouse events and thus, eventCount still be zero
+ tableView->setInteractive(false);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ eventCount = root->property("eventCount").toInt();
+ QCOMPARE(eventCount, 0);
+
+ // Making both 'interactive' and 'pointerNavigationEnabled' as false, doesn't
+ // allow TableView (and its parent Flickable) to consume mouse event and it
+ // passes to the below visual item
+ tableView->setInteractive(false);
+ tableView->setPointerNavigationEnabled(false);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ eventCount = root->property("eventCount").toInt();
+ QCOMPARE(eventCount, 1);
+
+ // Making 'interactive' as true and 'pointerNavigationEnabled' as false,
+ // allows parent of TableView (i.e. Flickable) to consume mouse events
+ tableView->setInteractive(true);
+ tableView->setPointerNavigationEnabled(false);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(100, 100));
+ eventCount = root->property("eventCount").toInt();
+ QCOMPARE(eventCount, 1);
+}
+
void tst_QQuickTableView::columnResizing_data()
{
QTest::addColumn<int>("column");
@@ -6161,7 +6404,7 @@ void tst_QQuickTableView::columnResizing()
QSignalSpy currentIndexSpy(tableView->selectionModel(), &QItemSelectionModel::currentChanged);
QSignalSpy selectionSpy(tableView->selectionModel(), &QItemSelectionModel::selectionChanged);
- const auto item = tableView->itemAtCell(column, 0);
+ const auto item = tableView->itemAtIndex(tableView->index(0, column));
QQuickWindow *window = item->window();
const qreal columnStartWidth = tableView->columnWidth(column);
@@ -6212,7 +6455,7 @@ void tst_QQuickTableView::rowResizing()
QSignalSpy currentIndexSpy(tableView->selectionModel(), &QItemSelectionModel::currentChanged);
QSignalSpy selectionSpy(tableView->selectionModel(), &QItemSelectionModel::selectionChanged);
- const auto item = tableView->itemAtCell(0, row);
+ const auto item = tableView->itemAtIndex(tableView->index(row, 0));
QQuickWindow *window = item->window();
const qreal rowStartHeight = tableView->rowHeight(row);
@@ -6265,7 +6508,7 @@ void tst_QQuickTableView::rowAndColumnResizing()
QCOMPARE(tableView->explicitColumnWidth(rowAndColumn), -1);
QCOMPARE(tableView->explicitRowHeight(rowAndColumn), -1);
- const auto item = tableView->itemAtCell(rowAndColumn, rowAndColumn);
+ const auto item = tableView->itemAtIndex(tableView->index(rowAndColumn, rowAndColumn));
QVERIFY(item);
if (addDelegateDragHandler) {
@@ -6320,7 +6563,7 @@ void tst_QQuickTableView::columnResizingDisabled()
const int row = 1;
QCOMPARE(tableView->explicitRowHeight(row), -1);
- const auto item = tableView->itemAtCell(0, row);
+ const auto item = tableView->itemAtIndex(tableView->index(row, 0));
QQuickWindow *window = item->window();
const QPoint localPos = QPoint(item->width() / 2, item->height());
@@ -6357,7 +6600,7 @@ void tst_QQuickTableView::rowResizingDisabled()
const int row = 1;
QCOMPARE(tableView->explicitRowHeight(row), -1);
- const auto item = tableView->itemAtCell(0, row);
+ const auto item = tableView->itemAtIndex(tableView->index(row, 0));
QQuickWindow *window = item->window();
const QPoint localPos = QPoint(item->width() / 2, item->height());
@@ -6395,7 +6638,7 @@ void tst_QQuickTableView::dragFromCellCenter()
const int row = 1;
QCOMPARE(tableView->explicitRowHeight(row), -1);
- const auto item = tableView->itemAtCell(0, row);
+ const auto item = tableView->itemAtIndex(tableView->index(row, 0));
QQuickWindow *window = item->window();
const QPoint localPos = QPoint(item->width() / 2, item->height() / 2);
@@ -6590,7 +6833,7 @@ void tst_QQuickTableView::editUsingEditTriggers()
if (editTriggers & QQuickTableView::SelectedTapped) {
// select cell first, then tap on it
- tableView->selectionModel()->setCurrentIndex(index1, QItemSelectionModel::NoUpdate);
+ tableView->selectionModel()->setCurrentIndex(index1, QItemSelectionModel::Select);
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, tapPos1);
QCOMPARE(tableView->selectionModel()->currentIndex(), index1);
const auto editItem1 = tableView->property(kEditItem).value<QQuickItem *>();
@@ -6611,6 +6854,11 @@ void tst_QQuickTableView::editUsingEditTriggers()
QVERIFY(!tableView->property(kEditItem).value<QQuickItem *>());
QVERIFY(!tableView->property(kEditIndex).value<QModelIndex>().isValid());
QCOMPARE(tableView->selectionModel()->currentIndex(), index2);
+
+ // tap on the current cell. This alone should not start an edit (unless it's also selected)
+ QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, tapPos1);
+ QVERIFY(!tableView->property(kEditItem).value<QQuickItem *>());
+ QVERIFY(!tableView->property(kEditIndex).value<QModelIndex>().isValid());
}
if (editTriggers & QQuickTableView::EditKeyPressed) {
@@ -7075,7 +7323,7 @@ void tst_QQuickTableView::editWarning_noEditDelegate()
WAIT_UNTIL_POLISHED;
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*cannot edit: no TableView.editDelegate set!"));
- tableView->edit(tableView->modelIndex(1, 1));
+ tableView->edit(tableView->index(1, 1));
}
void tst_QQuickTableView::editWarning_invalidIndex()
@@ -7090,7 +7338,7 @@ void tst_QQuickTableView::editWarning_invalidIndex()
WAIT_UNTIL_POLISHED;
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*cannot edit: index is not valid!"));
- tableView->edit(tableView->modelIndex(-1, -1));
+ tableView->edit(tableView->index(-1, -1));
}
void tst_QQuickTableView::editWarning_nonEditableModelItem()
@@ -7108,7 +7356,7 @@ void tst_QQuickTableView::editWarning_nonEditableModelItem()
WAIT_UNTIL_POLISHED;
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*cannot edit:.*flags.*Qt::ItemIsEditable"));
- tableView->edit(tableView->modelIndex(1, 1));
+ tableView->edit(tableView->index(1, 1));
}
void tst_QQuickTableView::attachedPropertiesOnEditDelegate()
@@ -7214,7 +7462,7 @@ void tst_QQuickTableView::requiredPropertiesOnEditDelegate()
const QPoint cell(1, 1);
const QModelIndex index1 = tableView->modelIndex(cell);
- const QModelIndex index2 = tableView->modelIndex(2, 2);
+ const QModelIndex index2 = tableView->index(2, 2);
tableView->edit(index1);
@@ -7232,6 +7480,311 @@ void tst_QQuickTableView::requiredPropertiesOnEditDelegate()
QCOMPARE(textInput->property("current").toBool(), false);
}
+void tst_QQuickTableView::resettingRolesRespected()
+{
+ LOAD_TABLEVIEW("resetModelData.qml");
+
+ TestModel model(1, 1);
+ tableView->setModel(QVariant::fromValue(&model));
+
+ WAIT_UNTIL_POLISHED;
+
+ QVERIFY(!tableView->property("success").toBool());
+ model.useCustomRoleNames(true);
+ QTRY_VERIFY(tableView->property("success").toBool());
+}
+
+void tst_QQuickTableView::checkScroll_data()
+{
+ QTest::addColumn<bool>("resizableColumns");
+ QTest::addColumn<bool>("resizableRows");
+ QTest::newRow("T, T") << true << true;
+ QTest::newRow("T, F") << true << false;
+ QTest::newRow("F, T") << false << true;
+ QTest::newRow("F, F") << false << false;
+}
+
+/*!
+ Make sure that the TableView is scrollable regardless
+ of the values of resizableColumns and resizableRows.
+*/
+void tst_QQuickTableView::checkScroll() // QTBUG-116566
+{
+ QFETCH(bool, resizableColumns);
+ QFETCH(bool, resizableRows);
+ LOAD_TABLEVIEW("plaintableview.qml"); // gives us 'tableView' variable
+
+ tableView->setResizableColumns(resizableColumns);
+ tableView->setResizableRows(resizableRows);
+
+ auto model = TestModelAsVariant(20, 10);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ // Scroll with the mouse wheel
+ sendWheelEvent(view, {10, 10}, {0, -120}, {0, -120});
+
+ // Check that scrolling succeeded
+ QTRY_COMPARE_GT(tableView->contentY(), 20);
+}
+
+void tst_QQuickTableView::checkRebuildJsModel()
+{
+ LOAD_TABLEVIEW("resetJsModelData.qml"); // gives us 'tableView' variable
+
+ // Generate javascript model
+ const int size = 5;
+ const char* modelUpdated = "modelUpdated";
+
+ QJSEngine jsEngine;
+ QJSValue jsArray;
+ jsArray = jsEngine.newArray(size);
+ for (int i = 0; i < size; ++i)
+ jsArray.setProperty(i, QRandomGenerator::global()->generate());
+
+ QVariant jsModel = QVariant::fromValue(jsArray);
+ tableView->setModel(jsModel);
+ WAIT_UNTIL_POLISHED;
+
+ // Model change would be triggered for the first time
+ QCOMPARE(tableView->property(modelUpdated).toInt(), 1);
+
+ // Set the same model once again and check if model changes
+ tableView->setModel(jsModel);
+ QCOMPARE(tableView->property(modelUpdated).toInt(), 1);
+}
+
+void tst_QQuickTableView::checkVisualRowColumnAfterReorder()
+{
+ LOAD_TABLEVIEW("reordertableview.qml"); // gives us 'tableView' variable
+ auto model = TestModelAsVariant(3, 3);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ QSignalSpy columnMovedSpy(tableView, &QQuickTableView::columnMoved);
+ QSignalSpy rowMovedSpy(tableView, &QQuickTableView::rowMoved);
+
+ // Move row and column
+ tableView->moveColumn(0, 2);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(columnMovedSpy.size(), 3);
+
+ tableView->moveRow(1, 0);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(rowMovedSpy.size(), 2);
+
+ QVariantList firstColumnVar = columnMovedSpy.takeFirst();
+ QCOMPARE(firstColumnVar.at(0), 0); // Logical index
+ QCOMPARE(firstColumnVar.at(1), 0); // Old visual index
+ QCOMPARE(firstColumnVar.at(2), 2); // New visual index
+
+ QVariantList firstRowVar = rowMovedSpy.takeFirst();
+ QCOMPARE(firstRowVar.at(0), 0); // Logical index
+ QCOMPARE(firstRowVar.at(1), 0); // Old visual index
+ QCOMPARE(firstRowVar.at(2), 1); // New visual index
+}
+
+void tst_QQuickTableView::checkColumnRowSizeAfterReorder()
+{
+ LOAD_TABLEVIEW("reordertableview.qml"); // gives us 'tableView' variable
+ auto model = TestModelAsVariant(3, 3);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ const QSignalSpy columMovedSpy(tableView, &QQuickTableView::columnMoved);
+ const QSignalSpy rowMovedSpy(tableView, &QQuickTableView::rowMoved);
+
+ for (int index = 0, minSize = 10; index < tableView->columns(); index++, minSize+=10) {
+ tableView->setColumnWidth(index, minSize);
+ tableView->setRowHeight(index, minSize);
+ }
+ WAIT_UNTIL_POLISHED;
+
+ // Move row and column
+ tableView->moveColumn(0, 2);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(columMovedSpy.size(), 3);
+
+ tableView->moveRow(0, 2);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(rowMovedSpy.size(), 3);
+
+ QCOMPARE(tableView->columnWidth(0), 20);
+ QCOMPARE(tableView->columnWidth(1), 30);
+ QCOMPARE(tableView->columnWidth(2), 10);
+
+ QCOMPARE(tableView->rowHeight(0), 20);
+ QCOMPARE(tableView->rowHeight(1), 30);
+ QCOMPARE(tableView->rowHeight(2), 10);
+}
+
+void tst_QQuickTableView::checkCellModelIdxAfterReorder()
+{
+ LOAD_TABLEVIEW("reordertableview.qml"); // gives us 'tableView' variable
+ auto model = TestModelAsVariant(3, 3);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ const QSignalSpy columnMovedSpy(tableView, &QQuickTableView::columnMoved);
+ const QSignalSpy rowMovedSpy(tableView, &QQuickTableView::rowMoved);
+
+ const QSharedPointer<TestModel> testModel = model.value<QSharedPointer<TestModel>>();
+ const QString objNameItem21(tableView->itemAtIndex(testModel->index(2, 1))->objectName());
+ const QString objNameItem00(tableView->itemAtIndex(testModel->index(0 ,0))->objectName());
+ const QString objNameItem11(tableView->itemAtIndex(testModel->index(1 ,1))->objectName());
+
+ // Move row and column
+ tableView->moveColumn(0, 2);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(columnMovedSpy.size(), 3);
+
+ tableView->moveRow(1, 0);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(rowMovedSpy.size(), 2);
+
+ // Check model index - index()
+ QModelIndex modelIndex = tableView->index(0, 0);
+ QCOMPARE(modelIndex.column(), 1);
+ QCOMPARE(modelIndex.row(), 1);
+
+ modelIndex = tableView->index(1, 1);
+ QCOMPARE(modelIndex.column(), 2);
+ QCOMPARE(modelIndex.row(), 0);
+
+ modelIndex = tableView->index(2, 2);
+ QCOMPARE(modelIndex.column(), 0);
+ QCOMPARE(modelIndex.row(), 2);
+
+ // Check cell index - cellAtIndex()
+ {
+ QPoint cell = tableView->cellAtIndex(testModel->index(0, 0));
+ QCOMPARE(cell.x(), 2);
+ QCOMPARE(cell.y(), 1);
+ }
+
+ // Check column and row index - columnAtIndex(), rowAtIndex()
+ {
+ int columnIndex = tableView->columnAtIndex(testModel->index(0, 0));
+ int rowIndex = tableView->rowAtIndex(testModel->index(0, 0));
+ QCOMPARE(columnIndex, 2);
+ QCOMPARE(rowIndex, 1);
+ }
+
+ // Check item - itemAtIndex()
+ // Item at index provides the item that is mapped to that model index
+ // and it shouldn't be confused with cell index
+ {
+ QQuickItem *item = tableView->itemAtIndex(testModel->index(0 ,0));
+ QCOMPARE(objNameItem00, item->objectName());
+ }
+
+ // Check item at cell localtion 0, 0 - itemAtCell()
+ {
+ QQuickItem *item = tableView->itemAtCell(QPoint(0, 0));
+ QCOMPARE(objNameItem11, item->objectName());
+ }
+}
+
+void tst_QQuickTableView::checkEditAfterReorder()
+{
+ LOAD_TABLEVIEW("editdelegate.qml"); // gives us 'tableView' variable
+ auto model = TestModelAsVariant(3, 3);
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ const QSignalSpy columnMovedSpy(tableView, &QQuickTableView::columnMoved);
+ const QSignalSpy rowMovedSpy(tableView, &QQuickTableView::rowMoved);
+
+ // Move row and column
+ tableView->moveColumn(0, 1);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(columnMovedSpy.size(), 2);
+
+ tableView->moveRow(0, 1);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(rowMovedSpy.size(), 2);
+
+ // Edit model index (0, 0)
+ const QSharedPointer<TestModel> testModel = model.value<QSharedPointer<TestModel>>();
+ const auto cellItem1 = tableView->itemAtCell(QPoint(0, 0));
+ QCOMPARE(cellItem1->property("editing").toBool(), false);
+
+ tableView->edit(testModel->index(1, 1));
+ QCOMPARE(cellItem1->property("editing").toBool(), true);
+
+ // Close the editor
+ tableView->closeEditor();
+ QCOMPARE(cellItem1->property("editing").toBool(), false);
+}
+
+void tst_QQuickTableView::checkSelectionAfterReorder()
+{
+ LOAD_TABLEVIEW("tableviewwithselected1.qml");
+
+ TestModel model(10, 10);
+ QItemSelectionModel selectionModel(&model);
+
+ tableView->setModel(QVariant::fromValue(&model));
+ tableView->setSelectionModel(&selectionModel);
+
+ WAIT_UNTIL_POLISHED;
+
+ QCOMPARE(selectionModel.hasSelection(), false);
+ QCOMPARE(tableView->selectionBehavior(), QQuickTableView::SelectCells);
+
+ const QSignalSpy columnMovedSpy(tableView, &QQuickTableView::columnMoved);
+ tableView->moveColumn(0, 2);
+ WAIT_UNTIL_POLISHED;
+ QCOMPARE(columnMovedSpy.size(), 3);
+
+ const QPoint endCellDist(1, 1);
+ const QPoint startCell(0, 0);
+ const QPoint endCell = startCell + endCellDist;
+
+ const QQuickItem *startItem = tableView->itemAtCell(startCell);
+ const QQuickItem *endItem = tableView->itemAtCell(endCell);
+ QVERIFY(startItem);
+ QVERIFY(endItem);
+
+ const QPointF startPos(startItem->x(), startItem->y());
+ const QPointF endPos(endItem->x(), endItem->y());
+
+ QVERIFY(tableViewPrivate->startSelection(startPos, Qt::NoModifier));
+ tableViewPrivate->setSelectionStartPos(startPos);
+ tableViewPrivate->setSelectionEndPos(endPos);
+
+ QCOMPARE(selectionModel.hasSelection(), true);
+
+ const int x1 = qMin(startCell.x(), endCell.x());
+ const int x2 = qMax(startCell.x(), endCell.x());
+ const int y1 = qMin(startCell.y(), endCell.y());
+ const int y2 = qMax(startCell.y(), endCell.y());
+
+ for (int x = x1; x <= x2; ++x) {
+ for (int y = y1; y <= y2; ++y) {
+ const auto index = tableView->index(y, x);
+ QVERIFY(selectionModel.isSelected(index));
+ }
+ }
+
+ const int expectedCount = (x2 - x1 + 1) * (y2 - y1 + 1);
+ const int actualCount = selectionModel.selectedIndexes().size();
+ QCOMPARE(actualCount, expectedCount);
+
+ // The column which has been moved shouldn't have the selected
+ // bit enabled
+ for (int index = 0; index < model.rowCount(); index++)
+ QCOMPARE(selectionModel.isSelected(model.index(index, 0)), false);
+
+ tableViewPrivate->clearSelection();
+ QCOMPARE(selectionModel.hasSelection(), false);
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"