QTableView: Fix selection for reordered or hidden rows/columns

The old code sometimes made incorrect selections when rows or columns were
hidden or moved. It used logical top left and bottom right indexes to create a
selection rectangle. However on moved or hidden cells a wrong rectangle was
made. This fix calculates a simple rectangle without hidden cells and makes use
of the row/column select functionality provided by the selection model, to make
the right selection.

[ChangeLog][QtWidgets][QTableView] Fixed a selection bug when rows or columns were hidden (QTBUG-50171)

Task-number: QTBUG-50171
Change-Id: Id186012af26da7b2051ff5eb1c13e6b7494cca77
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
This commit is contained in:
Vyacheslav Grigoryev 2016-05-06 01:29:27 +03:00 committed by Thorbjørn Lund Martsum
parent 194a56ea79
commit 558718ff44
2 changed files with 46 additions and 13 deletions

View File

@ -3249,13 +3249,12 @@ void QTableViewPrivate::selectRow(int row, bool anchor)
command |= QItemSelectionModel::Current;
}
QModelIndex tl = model->index(qMin(rowSectionAnchor, row), logicalColumn(0), root);
QModelIndex br = model->index(qMax(rowSectionAnchor, row), logicalColumn(model->columnCount(root) - 1), root);
if ((verticalHeader->sectionsMoved() && tl.row() != br.row())
|| horizontalHeader->sectionsMoved()) {
q->setSelection(q->visualRect(tl)|q->visualRect(br), command);
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())) {
q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows);
} else {
selectionModel->select(QItemSelection(tl, br), command);
selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows);
}
}
}
@ -3289,14 +3288,12 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
command |= QItemSelectionModel::Current;
}
QModelIndex tl = model->index(logicalRow(0), qMin(columnSectionAnchor, column), root);
QModelIndex br = model->index(logicalRow(model->rowCount(root) - 1),
qMax(columnSectionAnchor, column), root);
if ((horizontalHeader->sectionsMoved() && tl.column() != br.column())
|| verticalHeader->sectionsMoved()) {
q->setSelection(q->visualRect(tl)|q->visualRect(br), command);
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())) {
q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns);
} else {
selectionModel->select(QItemSelection(tl, br), command);
selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns);
}
}
}

View File

@ -203,6 +203,7 @@ private slots:
void taskQTBUG_8777_scrollToSpans();
void taskQTBUG_10169_sizeHintForRow();
void taskQTBUG_30653_doItemsLayout();
void taskQTBUG_50171_selectRowAfterSwapColumns();
#ifndef QT_NO_WHEELEVENT
void mouseWheel_data();
@ -4476,5 +4477,40 @@ void tst_QTableView::taskQTBUG_30653_doItemsLayout()
QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset);
}
void tst_QTableView::taskQTBUG_50171_selectRowAfterSwapColumns()
{
{
QtTestTableView tableView;
QtTestTableModel model(2, 3);
tableView.setModel(&model);
tableView.horizontalHeader()->swapSections(1, 2);
tableView.horizontalHeader()->hideSection(0);
tableView.selectRow(1);
QItemSelectionModel* tableSelectionModel = tableView.selectionModel();
QCOMPARE(tableSelectionModel->isRowSelected(1, QModelIndex()), true);
QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 0)), false);
QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 1)), false);
QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 2)), false);
}
{
QtTestTableView tableView;
QtTestTableModel model(3, 2);
tableView.setModel(&model);
tableView.verticalHeader()->swapSections(1, 2);
tableView.verticalHeader()->hideSection(0);
tableView.selectColumn(1);
QItemSelectionModel* sModel = tableView.selectionModel();
QCOMPARE(sModel->isColumnSelected(1, QModelIndex()), true);
QCOMPARE(sModel->isSelected(tableView.model()->index(0, 0)), false);
QCOMPARE(sModel->isSelected(tableView.model()->index(1, 0)), false);
QCOMPARE(sModel->isSelected(tableView.model()->index(2, 0)), false);
}
}
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"