diff options
author | Daniel Teske <qt@squorn.de> | 2017-11-06 14:44:42 +0100 |
---|---|---|
committer | Daniel Teske <qt@squorn.de> | 2018-04-30 19:01:14 +0000 |
commit | 259648f876b2092f7d28925ba4569ac8a5612ca8 (patch) | |
tree | 0c72e7bf6d7e576d3c4544a9f00c031abd02bfda /src/corelib/itemmodels | |
parent | edf6debbabe997dee9e636a831ccff73d184b6c1 (diff) |
QItemSelectionModel: More fixes for is(Column/Row)Selected
Replace the code for isRowSelected and isColumnSelected with
a much simpler algorithm for deciding if a row/column is selected.
In a model with a cross-hatch of unselectable indexes, the return values
of is(Column/Row)Selected would depend on the order in which the
selections were done.
Task-number: QTBUG-18001
Change-Id: I6aa4b1df7c07fae469a686041927fa8c42bc9b16
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/corelib/itemmodels')
-rw-r--r-- | src/corelib/itemmodels/qitemselectionmodel.cpp | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp index ceec0e4c94..edb9bb9098 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.cpp +++ b/src/corelib/itemmodels/qitemselectionmodel.cpp @@ -1502,30 +1502,40 @@ bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) cons && d->currentSelection.at(i).intersected(d->ranges.at(j)).isValid()) return false; } + + auto isSelectable = [&](int row, int column) { + Qt::ItemFlags flags = d->model->index(row, column, parent).flags(); + return (flags & Qt::ItemIsSelectable); + }; + + const int colCount = d->model->columnCount(parent); + int unselectable = 0; // add ranges and currentSelection and check through them all QList<QItemSelectionRange>::const_iterator it; QList<QItemSelectionRange> joined = d->ranges; if (d->currentSelection.count()) joined += d->currentSelection; - int colCount = d->model->columnCount(parent); for (int column = 0; column < colCount; ++column) { + if (!isSelectable(row, column)) { + ++unselectable; + continue; + } + for (it = joined.constBegin(); it != joined.constEnd(); ++it) { if ((*it).contains(row, column, parent)) { - bool selectable = false; - for (int i = column; !selectable && i <= (*it).right(); ++i) { - Qt::ItemFlags flags = d->model->index(row, i, parent).flags(); - selectable = flags & Qt::ItemIsSelectable; - } - if (selectable){ - column = qMax(column, (*it).right()); - break; + for (int i = column; i <= (*it).right(); ++i) { + if (!isSelectable(row, i)) + ++unselectable; } + + column = qMax(column, (*it).right()); + break; } } if (it == joined.constEnd()) return false; } - return colCount > 0; // no columns means no selected items + return unselectable < colCount; } /*! @@ -1568,30 +1578,39 @@ bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent } } } + + auto isSelectable = [&](int row, int column) { + Qt::ItemFlags flags = d->model->index(row, column, parent).flags(); + return (flags & Qt::ItemIsSelectable); + }; + const int rowCount = d->model->rowCount(parent); + int unselectable = 0; + // add ranges and currentSelection and check through them all QList<QItemSelectionRange>::const_iterator it; QList<QItemSelectionRange> joined = d->ranges; if (d->currentSelection.count()) joined += d->currentSelection; - int rowCount = d->model->rowCount(parent); for (int row = 0; row < rowCount; ++row) { - for (it = joined.constBegin(); it != joined.constEnd(); ++it) { - if ((*it).contains(row, column, parent)) { - bool selectable = false; - for (int i = row; !selectable && i <= (*it).bottom(); ++i) { - Qt::ItemFlags flags = d->model->index(i, column, parent).flags(); - selectable = flags & Qt::ItemIsSelectable; - } - if (selectable){ - row = qMax(row, (*it).bottom()); - break; - } - } - } - if (it == joined.constEnd()) - return false; + if (!isSelectable(row, column)) { + ++unselectable; + continue; + } + for (it = joined.constBegin(); it != joined.constEnd(); ++it) { + if ((*it).contains(row, column, parent)) { + for (int i = row; i <= (*it).bottom(); ++i) { + if (!isSelectable(i, column)) { + ++unselectable; + } + } + row = qMax(row, (*it).bottom()); + break; + } + } + if (it == joined.constEnd()) + return false; } - return rowCount > 0; // no rows means no selected items + return unselectable < rowCount; } /*! |