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);
|
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||||
if ((anchor && !(command & QItemSelectionModel::Current))
|
if ((anchor && !(command & QItemSelectionModel::Current))
|
||||||
|| (q->selectionMode() == QTableView::SingleSelection))
|
|| (q->selectionMode() == QTableView::SingleSelection))
|
||||||
rowSectionAnchor = row;
|
currentSelectionStartIndex = model->index(row, column, root);
|
||||||
|
|
||||||
if (q->selectionMode() != QTableView::SingleSelection
|
if (q->selectionMode() != QTableView::SingleSelection
|
||||||
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
||||||
@ -3401,6 +3401,7 @@ void QTableViewPrivate::selectRow(int row, bool anchor)
|
|||||||
command |= QItemSelectionModel::Current;
|
command |= QItemSelectionModel::Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto rowSectionAnchor = currentSelectionStartIndex.row();
|
||||||
QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);
|
QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);
|
||||||
QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);
|
QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);
|
||||||
if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {
|
if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {
|
||||||
@ -3427,7 +3428,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
|
|||||||
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||||
if ((anchor && !(command & QItemSelectionModel::Current))
|
if ((anchor && !(command & QItemSelectionModel::Current))
|
||||||
|| (q->selectionMode() == QTableView::SingleSelection))
|
|| (q->selectionMode() == QTableView::SingleSelection))
|
||||||
columnSectionAnchor = column;
|
currentSelectionStartIndex = model->index(row, column, root);
|
||||||
|
|
||||||
if (q->selectionMode() != QTableView::SingleSelection
|
if (q->selectionMode() != QTableView::SingleSelection
|
||||||
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
&& command.testFlag(QItemSelectionModel::Toggle)) {
|
||||||
@ -3440,6 +3441,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
|
|||||||
command |= QItemSelectionModel::Current;
|
command |= QItemSelectionModel::Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto columnSectionAnchor = currentSelectionStartIndex.column();
|
||||||
QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);
|
QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);
|
||||||
QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);
|
QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);
|
||||||
if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {
|
if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {
|
||||||
|
@ -136,7 +136,6 @@ class QTableViewPrivate : public QAbstractItemViewPrivate
|
|||||||
public:
|
public:
|
||||||
QTableViewPrivate()
|
QTableViewPrivate()
|
||||||
: showGrid(true), gridStyle(Qt::SolidLine),
|
: showGrid(true), gridStyle(Qt::SolidLine),
|
||||||
rowSectionAnchor(-1), columnSectionAnchor(-1),
|
|
||||||
columnResizeTimerID(0), rowResizeTimerID(0),
|
columnResizeTimerID(0), rowResizeTimerID(0),
|
||||||
horizontalHeader(nullptr), verticalHeader(nullptr),
|
horizontalHeader(nullptr), verticalHeader(nullptr),
|
||||||
sortingEnabled(false), geometryRecursionBlock(false),
|
sortingEnabled(false), geometryRecursionBlock(false),
|
||||||
@ -186,8 +185,6 @@ public:
|
|||||||
|
|
||||||
bool showGrid;
|
bool showGrid;
|
||||||
Qt::PenStyle gridStyle;
|
Qt::PenStyle gridStyle;
|
||||||
int rowSectionAnchor;
|
|
||||||
int columnSectionAnchor;
|
|
||||||
int columnResizeTimerID;
|
int columnResizeTimerID;
|
||||||
int rowResizeTimerID;
|
int rowResizeTimerID;
|
||||||
QList<int> columnsToUpdate;
|
QList<int> columnsToUpdate;
|
||||||
|
@ -437,6 +437,8 @@ private slots:
|
|||||||
void taskQTBUG_30653_doItemsLayout();
|
void taskQTBUG_30653_doItemsLayout();
|
||||||
void taskQTBUG_50171_selectRowAfterSwapColumns();
|
void taskQTBUG_50171_selectRowAfterSwapColumns();
|
||||||
void deselectRow();
|
void deselectRow();
|
||||||
|
void selectRowsAndCells();
|
||||||
|
void selectColumnsAndCells();
|
||||||
|
|
||||||
#if QT_CONFIG(wheelevent)
|
#if QT_CONFIG(wheelevent)
|
||||||
void mouseWheel_data();
|
void mouseWheel_data();
|
||||||
@ -4783,6 +4785,76 @@ void tst_QTableView::deselectRow()
|
|||||||
QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex()));
|
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
|
// This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel
|
||||||
#if QT_CONFIG(textmarkdownwriter)
|
#if QT_CONFIG(textmarkdownwriter)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user