313void QSpanCollection::updateRemovedRows(
int start,
int end)
315#ifdef DEBUG_SPAN_UPDATE
316 qDebug() << start << end << Qt::endl << index;
321 SpanList spansToBeDeleted;
322 int delta = end - start + 1;
323#ifdef DEBUG_SPAN_UPDATE
326 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
328#ifdef DEBUG_SPAN_UPDATE
329 qDebug() << span << *span;
331 if (span->m_bottom < start) {
335 if (span->m_top < start) {
336 if (span->m_bottom <= end)
337 span->m_bottom = start - 1;
339 span->m_bottom -= delta;
341 if (span->m_bottom > end) {
342 if (span->m_top <= end)
345 span->m_top -= delta;
346 span->m_bottom -= delta;
348 span->will_be_deleted =
true;
351 if (span->m_top == span->m_bottom && span->m_left == span->m_right)
352 span->will_be_deleted =
true;
353 if (span->will_be_deleted) {
354 spansToBeDeleted.push_back(span);
355 it = spans.erase(it);
361#ifdef DEBUG_SPAN_UPDATE
366 qDeleteAll(spansToBeDeleted);
371 Index::iterator it_y = index.end();
375 SubIndex &subindex = it_y.value();
377 if (cleanSpanSubIndex(subindex, y))
378 it_y = index.erase(it_y);
379 }
else if (y >= start && y <= end) {
380 bool span_at_start =
false;
381 SubIndex spansToBeMoved;
382 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {
383 Span *span = it.value();
384 if (span->will_be_deleted)
386 if (!span_at_start && span->m_top == start)
387 span_at_start =
true;
388 spansToBeMoved.insert(it.key(), span);
391 if (y == start && span_at_start)
394 it_y = index.erase(it_y);
397 Index::iterator it_start;
401 it_start = index.find(-start);
402 if (it_start == index.end())
403 it_start = index.insert(-start, SubIndex());
405 SubIndex &start_subindex = it_start.value();
406 for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)
407 start_subindex.insert(it.key(), it.value());
411 Index::iterator it_top = index.find(-y + delta);
412 if (it_top == index.end())
413 it_top = index.insert(-y + delta, SubIndex());
414 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
415 Span *span = it.value();
416 if (!span->will_be_deleted)
417 it_top.value().insert(it.key(), span);
421 index.insert(-y + delta, subindex);
423 it_y = index.erase(it_y);
425 }
while (it_y != index.begin());
427#ifdef DEBUG_SPAN_UPDATE
430 qDebug() << spansToBeDeleted;
432 qDeleteAll(spansToBeDeleted);
661QRect QTableViewPrivate::intersectedRect(
const QRect rect,
const QModelIndex &topLeft,
const QModelIndex &bottomRight)
const
663 Q_Q(
const QTableView);
665 using minMaxPair = std::pair<
int,
int>;
666 const auto calcMinMax = [q](QHeaderView *hdr,
int startIdx,
int endIdx, minMaxPair bounds) -> minMaxPair
668 minMaxPair ret(std::numeric_limits<
int>::max(), std::numeric_limits<
int>::min());
669 if (hdr->sectionsMoved()) {
670 for (
int i = startIdx; i <= endIdx; ++i) {
671 const int start = hdr->sectionViewportPosition(i);
672 const int end = start + hdr->sectionSize(i);
673 ret.first = std::min(start, ret.first);
674 ret.second = std::max(end, ret.second);
675 if (ret.first <= bounds.first && ret.second >= bounds.second)
679 if (q->isRightToLeft() && q->horizontalHeader() == hdr)
680 std::swap(startIdx, endIdx);
681 ret.first = hdr->sectionViewportPosition(startIdx);
682 ret.second = hdr->sectionViewportPosition(endIdx) +
683 hdr->sectionSize(endIdx);
688 const auto yVals = calcMinMax(verticalHeader, topLeft.row(), bottomRight.row(),
689 minMaxPair(rect.top(), rect.bottom()));
690 if (yVals.first == yVals.second)
694 const QRect colRect(QPoint(rect.left(), yVals.first),
695 QPoint(rect.right(), yVals.second));
696 const QRect intersected = rect.intersected(colRect);
697 if (intersected.isNull())
700 const auto xVals = calcMinMax(horizontalHeader, topLeft.column(), bottomRight.column(),
701 minMaxPair(rect.left(), rect.right()));
702 const QRect updateRect(QPoint(xVals.first, yVals.first),
703 QPoint(xVals.second, yVals.second));
704 return rect.intersected(updateRect);
894void QTableViewPrivate::drawAndClipSpans(
const QRegion &area, QPainter *painter,
895 const QStyleOptionViewItem &option, QBitArray *drawn,
896 int firstVisualRow,
int lastVisualRow,
int firstVisualColumn,
int lastVisualColumn)
898 Q_Q(
const QTableView);
899 bool alternateBase =
false;
900 QRegion region = viewport->rect();
902 QSet<QSpanCollection::Span *> visibleSpans;
903 bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved();
906 visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),
907 lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);
922 const auto spanList = spans.spans;
923 for (QSpanCollection::Span *span : spanList) {
924 const int spanVisualLeft = visualColumn(span->left());
925 const int spanVisualTop = visualRow(span->top());
926 const int spanVisualRight = spanVisualLeft + span->width() - 1;
927 const int spanVisualBottom = spanVisualTop + span->height() - 1;
928 if ((spanVisualLeft <= lastVisualColumn && spanVisualRight >= firstVisualColumn)
929 && (spanVisualTop <= lastVisualRow && spanVisualBottom >= firstVisualRow))
930 visibleSpans.insert(span);
934 for (QSpanCollection::Span *span : std::as_const(visibleSpans)) {
935 int row = span->top();
936 int col = span->left();
937 QModelIndex index = model->index(row, col, root);
938 if (!index.isValid())
940 QRect rect = visualSpanRect(*span);
941 rect.translate(scrollDelayOffset);
942 if (!area.intersects(rect))
944 QStyleOptionViewItem opt = option;
946 alternateBase = alternatingColors && (span->top() & 1);
947 opt.features.setFlag(QStyleOptionViewItem::Alternate, alternateBase);
948 drawCell(painter, opt, index);
952 if (horizontalHeader->visualIndex(row) == 0)
953 rect.setTop(rect.top() + 1);
954 if (verticalHeader->visualIndex(row) == 0) {
955 if (q->isLeftToRight())
956 rect.setLeft(rect.left() + 1);
958 rect.setRight(rect.right() - 1);
962 for (
int r = span->top(); r <= span->bottom(); ++r) {
963 const int vr = visualRow(r);
964 if (vr < firstVisualRow || vr > lastVisualRow)
966 for (
int c = span->left(); c <= span->right(); ++c) {
967 const int vc = visualColumn(c);
968 if (vc < firstVisualColumn || vc > lastVisualColumn)
970 drawn->setBit((vr - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
971 + vc - firstVisualColumn);
976 painter->setClipRegion(region);
1392void QTableView::setHorizontalHeader(QHeaderView *header)
1396 if (!header || header == d->horizontalHeader)
1398 for (
const QMetaObject::Connection &connection : d->horHeaderConnections)
1399 disconnect(connection);
1400 if (d->horizontalHeader && d->horizontalHeader->parent() ==
this)
1401 delete d->horizontalHeader;
1402 d->horizontalHeader = header;
1403 d->horizontalHeader->setParent(
this);
1404 d->horizontalHeader->setFirstSectionMovable(
true);
1405 if (!d->horizontalHeader->model()) {
1406 d->horizontalHeader->setModel(d->model);
1407 if (d->selectionModel)
1408 d->horizontalHeader->setSelectionModel(d->selectionModel);
1411 d->horHeaderConnections = {
1412 connect(d->horizontalHeader,&QHeaderView::sectionResized,
1413 this, &QTableView::columnResized),
1414 connect(d->horizontalHeader, &QHeaderView::sectionMoved,
1415 this, &QTableView::columnMoved),
1416 connect(d->horizontalHeader, &QHeaderView::sectionCountChanged,
1417 this, &QTableView::columnCountChanged),
1418 connect(d->horizontalHeader, &QHeaderView::sectionHandleDoubleClicked,
1419 this, &QTableView::resizeColumnToContents),
1420 connect(d->horizontalHeader, &QHeaderView::geometriesChanged,
1421 this, &QTableView::updateGeometries),
1424 setSortingEnabled(d->sortingEnabled);
1432void QTableView::setVerticalHeader(QHeaderView *header)
1436 if (!header || header == d->verticalHeader)
1438 for (
const QMetaObject::Connection &connection : d->verHeaderConnections)
1439 disconnect(connection);
1440 if (d->verticalHeader && d->verticalHeader->parent() ==
this)
1441 delete d->verticalHeader;
1442 d->verticalHeader = header;
1443 d->verticalHeader->setParent(
this);
1444 d->verticalHeader->setFirstSectionMovable(
true);
1445 if (!d->verticalHeader->model()) {
1446 d->verticalHeader->setModel(d->model);
1447 if (d->selectionModel)
1448 d->verticalHeader->setSelectionModel(d->selectionModel);
1451 d->verHeaderConnections = {
1452 connect(d->verticalHeader, &QHeaderView::sectionResized,
1453 this, &QTableView::rowResized),
1454 connect(d->verticalHeader, &QHeaderView::sectionMoved,
1455 this, &QTableView::rowMoved),
1456 connect(d->verticalHeader, &QHeaderView::sectionCountChanged,
1457 this, &QTableView::rowCountChanged),
1458 connect(d->verticalHeader, &QHeaderView::sectionPressed,
1459 this, &QTableView::selectRow),
1460 connect(d->verticalHeader, &QHeaderView::sectionHandleDoubleClicked,
1461 this, &QTableView::resizeRowToContents),
1462 connect(d->verticalHeader, &QHeaderView::geometriesChanged,
1463 this, &QTableView::updateGeometries),
1464 connect(d->verticalHeader, &QHeaderView::sectionEntered,
1465 this, [d](
int row) { d->selectRow(row,
false); })
1524void QTableView::paintEvent(QPaintEvent *event)
1528 QStyleOptionViewItem option;
1529 initViewItemOption(&option);
1530 const QPoint offset = d->scrollDelayOffset;
1531 const bool showGrid = d->showGrid;
1532 const int gridSize = showGrid ? 1 : 0;
1533 const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option,
this);
1534 const QColor gridColor = QColor::fromRgba(
static_cast<QRgb>(gridHint));
1535 const QPen gridPen = QPen(gridColor, 1, d->gridStyle);
1536 const QHeaderView *verticalHeader = d->verticalHeader;
1537 const QHeaderView *horizontalHeader = d->horizontalHeader;
1538 const bool alternate = d->alternatingColors;
1539 const bool rightToLeft = isRightToLeft();
1541 QPainter painter(d->viewport);
1544 if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate)
1547 const int x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
1548 const int y = verticalHeader->length() - verticalHeader->offset() - 1;
1552 int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
1553 int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->height());
1554 if (lastVisualRow == -1)
1555 lastVisualRow = d->model->rowCount(d->root) - 1;
1557 int firstVisualColumn = horizontalHeader->visualIndexAt(0);
1558 int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->width());
1560 qSwap(firstVisualColumn, lastVisualColumn);
1561 if (firstVisualColumn == -1)
1562 firstVisualColumn = 0;
1563 if (lastVisualColumn == -1)
1564 lastVisualColumn = horizontalHeader->count() - 1;
1566 QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
1568 const QRegion region = event->region().translated(offset);
1570 if (d->hasSpans()) {
1571 d->drawAndClipSpans(region, &painter, option, &drawn,
1572 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
1575 for (QRect dirtyArea : region) {
1576 dirtyArea.setBottom(qMin(dirtyArea.bottom(),
int(y)));
1578 dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() -
int(x)));
1580 dirtyArea.setRight(qMin(dirtyArea.right(),
int(x)));
1583 if (!dirtyArea.isValid())
1587 int left = horizontalHeader->visualIndexAt(dirtyArea.left());
1588 int right = horizontalHeader->visualIndexAt(dirtyArea.right());
1591 if (left == -1) left = 0;
1592 if (right == -1) right = horizontalHeader->count() - 1;
1595 int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom());
1596 if (bottom == -1) bottom = verticalHeader->count() - 1;
1598 bool alternateBase =
false;
1599 if (alternate && verticalHeader->sectionsHidden()) {
1600 const int verticalOffset = verticalHeader->offset();
1601 int row = verticalHeader->logicalIndex(top);
1603 ((y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom);
1605 row = verticalHeader->logicalIndex(top);
1606 if (alternate && !verticalHeader->isSectionHidden(row))
1607 alternateBase = !alternateBase;
1610 top = verticalHeader->visualIndexAt(dirtyArea.top());
1611 alternateBase = (top & 1) && alternate;
1613 if (top == -1 || top > bottom)
1617 for (
int visualRowIndex = top; visualRowIndex <= bottom; ++visualRowIndex) {
1618 int row = verticalHeader->logicalIndex(visualRowIndex);
1619 if (verticalHeader->isSectionHidden(row))
1621 int rowY = rowViewportPosition(row);
1623 int rowh = rowHeight(row) - gridSize;
1626 for (
int visualColumnIndex = left; visualColumnIndex <= right; ++visualColumnIndex) {
1627 int currentBit = (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
1628 + visualColumnIndex - firstVisualColumn;
1630 if (currentBit < 0 || currentBit >= drawn.size() || drawn.testBit(currentBit))
1632 drawn.setBit(currentBit);
1634 int col = horizontalHeader->logicalIndex(visualColumnIndex);
1635 if (horizontalHeader->isSectionHidden(col))
1637 int colp = columnViewportPosition(col);
1639 int colw = columnWidth(col) - gridSize;
1641 const QModelIndex index = d->model->index(row, col, d->root);
1642 if (index.isValid()) {
1643 option.rect = QRect(colp + (showGrid && rightToLeft ? 1 : 0), rowY, colw, rowh);
1646 option.features |= QStyleOptionViewItem::Alternate;
1648 option.features &= ~QStyleOptionViewItem::Alternate;
1650 d->drawCell(&painter, option, index);
1653 alternateBase = !alternateBase && alternate;
1658 while (verticalHeader->isSectionHidden(verticalHeader->logicalIndex(bottom))) --bottom;
1659 QPen old = painter.pen();
1660 painter.setPen(gridPen);
1662 for (
int visualIndex = top; visualIndex <= bottom; ++visualIndex) {
1663 int row = verticalHeader->logicalIndex(visualIndex);
1664 if (verticalHeader->isSectionHidden(row))
1666 int rowY = rowViewportPosition(row);
1668 int rowh = rowHeight(row) - gridSize;
1669 QLineF line(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
1670 painter.drawLine(line.translated(0.5, 0.5));
1674 for (
int h = left; h <= right; ++h) {
1675 int col = horizontalHeader->logicalIndex(h);
1676 if (horizontalHeader->isSectionHidden(col))
1678 int colp = columnViewportPosition(col);
1681 colp += columnWidth(col) - gridSize;
1682 QLineF line(colp, dirtyArea.top(), colp, dirtyArea.bottom());
1683 painter.drawLine(line.translated(0.5, 0.5));
1685 const bool drawWhenHidden = style()->styleHint(QStyle::SH_Table_AlwaysDrawLeftTopGridLines,
1687 if (drawWhenHidden && horizontalHeader->isHidden()) {
1688 const int row = verticalHeader->logicalIndex(top);
1689 if (!verticalHeader->isSectionHidden(row)) {
1690 const int rowY = rowViewportPosition(row) + offset.y();
1691 if (rowY == dirtyArea.top())
1692 painter.drawLine(dirtyArea.left(), rowY, dirtyArea.right(), rowY);
1695 if (drawWhenHidden && verticalHeader->isHidden()) {
1696 const int col = horizontalHeader->logicalIndex(left);
1697 if (!horizontalHeader->isSectionHidden(col)) {
1698 int colX = columnViewportPosition(col) + offset.x();
1699 if (!isLeftToRight())
1700 colX += columnWidth(left) - 1;
1701 if (isLeftToRight() && colX == dirtyArea.left())
1702 painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
1703 if (!isLeftToRight() && colX == dirtyArea.right())
1704 painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
1707 painter.setPen(old);
1711#if QT_CONFIG(draganddrop)
1713 d->paintDropIndicator(&painter);
1774QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
1777 Q_UNUSED(modifiers);
1779 int bottom = d->model->rowCount(d->root) - 1;
1781 while (bottom >= 0 && isRowHidden(d->logicalRow(bottom)))
1784 int right = d->model->columnCount(d->root) - 1;
1786 while (right >= 0 && isColumnHidden(d->logicalColumn(right)))
1789 if (bottom == -1 || right == -1)
1790 return QModelIndex();
1792 QModelIndex current = currentIndex();
1794 if (!current.isValid()) {
1797 while (column < right && isColumnHidden(d->logicalColumn(column)))
1799 while (isRowHidden(d->logicalRow(row)) && row < bottom)
1801 d->visualCursor = QPoint(column, row);
1802 return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);
1806 QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));
1807 if (visualCurrent != d->visualCursor) {
1808 if (d->hasSpans()) {
1809 QSpanCollection::Span span = d->span(current.row(), current.column());
1810 if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()
1811 || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())
1812 d->visualCursor = visualCurrent;
1814 d->visualCursor = visualCurrent;
1818 int visualRow = d->visualCursor.y();
1819 if (visualRow > bottom)
1821 Q_ASSERT(visualRow != -1);
1822 int visualColumn = d->visualCursor.x();
1823 if (visualColumn > right)
1824 visualColumn = right;
1825 Q_ASSERT(visualColumn != -1);
1827 if (isRightToLeft()) {
1828 if (cursorAction == MoveLeft)
1829 cursorAction = MoveRight;
1830 else if (cursorAction == MoveRight)
1831 cursorAction = MoveLeft;
1834 switch (cursorAction) {
1836 int originalRow = visualRow;
1837#ifdef QT_KEYPAD_NAVIGATION
1838 if (QApplicationPrivate::keypadNavigationEnabled() && visualRow == 0)
1839 visualRow = d->visualRow(model()->rowCount() - 1) + 1;
1842 int r = d->logicalRow(visualRow);
1843 int c = d->logicalColumn(visualColumn);
1844 if (r != -1 && d->hasSpans()) {
1845 QSpanCollection::Span span = d->span(r, c);
1846 if (span.width() > 1 || span.height() > 1)
1847 visualRow = d->visualRow(span.top());
1849 while (visualRow >= 0) {
1851 r = d->logicalRow(visualRow);
1852 c = d->logicalColumn(visualColumn);
1853 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
1857 visualRow = originalRow;
1861 int originalRow = visualRow;
1862 if (d->hasSpans()) {
1863 QSpanCollection::Span span = d->span(current.row(), current.column());
1864 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
1866#ifdef QT_KEYPAD_NAVIGATION
1867 if (QApplicationPrivate::keypadNavigationEnabled() && visualRow >= bottom)
1870 int r = d->logicalRow(visualRow);
1871 int c = d->logicalColumn(visualColumn);
1872 if (r != -1 && d->hasSpans()) {
1873 QSpanCollection::Span span = d->span(r, c);
1874 if (span.width() > 1 || span.height() > 1)
1875 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
1877 while (visualRow <= bottom) {
1879 r = d->logicalRow(visualRow);
1880 c = d->logicalColumn(visualColumn);
1881 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
1884 if (visualRow > bottom)
1885 visualRow = originalRow;
1890 int originalRow = visualRow;
1891 int originalColumn = visualColumn;
1892 bool firstTime =
true;
1893 bool looped =
false;
1894 bool wrapped =
false;
1896 int r = d->logicalRow(visualRow);
1897 int c = d->logicalColumn(visualColumn);
1898 if (firstTime && c != -1 && d->hasSpans()) {
1900 QSpanCollection::Span span = d->span(r, c);
1901 if (span.width() > 1 || span.height() > 1)
1902 visualColumn = d->visualColumn(span.left());
1904 while (visualColumn >= 0) {
1906 r = d->logicalRow(visualRow);
1907 c = d->logicalColumn(visualColumn);
1908 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
1910 if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {
1915 if (cursorAction == MoveLeft || visualColumn >= 0)
1917 visualColumn = right + 1;
1918 if (visualRow == 0) {
1925 if (visualColumn < 0)
1926 visualColumn = originalColumn;
1931 int originalRow = visualRow;
1932 int originalColumn = visualColumn;
1933 bool firstTime =
true;
1934 bool looped =
false;
1935 bool wrapped =
false;
1937 int r = d->logicalRow(visualRow);
1938 int c = d->logicalColumn(visualColumn);
1939 if (firstTime && c != -1 && d->hasSpans()) {
1941 QSpanCollection::Span span = d->span(r, c);
1942 if (span.width() > 1 || span.height() > 1)
1943 visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
1945 while (visualColumn <= right) {
1947 r = d->logicalRow(visualRow);
1948 c = d->logicalColumn(visualColumn);
1949 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
1951 if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {
1956 if (cursorAction == MoveRight || visualColumn <= right)
1959 if (visualRow == bottom) {
1966 if (visualColumn > right)
1967 visualColumn = originalColumn;
1971 visualColumn = d->nextActiveVisualColumn(visualRow, 0, right,
1972 QTableViewPrivate::SearchDirection::Increasing);
1973 if (modifiers & Qt::ControlModifier)
1974 visualRow = d->nextActiveVisualRow(0, visualColumn, bottom,
1975 QTableViewPrivate::SearchDirection::Increasing);
1978 visualColumn = d->nextActiveVisualColumn(visualRow, right, -1,
1979 QTableViewPrivate::SearchDirection::Decreasing);
1980 if (modifiers & Qt::ControlModifier)
1981 visualRow = d->nextActiveVisualRow(bottom, visualColumn, -1,
1982 QTableViewPrivate::SearchDirection::Decreasing);
1985 int newLogicalRow = rowAt(visualRect(current).bottom() - d->viewport->height());
1986 int visualRow = (newLogicalRow == -1 ? 0 : d->visualRow(newLogicalRow));
1987 visualRow = d->nextActiveVisualRow(visualRow, current.column(), bottom,
1988 QTableViewPrivate::SearchDirection::Increasing);
1989 newLogicalRow = d->logicalRow(visualRow);
1990 return d->model->index(newLogicalRow, current.column(), d->root);
1992 case MovePageDown: {
1993 int newLogicalRow = rowAt(visualRect(current).top() + d->viewport->height());
1994 int visualRow = (newLogicalRow == -1 ? bottom : d->visualRow(newLogicalRow));
1995 visualRow = d->nextActiveVisualRow(visualRow, current.column(), -1,
1996 QTableViewPrivate::SearchDirection::Decreasing);
1997 newLogicalRow = d->logicalRow(visualRow);
1998 return d->model->index(newLogicalRow, current.column(), d->root);
2001 d->visualCursor = QPoint(visualColumn, visualRow);
2002 int logicalRow = d->logicalRow(visualRow);
2003 int logicalColumn = d->logicalColumn(visualColumn);
2004 if (!d->model->hasIndex(logicalRow, logicalColumn, d->root))
2005 return QModelIndex();
2007 QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
2008 if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) {
2009 if (d->hasSpans()) {
2010 QSpanCollection::Span span = d->span(result.row(), result.column());
2011 if (span.width() > 1 || span.height() > 1) {
2012 result = d->model->sibling(span.top(), span.left(), result);
2018 return QModelIndex();
2028void QTableView::setSelection(
const QRect &rect, QItemSelectionModel::SelectionFlags command)
2031 QModelIndex tl = indexAt(QPoint(isRightToLeft() ? qMax(rect.left(), rect.right())
2032 : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom())));
2033 QModelIndex br = indexAt(QPoint(isRightToLeft() ? qMin(rect.left(), rect.right()) :
2034 qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom())));
2035 if (!d->selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br))
2038 const bool verticalMoved = verticalHeader()->sectionsMoved();
2039 const bool horizontalMoved = horizontalHeader()->sectionsMoved();
2041 QItemSelection selection;
2043 int bottom = br.row();
2044 int left = tl.column();
2045 int right = br.column();
2047 const auto updateVisualIndices = [&]() {
2048 if (verticalMoved && horizontalMoved) {
2049 top = d->visualRow(tl.row());
2050 bottom = d->visualRow(br.row());
2051 left = d->visualColumn(tl.column());
2052 right = d->visualColumn(br.column());
2053 }
else if (horizontalMoved) {
2056 left = d->visualColumn(tl.column());
2057 right = d->visualColumn(br.column());
2058 }
else if (verticalMoved) {
2059 top = d->visualRow(tl.row());
2060 bottom = d->visualRow(br.row());
2062 right = br.column();
2066 if (d->hasSpans()) {
2070 bool intersectsSpan =
false;
2071 top = qMin(d->visualRow(tl.row()), d->visualRow(br.row()));
2072 left = qMin(d->visualColumn(tl.column()), d->visualColumn(br.column()));
2073 bottom = qMax(d->visualRow(tl.row()), d->visualRow(br.row()));
2074 right = qMax(d->visualColumn(tl.column()), d->visualColumn(br.column()));
2077 for (QSpanCollection::Span *it : d->spans.spans) {
2078 const QSpanCollection::Span &span = *it;
2079 const int t = d->visualRow(span.top());
2080 const int l = d->visualColumn(span.left());
2081 const int b = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
2082 const int r = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
2083 if ((t > bottom) || (l > right) || (top > b) || (left > r))
2085 intersectsSpan =
true;
2106 if (!intersectsSpan) {
2107 updateVisualIndices();
2108 }
else if (!verticalMoved && !horizontalMoved) {
2110 tl = d->model->index(top, left, d->root);
2111 br = d->model->index(bottom, right, d->root);
2114 updateVisualIndices();
2117 if (horizontalMoved && verticalMoved) {
2118 selection.reserve((right - left + 1) * (bottom - top + 1));
2119 for (
int horizontal = left; horizontal <= right; ++horizontal) {
2120 int column = d->logicalColumn(horizontal);
2121 for (
int vertical = top; vertical <= bottom; ++vertical) {
2122 int row = d->logicalRow(vertical);
2123 QModelIndex index = d->model->index(row, column, d->root);
2124 selection.append(QItemSelectionRange(index));
2127 }
else if (horizontalMoved) {
2128 selection.reserve(right - left + 1);
2129 for (
int visual = left; visual <= right; ++visual) {
2130 int column = d->logicalColumn(visual);
2131 QModelIndex topLeft = d->model->index(top, column, d->root);
2133 selection.append(QItemSelectionRange(topLeft));
2135 selection.append({ topLeft, topLeft.siblingAtRow(bottom) });
2137 }
else if (verticalMoved) {
2138 selection.reserve(bottom - top + 1);
2139 for (
int visual = top; visual <= bottom; ++visual) {
2140 int row = d->logicalRow(visual);
2141 QModelIndex topLeft = d->model->index(row, left, d->root);
2143 selection.append(QItemSelectionRange(topLeft));
2145 selection.append({ topLeft, topLeft.siblingAtColumn(right) });
2148 QItemSelectionRange range(tl, br);
2149 if (!range.isEmpty())
2150 selection.append(range);
2153 d->selectionModel->select(selection, command);
2165QRegion QTableView::visualRegionForSelection(
const QItemSelection &selection)
const
2167 Q_D(
const QTableView);
2169 if (selection.isEmpty())
2172 QRegion selectionRegion;
2173 const QRect &viewportRect = d->viewport->rect();
2174 bool verticalMoved = verticalHeader()->sectionsMoved();
2175 bool horizontalMoved = horizontalHeader()->sectionsMoved();
2177 if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
2178 for (
const auto &range : selection) {
2179 if (range.parent() != d->root || !range.isValid())
2181 for (
int r = range.top(); r <= range.bottom(); ++r)
2182 for (
int c = range.left(); c <= range.right(); ++c) {
2183 const QRect &rangeRect = visualRect(d->model->index(r, c, d->root));
2184 if (viewportRect.intersects(rangeRect))
2185 selectionRegion += rangeRect;
2188 }
else if (horizontalMoved) {
2189 for (
const auto &range : selection) {
2190 if (range.parent() != d->root || !range.isValid())
2192 int top = rowViewportPosition(range.top());
2193 int bottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
2195 qSwap<
int>(top, bottom);
2196 int height = bottom - top;
2197 for (
int c = range.left(); c <= range.right(); ++c) {
2198 const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
2199 if (viewportRect.intersects(rangeRect))
2200 selectionRegion += rangeRect;
2203 }
else if (verticalMoved) {
2204 for (
const auto &range : selection) {
2205 if (range.parent() != d->root || !range.isValid())
2207 int left = columnViewportPosition(range.left());
2208 int right = columnViewportPosition(range.right()) + columnWidth(range.right());
2210 qSwap<
int>(left, right);
2211 int width = right - left;
2212 for (
int r = range.top(); r <= range.bottom(); ++r) {
2213 const QRect rangeRect(left, rowViewportPosition(r), width, rowHeight(r));
2214 if (viewportRect.intersects(rangeRect))
2215 selectionRegion += rangeRect;
2219 const int gridAdjust = showGrid() ? 1 : 0;
2220 for (
auto range : selection) {
2221 if (range.parent() != d->root || !range.isValid())
2223 d->trimHiddenSelections(&range);
2225 const int rtop = rowViewportPosition(range.top());
2226 const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
2229 if (isLeftToRight()) {
2230 rleft = columnViewportPosition(range.left());
2231 rright = columnViewportPosition(range.right()) + columnWidth(range.right());
2233 rleft = columnViewportPosition(range.right());
2234 rright = columnViewportPosition(range.left()) + columnWidth(range.left());
2236 const QRect rangeRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
2237 if (viewportRect.intersects(rangeRect))
2238 selectionRegion += rangeRect;
2239 if (d->hasSpans()) {
2240 const auto spansInRect = d->spans.spansInRect(range.left(), range.top(), range.width(), range.height());
2241 for (QSpanCollection::Span *s : spansInRect) {
2242 if (range.contains(s->top(), s->left(), range.parent())) {
2243 const QRect &visualSpanRect = d->visualSpanRect(*s);
2244 if (viewportRect.intersects(visualSpanRect))
2245 selectionRegion += visualSpanRect;
2252 return selectionRegion;
2309void QTableView::updateGeometries()
2312 if (d->geometryRecursionBlock)
2314 d->geometryRecursionBlock =
true;
2317 if (!d->verticalHeader->isHidden()) {
2318 width = qMax(d->verticalHeader->minimumWidth(), d->verticalHeader->sizeHint().width());
2319 width = qMin(width, d->verticalHeader->maximumWidth());
2322 if (!d->horizontalHeader->isHidden()) {
2323 height = qMax(d->horizontalHeader->minimumHeight(), d->horizontalHeader->sizeHint().height());
2324 height = qMin(height, d->horizontalHeader->maximumHeight());
2326 bool reverse = isRightToLeft();
2328 setViewportMargins(0, height, width, 0);
2330 setViewportMargins(width, height, 0, 0);
2334 QRect vg = d->viewport->geometry();
2336 int verticalLeft = reverse ? vg.right() + 1 : (vg.left() - width);
2337 d->verticalHeader->setGeometry(verticalLeft, vg.top(), width, vg.height());
2338 if (d->verticalHeader->isHidden())
2339 QMetaObject::invokeMethod(d->verticalHeader,
"updateGeometries");
2341 int horizontalTop = vg.top() - height;
2342 d->horizontalHeader->setGeometry(vg.left(), horizontalTop, vg.width(), height);
2343 if (d->horizontalHeader->isHidden())
2344 QMetaObject::invokeMethod(d->horizontalHeader,
"updateGeometries");
2346#if QT_CONFIG(abstractbutton)
2348 if (d->horizontalHeader->isHidden() || d->verticalHeader->isHidden()) {
2349 d->cornerWidget->setHidden(
true);
2351 d->cornerWidget->setHidden(
false);
2352 d->cornerWidget->setGeometry(verticalLeft, horizontalTop, width, height);
2359 QSize vsize = d->viewport->size();
2360 QSize max = maximumViewportSize();
2361 const int horizontalLength = d->horizontalHeader->length();
2362 const int verticalLength = d->verticalHeader->length();
2363 if (max.width() >= horizontalLength && max.height() >= verticalLength)
2367 const int columnCount = d->horizontalHeader->count();
2368 const int viewportWidth = vsize.width();
2369 int columnsInViewport = 0;
2370 for (
int width = 0, column = columnCount - 1; column >= 0; --column) {
2371 int logical = d->horizontalHeader->logicalIndex(column);
2372 if (!d->horizontalHeader->isSectionHidden(logical)) {
2373 width += d->horizontalHeader->sectionSize(logical);
2374 if (width > viewportWidth)
2376 ++columnsInViewport;
2379 columnsInViewport = qMax(columnsInViewport, 1);
2381 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
2382 const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();
2383 horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport);
2384 horizontalScrollBar()->setPageStep(columnsInViewport);
2385 if (columnsInViewport >= visibleColumns)
2386 d->horizontalHeader->setOffset(0);
2387 horizontalScrollBar()->setSingleStep(1);
2389 horizontalScrollBar()->setPageStep(vsize.width());
2390 horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());
2391 horizontalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
2395 const int rowCount = d->verticalHeader->count();
2396 const int viewportHeight = vsize.height();
2397 int rowsInViewport = 0;
2398 for (
int height = 0, row = rowCount - 1; row >= 0; --row) {
2399 int logical = d->verticalHeader->logicalIndex(row);
2400 if (!d->verticalHeader->isSectionHidden(logical)) {
2401 height += d->verticalHeader->sectionSize(logical);
2402 if (height > viewportHeight)
2407 rowsInViewport = qMax(rowsInViewport, 1);
2409 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
2410 const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();
2411 verticalScrollBar()->setRange(0, visibleRows - rowsInViewport);
2412 verticalScrollBar()->setPageStep(rowsInViewport);
2413 if (rowsInViewport >= visibleRows)
2414 d->verticalHeader->setOffset(0);
2415 verticalScrollBar()->setSingleStep(1);
2417 verticalScrollBar()->setPageStep(vsize.height());
2418 verticalScrollBar()->setRange(0, verticalLength - vsize.height());
2419 verticalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
2421 d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
2423 d->geometryRecursionBlock =
false;
2424 QAbstractItemView::updateGeometries();
2441int QTableView::sizeHintForRow(
int row)
const
2443 Q_D(
const QTableView);
2449 const int maximumProcessCols = d->verticalHeader->resizeContentsPrecision();
2452 int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
2453 int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
2455 right = d->model->columnCount(d->root) - 1;
2457 QStyleOptionViewItem option;
2458 initViewItemOption(&option);
2462 int columnsProcessed = 0;
2464 for (; column <= right; ++column) {
2465 int logicalColumn = d->horizontalHeader->logicalIndex(column);
2466 if (d->horizontalHeader->isSectionHidden(logicalColumn))
2468 index = d->model->index(row, logicalColumn, d->root);
2469 hint = d->heightHintForIndex(index, hint, option);
2472 if (columnsProcessed == maximumProcessCols)
2476 const int actualRight = d->model->columnCount(d->root) - 1;
2478 int idxRight = column - 1;
2480 if (maximumProcessCols == 0 || actualRight < idxLeft)
2481 columnsProcessed = maximumProcessCols;
2483 while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {
2484 int logicalIdx = -1;
2486 if ((columnsProcessed % 2 && idxLeft > 0) || idxRight == actualRight) {
2487 while (idxLeft > 0) {
2489 int logcol = d->horizontalHeader->logicalIndex(idxLeft);
2490 if (d->horizontalHeader->isSectionHidden(logcol))
2492 logicalIdx = logcol;
2496 while (idxRight < actualRight) {
2498 int logcol = d->horizontalHeader->logicalIndex(idxRight);
2499 if (d->horizontalHeader->isSectionHidden(logcol))
2501 logicalIdx = logcol;
2505 if (logicalIdx >= 0) {
2506 index = d->model->index(row, logicalIdx, d->root);
2507 hint = d->heightHintForIndex(index, hint, option);
2512 return d->showGrid ? hint + 1 : hint;
2530int QTableView::sizeHintForColumn(
int column)
const
2532 Q_D(
const QTableView);
2538 const int maximumProcessRows = d->horizontalHeader->resizeContentsPrecision();
2540 int top = qMax(0, d->verticalHeader->visualIndexAt(0));
2541 int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
2542 if (!isVisible() || bottom == -1)
2543 bottom = d->model->rowCount(d->root) - 1;
2545 QStyleOptionViewItem option;
2546 initViewItemOption(&option);
2549 int rowsProcessed = 0;
2552 for (; row <= bottom; ++row) {
2553 int logicalRow = d->verticalHeader->logicalIndex(row);
2554 if (d->verticalHeader->isSectionHidden(logicalRow))
2556 index = d->model->index(logicalRow, column, d->root);
2558 hint = d->widthHintForIndex(index, hint, option);
2560 if (rowsProcessed == maximumProcessRows)
2564 const int actualBottom = d->model->rowCount(d->root) - 1;
2566 int idxBottom = row - 1;
2568 if (maximumProcessRows == 0 || actualBottom < idxTop)
2569 rowsProcessed = maximumProcessRows;
2571 while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {
2572 int logicalIdx = -1;
2574 if ((rowsProcessed % 2 && idxTop > 0) || idxBottom == actualBottom) {
2575 while (idxTop > 0) {
2577 int logrow = d->verticalHeader->logicalIndex(idxTop);
2578 if (d->verticalHeader->isSectionHidden(logrow))
2580 logicalIdx = logrow;
2584 while (idxBottom < actualBottom) {
2586 int logrow = d->verticalHeader->logicalIndex(idxBottom);
2587 if (d->verticalHeader->isSectionHidden(logrow))
2589 logicalIdx = logrow;
2593 if (logicalIdx >= 0) {
2594 index = d->model->index(logicalIdx, column, d->root);
2595 hint = d->widthHintForIndex(index, hint, option);
2600 return d->showGrid ? hint + 1 : hint;
2927void QTableView::scrollTo(
const QModelIndex &index, ScrollHint hint)
2932 if (!d->isIndexValid(index)
2933 || (d->model->parent(index) != d->root)
2934 || isRowHidden(index.row()) || isColumnHidden(index.column()))
2937 QSpanCollection::Span span;
2939 span = d->span(index.row(), index.column());
2943 int viewportWidth = d->viewport->width();
2944 int horizontalOffset = d->horizontalHeader->offset();
2945 int horizontalPosition = d->horizontalHeader->sectionPosition(index.column());
2946 int horizontalIndex = d->horizontalHeader->visualIndex(index.column());
2947 int cellWidth = d->hasSpans()
2948 ? d->columnSpanWidth(index.column(), span.width())
2949 : d->horizontalHeader->sectionSize(index.column());
2951 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
2953 bool positionAtLeft = (horizontalPosition - horizontalOffset < 0);
2954 bool positionAtRight = (horizontalPosition - horizontalOffset + cellWidth > viewportWidth);
2956 if (hint == PositionAtCenter || positionAtRight) {
2957 int w = (hint == PositionAtCenter ? viewportWidth / 2 : viewportWidth);
2959 while (horizontalIndex > 0) {
2960 x += columnWidth(d->horizontalHeader->logicalIndex(horizontalIndex-1));
2967 if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {
2968 int hiddenSections = 0;
2969 if (d->horizontalHeader->sectionsHidden()) {
2970 for (
int s = horizontalIndex - 1; s >= 0; --s) {
2971 int column = d->horizontalHeader->logicalIndex(s);
2972 if (d->horizontalHeader->isSectionHidden(column))
2976 horizontalScrollBar()->setValue(horizontalIndex - hiddenSections);
2980 if (hint == PositionAtCenter) {
2981 horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
2983 if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
2984 horizontalScrollBar()->setValue(horizontalPosition);
2985 else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
2986 horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
2992 int viewportHeight = d->viewport->height();
2993 int verticalOffset = d->verticalHeader->offset();
2994 int verticalPosition = d->verticalHeader->sectionPosition(index.row());
2995 int verticalIndex = d->verticalHeader->visualIndex(index.row());
2996 int cellHeight = d->hasSpans()
2997 ? d->rowSpanHeight(index.row(), span.height())
2998 : d->verticalHeader->sectionSize(index.row());
3000 if (verticalPosition - verticalOffset < 0 || cellHeight > viewportHeight) {
3001 if (hint == EnsureVisible)
3002 hint = PositionAtTop;
3003 }
else if (verticalPosition - verticalOffset + cellHeight > viewportHeight) {
3004 if (hint == EnsureVisible)
3005 hint = PositionAtBottom;
3008 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
3010 if (hint == PositionAtBottom || hint == PositionAtCenter) {
3011 int h = (hint == PositionAtCenter ? viewportHeight / 2 : viewportHeight);
3013 while (verticalIndex > 0) {
3014 int row = d->verticalHeader->logicalIndex(verticalIndex - 1);
3015 y += d->verticalHeader->sectionSize(row);
3022 if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {
3023 int hiddenSections = 0;
3024 if (d->verticalHeader->sectionsHidden()) {
3025 for (
int s = verticalIndex - 1; s >= 0; --s) {
3026 int row = d->verticalHeader->logicalIndex(s);
3027 if (d->verticalHeader->isSectionHidden(row))
3031 verticalScrollBar()->setValue(verticalIndex - hiddenSections);
3035 if (hint == PositionAtTop) {
3036 verticalScrollBar()->setValue(verticalPosition);
3037 }
else if (hint == PositionAtBottom) {
3038 verticalScrollBar()->setValue(verticalPosition - viewportHeight + cellHeight);
3039 }
else if (hint == PositionAtCenter) {
3040 verticalScrollBar()->setValue(verticalPosition - ((viewportHeight - cellHeight) / 2));
3080void QTableView::timerEvent(QTimerEvent *event)
3084 if (event->id() == d->columnResizeTimer.id()) {
3085 const int oldScrollMax = horizontalScrollBar()->maximum();
3086 if (horizontalHeader()->d_func()->state != QHeaderViewPrivate::ResizeSection) {
3088 d->columnResizeTimer.stop();
3090 updateEditorGeometries();
3094 int viewportHeight = d->viewport->height();
3095 int viewportWidth = d->viewport->width();
3096 if (d->hasSpans() || horizontalScrollBar()->value() == oldScrollMax) {
3097 rect = QRect(0, 0, viewportWidth, viewportHeight);
3099 for (
int i = d->columnsToUpdate.size()-1; i >= 0; --i) {
3100 int column = d->columnsToUpdate.at(i);
3101 int x = columnViewportPosition(column);
3102 if (isRightToLeft())
3103 rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);
3105 rect |= QRect(x, 0, viewportWidth - x, viewportHeight);
3109 d->viewport->update(rect.normalized());
3110 d->columnsToUpdate.clear();
3113 if (event->id() == d->rowResizeTimer.id()) {
3114 const int oldScrollMax = verticalScrollBar()->maximum();
3115 if (verticalHeader()->d_func()->state != QHeaderViewPrivate::ResizeSection) {
3117 d->rowResizeTimer.stop();
3119 updateEditorGeometries();
3122 int viewportHeight = d->viewport->height();
3123 int viewportWidth = d->viewport->width();
3125 if (d->hasSpans() || verticalScrollBar()->value() == oldScrollMax) {
3128 top = viewportHeight;
3129 for (
int i = d->rowsToUpdate.size()-1; i >= 0; --i) {
3130 int y = rowViewportPosition(d->rowsToUpdate.at(i));
3135 d->viewport->update(QRect(0, top, viewportWidth, viewportHeight - top));
3136 d->rowsToUpdate.clear();
3139 QAbstractItemView::timerEvent(event);
3495void QTableViewPrivate::selectRow(
int row,
bool anchor)
3499 if (q->selectionBehavior() == QTableView::SelectColumns
3500 || (q->selectionMode() == QTableView::SingleSelection
3501 && q->selectionBehavior() == QTableView::SelectItems))
3504 if (row >= 0 && row < model->rowCount(root)) {
3505 int column = horizontalHeader->logicalIndexAt(q->isRightToLeft() ? viewport->width() : 0);
3506 QModelIndex index = model->index(row, column, root);
3507 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
3511 const auto startIndex = currentSelectionStartIndex;
3512 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
3513 currentSelectionStartIndex = startIndex;
3516 if ((anchor && !(command & QItemSelectionModel::Current))
3517 || (q->selectionMode() == QTableView::SingleSelection))
3518 currentSelectionStartIndex = model->index(row, column, root);
3520 if (q->selectionMode() != QTableView::SingleSelection
3521 && command.testFlag(QItemSelectionModel::Toggle)) {
3523 ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows(column).contains(index)
3524 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
3525 command &= ~QItemSelectionModel::Toggle;
3526 command |= ctrlDragSelectionFlag;
3528 command |= QItemSelectionModel::Current;
3531 const auto rowSectionAnchor = currentSelectionStartIndex.row();
3532 QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);
3533 QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);
3534 if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {
3535 q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows);
3537 selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows);
3542void QTableViewPrivate::selectColumn(
int column,
bool anchor)
3546 if (q->selectionBehavior() == QTableView::SelectRows
3547 || (q->selectionMode() == QTableView::SingleSelection
3548 && q->selectionBehavior() == QTableView::SelectItems))
3551 if (column >= 0 && column < model->columnCount(root)) {
3552 int row = verticalHeader->logicalIndexAt(0);
3553 QModelIndex index = model->index(row, column, root);
3554 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
3558 const auto startIndex = currentSelectionStartIndex;
3559 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
3560 currentSelectionStartIndex = startIndex;
3563 if ((anchor && !(command & QItemSelectionModel::Current))
3564 || (q->selectionMode() == QTableView::SingleSelection))
3565 currentSelectionStartIndex = model->index(row, column, root);
3567 if (q->selectionMode() != QTableView::SingleSelection
3568 && command.testFlag(QItemSelectionModel::Toggle)) {
3570 ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns(row).contains(index)
3571 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
3572 command &= ~QItemSelectionModel::Toggle;
3573 command |= ctrlDragSelectionFlag;
3575 command |= QItemSelectionModel::Current;
3578 const auto columnSectionAnchor = currentSelectionStartIndex.column();
3579 QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);
3580 QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);
3581 if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {
3582 q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns);
3584 selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns);