QTableView: fix selection with rows and cells in ExtendedSelection mode
QTableView stored the current row/column selection start in an own variable instead using currentSelectionStartIndex. This leads to an inconsistent behavior when the selection is done with a click on the header and then in a cell (and the other way round) Fixes: QTBUG-92561 Change-Id: I4c8bda3a938de451b6eff2819141e86a6870fbef Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit e8b3d35a18e7e4cf6543868d89d6060c90314f39) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e8d39c670e
commit
39817d0f3b
@ -3388,7 +3388,7 @@ void QTableViewPrivate::selectRow(int row, bool anchor)
|
||||
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
if ((anchor && !(command & QItemSelectionModel::Current))
|
||||
|| (q->selectionMode() == QTableView::SingleSelection))
|
||||
rowSectionAnchor = row;
|
||||
currentSelectionStartIndex = model->index(row, column, root);
|
||||
|
||||
if (q->selectionMode() != QTableView::SingleSelection
|
||||
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
||||
@ -3401,6 +3401,7 @@ void QTableViewPrivate::selectRow(int row, bool anchor)
|
||||
command |= QItemSelectionModel::Current;
|
||||
}
|
||||
|
||||
const auto rowSectionAnchor = currentSelectionStartIndex.row();
|
||||
QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);
|
||||
QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);
|
||||
if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {
|
||||
@ -3427,7 +3428,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
|
||||
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||
if ((anchor && !(command & QItemSelectionModel::Current))
|
||||
|| (q->selectionMode() == QTableView::SingleSelection))
|
||||
columnSectionAnchor = column;
|
||||
currentSelectionStartIndex = model->index(row, column, root);
|
||||
|
||||
if (q->selectionMode() != QTableView::SingleSelection
|
||||
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
||||
@ -3440,6 +3441,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
|
||||
command |= QItemSelectionModel::Current;
|
||||
}
|
||||
|
||||
const auto columnSectionAnchor = currentSelectionStartIndex.column();
|
||||
QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);
|
||||
QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);
|
||||
if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {
|
||||
|
@ -136,7 +136,6 @@ class QTableViewPrivate : public QAbstractItemViewPrivate
|
||||
public:
|
||||
QTableViewPrivate()
|
||||
: showGrid(true), gridStyle(Qt::SolidLine),
|
||||
rowSectionAnchor(-1), columnSectionAnchor(-1),
|
||||
columnResizeTimerID(0), rowResizeTimerID(0),
|
||||
horizontalHeader(nullptr), verticalHeader(nullptr),
|
||||
sortingEnabled(false), geometryRecursionBlock(false),
|
||||
@ -186,8 +185,6 @@ public:
|
||||
|
||||
bool showGrid;
|
||||
Qt::PenStyle gridStyle;
|
||||
int rowSectionAnchor;
|
||||
int columnSectionAnchor;
|
||||
int columnResizeTimerID;
|
||||
int rowResizeTimerID;
|
||||
QList<int> columnsToUpdate;
|
||||
|
@ -437,6 +437,8 @@ private slots:
|
||||
void taskQTBUG_30653_doItemsLayout();
|
||||
void taskQTBUG_50171_selectRowAfterSwapColumns();
|
||||
void deselectRow();
|
||||
void selectRowsAndCells();
|
||||
void selectColumnsAndCells();
|
||||
|
||||
#if QT_CONFIG(wheelevent)
|
||||
void mouseWheel_data();
|
||||
@ -4783,6 +4785,76 @@ void tst_QTableView::deselectRow()
|
||||
QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex()));
|
||||
}
|
||||
|
||||
class QTableViewSelectCells : public QTableView
|
||||
{
|
||||
public:
|
||||
QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index,
|
||||
const QEvent *) const override
|
||||
{
|
||||
return QTableView::selectionCommand(index, shiftPressed ? &mouseEvent : nullptr);
|
||||
}
|
||||
QMouseEvent mouseEvent = QMouseEvent(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::ShiftModifier);
|
||||
bool shiftPressed = false;
|
||||
};
|
||||
|
||||
void tst_QTableView::selectRowsAndCells()
|
||||
{
|
||||
const auto checkRows = [](const QModelIndexList &mil)
|
||||
{
|
||||
QCOMPARE(mil.size(), 3);
|
||||
for (const auto &mi : mil)
|
||||
QVERIFY(mi.row() >= 1 && mi.row() <= 3);
|
||||
};
|
||||
QTableViewSelectCells tw;
|
||||
QtTestTableModel model(5, 1);
|
||||
tw.setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
tw.setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
tw.setModel(&model);
|
||||
tw.show();
|
||||
|
||||
tw.selectRow(1);
|
||||
tw.shiftPressed = true;
|
||||
tw.selectRow(2);
|
||||
tw.shiftPressed = false;
|
||||
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(3, 0)).center());
|
||||
checkRows(tw.selectionModel()->selectedRows());
|
||||
|
||||
tw.clearSelection();
|
||||
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(3, 0)).center());
|
||||
tw.shiftPressed = true;
|
||||
tw.selectRow(1);
|
||||
checkRows(tw.selectionModel()->selectedRows());
|
||||
}
|
||||
|
||||
void tst_QTableView::selectColumnsAndCells()
|
||||
{
|
||||
const auto checkColumns = [](const QModelIndexList &mil)
|
||||
{
|
||||
QCOMPARE(mil.size(), 3);
|
||||
for (const auto &mi : mil)
|
||||
QVERIFY(mi.column() >= 1 && mi.column() <= 3);
|
||||
};
|
||||
QTableViewSelectCells tw;
|
||||
QtTestTableModel model(1, 5);
|
||||
tw.setSelectionBehavior(QAbstractItemView::SelectColumns);
|
||||
tw.setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
tw.setModel(&model);
|
||||
tw.show();
|
||||
|
||||
tw.selectColumn(1);
|
||||
tw.shiftPressed = true;
|
||||
tw.selectColumn(2);
|
||||
tw.shiftPressed = false;
|
||||
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(0, 3)).center());
|
||||
checkColumns(tw.selectionModel()->selectedColumns());
|
||||
|
||||
tw.clearSelection();
|
||||
QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(0, 3)).center());
|
||||
tw.shiftPressed = true;
|
||||
tw.selectColumn(1);
|
||||
checkColumns(tw.selectionModel()->selectedColumns());
|
||||
}
|
||||
|
||||
// This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel
|
||||
#if QT_CONFIG(textmarkdownwriter)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user