312void QSpanCollection::updateRemovedRows(
int start,
int end)
314#ifdef DEBUG_SPAN_UPDATE
315 qDebug() << start << end << Qt::endl << index;
320 SpanList spansToBeDeleted;
321 int delta = end - start + 1;
322#ifdef DEBUG_SPAN_UPDATE
325 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
327#ifdef DEBUG_SPAN_UPDATE
328 qDebug() << span << *span;
330 if (span->m_bottom < start) {
334 if (span->m_top < start) {
335 if (span->m_bottom <= end)
336 span->m_bottom = start - 1;
338 span->m_bottom -= delta;
340 if (span->m_bottom > end) {
341 if (span->m_top <= end)
344 span->m_top -= delta;
345 span->m_bottom -= delta;
347 span->will_be_deleted =
true;
350 if (span->m_top == span->m_bottom && span->m_left == span->m_right)
351 span->will_be_deleted =
true;
352 if (span->will_be_deleted) {
353 spansToBeDeleted.push_back(span);
354 it = spans.erase(it);
360#ifdef DEBUG_SPAN_UPDATE
365 qDeleteAll(spansToBeDeleted);
370 Index::iterator it_y = index.end();
374 SubIndex &subindex = it_y.value();
376 if (cleanSpanSubIndex(subindex, y))
377 it_y = index.erase(it_y);
378 }
else if (y >= start && y <= end) {
379 bool span_at_start =
false;
380 SubIndex spansToBeMoved;
381 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {
382 Span *span = it.value();
383 if (span->will_be_deleted)
385 if (!span_at_start && span->m_top == start)
386 span_at_start =
true;
387 spansToBeMoved.insert(it.key(), span);
390 if (y == start && span_at_start)
393 it_y = index.erase(it_y);
396 Index::iterator it_start;
400 it_start = index.find(-start);
401 if (it_start == index.end())
402 it_start = index.insert(-start, SubIndex());
404 SubIndex &start_subindex = it_start.value();
405 for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)
406 start_subindex.insert(it.key(), it.value());
410 Index::iterator it_top = index.find(-y + delta);
411 if (it_top == index.end())
412 it_top = index.insert(-y + delta, SubIndex());
413 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
414 Span *span = it.value();
415 if (!span->will_be_deleted)
416 it_top.value().insert(it.key(), span);
420 index.insert(-y + delta, subindex);
422 it_y = index.erase(it_y);
424 }
while (it_y != index.begin());
426#ifdef DEBUG_SPAN_UPDATE
429 qDebug() << spansToBeDeleted;
431 qDeleteAll(spansToBeDeleted);
658QRect QTableViewPrivate::intersectedRect(
const QRect rect,
const QModelIndex &topLeft,
const QModelIndex &bottomRight)
const
660 Q_Q(
const QTableView);
662 using minMaxPair = std::pair<
int,
int>;
663 const auto calcMinMax = [q](QHeaderView *hdr,
int startIdx,
int endIdx, minMaxPair bounds) -> minMaxPair
665 minMaxPair ret(std::numeric_limits<
int>::max(), std::numeric_limits<
int>::min());
666 if (hdr->sectionsMoved()) {
667 for (
int i = startIdx; i <= endIdx; ++i) {
668 const int start = hdr->sectionViewportPosition(i);
669 const int end = start + hdr->sectionSize(i);
670 ret.first = std::min(start, ret.first);
671 ret.second = std::max(end, ret.second);
672 if (ret.first <= bounds.first && ret.second >= bounds.second)
676 if (q->isRightToLeft() && q->horizontalHeader() == hdr)
677 std::swap(startIdx, endIdx);
678 ret.first = hdr->sectionViewportPosition(startIdx);
679 ret.second = hdr->sectionViewportPosition(endIdx) +
680 hdr->sectionSize(endIdx);
685 const auto yVals = calcMinMax(verticalHeader, topLeft.row(), bottomRight.row(),
686 minMaxPair(rect.top(), rect.bottom()));
687 if (yVals.first == yVals.second)
691 const QRect colRect(QPoint(rect.left(), yVals.first),
692 QPoint(rect.right(), yVals.second));
693 const QRect intersected = rect.intersected(colRect);
694 if (intersected.isNull())
697 const auto xVals = calcMinMax(horizontalHeader, topLeft.column(), bottomRight.column(),
698 minMaxPair(rect.left(), rect.right()));
699 const QRect updateRect(QPoint(xVals.first, yVals.first),
700 QPoint(xVals.second, yVals.second));
701 return rect.intersected(updateRect);
891void QTableViewPrivate::drawAndClipSpans(
const QRegion &area, QPainter *painter,
892 const QStyleOptionViewItem &option, QBitArray *drawn,
893 int firstVisualRow,
int lastVisualRow,
int firstVisualColumn,
int lastVisualColumn)
895 Q_Q(
const QTableView);
896 bool alternateBase =
false;
897 QRegion region = viewport->rect();
899 QSet<QSpanCollection::Span *> visibleSpans;
900 bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved();
903 visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),
904 lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);
919 const auto spanList = spans.spans;
920 for (QSpanCollection::Span *span : spanList) {
921 const int spanVisualLeft = visualColumn(span->left());
922 const int spanVisualTop = visualRow(span->top());
923 const int spanVisualRight = spanVisualLeft + span->width() - 1;
924 const int spanVisualBottom = spanVisualTop + span->height() - 1;
925 if ((spanVisualLeft <= lastVisualColumn && spanVisualRight >= firstVisualColumn)
926 && (spanVisualTop <= lastVisualRow && spanVisualBottom >= firstVisualRow))
927 visibleSpans.insert(span);
931 for (QSpanCollection::Span *span : std::as_const(visibleSpans)) {
932 int row = span->top();
933 int col = span->left();
934 QModelIndex index = model->index(row, col, root);
935 if (!index.isValid())
937 QRect rect = visualSpanRect(*span);
938 rect.translate(scrollDelayOffset);
939 if (!area.intersects(rect))
941 QStyleOptionViewItem opt = option;
943 alternateBase = alternatingColors && (span->top() & 1);
944 opt.features.setFlag(QStyleOptionViewItem::Alternate, alternateBase);
945 drawCell(painter, opt, index);
949 if (horizontalHeader->visualIndex(row) == 0)
950 rect.setTop(rect.top() + 1);
951 if (verticalHeader->visualIndex(row) == 0) {
952 if (q->isLeftToRight())
953 rect.setLeft(rect.left() + 1);
955 rect.setRight(rect.right() - 1);
959 for (
int r = span->top(); r <= span->bottom(); ++r) {
960 const int vr = visualRow(r);
961 if (vr < firstVisualRow || vr > lastVisualRow)
963 for (
int c = span->left(); c <= span->right(); ++c) {
964 const int vc = visualColumn(c);
965 if (vc < firstVisualColumn || vc > lastVisualColumn)
967 drawn->setBit((vr - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
968 + vc - firstVisualColumn);
973 painter->setClipRegion(region);
1368void QTableView::setHorizontalHeader(QHeaderView *header)
1372 if (!header || header == d->horizontalHeader)
1374 for (
const QMetaObject::Connection &connection : d->horHeaderConnections)
1375 disconnect(connection);
1376 if (d->horizontalHeader && d->horizontalHeader->parent() ==
this)
1377 delete d->horizontalHeader;
1378 d->horizontalHeader = header;
1379 d->horizontalHeader->setParent(
this);
1380 d->horizontalHeader->setFirstSectionMovable(
true);
1381 if (!d->horizontalHeader->model()) {
1382 d->horizontalHeader->setModel(d->model);
1383 if (d->selectionModel)
1384 d->horizontalHeader->setSelectionModel(d->selectionModel);
1387 d->horHeaderConnections = {
1388 connect(d->horizontalHeader,&QHeaderView::sectionResized,
1389 this, &QTableView::columnResized),
1390 connect(d->horizontalHeader, &QHeaderView::sectionMoved,
1391 this, &QTableView::columnMoved),
1392 connect(d->horizontalHeader, &QHeaderView::sectionCountChanged,
1393 this, &QTableView::columnCountChanged),
1394 connect(d->horizontalHeader, &QHeaderView::sectionHandleDoubleClicked,
1395 this, &QTableView::resizeColumnToContents),
1396 connect(d->horizontalHeader, &QHeaderView::geometriesChanged,
1397 this, &QTableView::updateGeometries),
1400 setSortingEnabled(d->sortingEnabled);
1408void QTableView::setVerticalHeader(QHeaderView *header)
1412 if (!header || header == d->verticalHeader)
1414 for (
const QMetaObject::Connection &connection : d->verHeaderConnections)
1415 disconnect(connection);
1416 if (d->verticalHeader && d->verticalHeader->parent() ==
this)
1417 delete d->verticalHeader;
1418 d->verticalHeader = header;
1419 d->verticalHeader->setParent(
this);
1420 d->verticalHeader->setFirstSectionMovable(
true);
1421 if (!d->verticalHeader->model()) {
1422 d->verticalHeader->setModel(d->model);
1423 if (d->selectionModel)
1424 d->verticalHeader->setSelectionModel(d->selectionModel);
1427 d->verHeaderConnections = {
1428 connect(d->verticalHeader, &QHeaderView::sectionResized,
1429 this, &QTableView::rowResized),
1430 connect(d->verticalHeader, &QHeaderView::sectionMoved,
1431 this, &QTableView::rowMoved),
1432 connect(d->verticalHeader, &QHeaderView::sectionCountChanged,
1433 this, &QTableView::rowCountChanged),
1434 connect(d->verticalHeader, &QHeaderView::sectionPressed,
1435 this, &QTableView::selectRow),
1436 connect(d->verticalHeader, &QHeaderView::sectionHandleDoubleClicked,
1437 this, &QTableView::resizeRowToContents),
1438 connect(d->verticalHeader, &QHeaderView::geometriesChanged,
1439 this, &QTableView::updateGeometries),
1440 connect(d->verticalHeader, &QHeaderView::sectionEntered,
1441 this, [d](
int row) { d->selectRow(row,
false); })
1500void QTableView::paintEvent(QPaintEvent *event)
1504 QStyleOptionViewItem option;
1505 initViewItemOption(&option);
1506 const QPoint offset = d->scrollDelayOffset;
1507 const bool showGrid = d->showGrid;
1508 const int gridSize = showGrid ? 1 : 0;
1509 const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option,
this);
1510 const QColor gridColor = QColor::fromRgba(
static_cast<QRgb>(gridHint));
1511 const QPen gridPen = QPen(gridColor, 1, d->gridStyle);
1512 const QHeaderView *verticalHeader = d->verticalHeader;
1513 const QHeaderView *horizontalHeader = d->horizontalHeader;
1514 const bool alternate = d->alternatingColors;
1515 const bool rightToLeft = isRightToLeft();
1517 QPainter painter(d->viewport);
1520 if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate)
1523 const int x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
1524 const int y = verticalHeader->length() - verticalHeader->offset() - 1;
1528 int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
1529 int lastVisualRow = verticalHeader->visualIndexAt(verticalHeader->height());
1530 if (lastVisualRow == -1)
1531 lastVisualRow = d->model->rowCount(d->root) - 1;
1533 int firstVisualColumn = horizontalHeader->visualIndexAt(0);
1534 int lastVisualColumn = horizontalHeader->visualIndexAt(horizontalHeader->width());
1536 qSwap(firstVisualColumn, lastVisualColumn);
1537 if (firstVisualColumn == -1)
1538 firstVisualColumn = 0;
1539 if (lastVisualColumn == -1)
1540 lastVisualColumn = horizontalHeader->count() - 1;
1542 QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
1544 const QRegion region = event->region().translated(offset);
1546 if (d->hasSpans()) {
1547 d->drawAndClipSpans(region, &painter, option, &drawn,
1548 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
1551 for (QRect dirtyArea : region) {
1552 dirtyArea.setBottom(qMin(dirtyArea.bottom(),
int(y)));
1554 dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() -
int(x)));
1556 dirtyArea.setRight(qMin(dirtyArea.right(),
int(x)));
1559 if (!dirtyArea.isValid())
1563 int left = horizontalHeader->visualIndexAt(dirtyArea.left());
1564 int right = horizontalHeader->visualIndexAt(dirtyArea.right());
1567 if (left == -1) left = 0;
1568 if (right == -1) right = horizontalHeader->count() - 1;
1571 int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom());
1572 if (bottom == -1) bottom = verticalHeader->count() - 1;
1574 bool alternateBase =
false;
1575 if (alternate && verticalHeader->sectionsHidden()) {
1576 const int verticalOffset = verticalHeader->offset();
1577 int row = verticalHeader->logicalIndex(top);
1579 ((y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom);
1581 row = verticalHeader->logicalIndex(top);
1582 if (alternate && !verticalHeader->isSectionHidden(row))
1583 alternateBase = !alternateBase;
1586 top = verticalHeader->visualIndexAt(dirtyArea.top());
1587 alternateBase = (top & 1) && alternate;
1589 if (top == -1 || top > bottom)
1593 for (
int visualRowIndex = top; visualRowIndex <= bottom; ++visualRowIndex) {
1594 int row = verticalHeader->logicalIndex(visualRowIndex);
1595 if (verticalHeader->isSectionHidden(row))
1597 int rowY = rowViewportPosition(row);
1599 int rowh = rowHeight(row) - gridSize;
1602 for (
int visualColumnIndex = left; visualColumnIndex <= right; ++visualColumnIndex) {
1603 int currentBit = (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1)
1604 + visualColumnIndex - firstVisualColumn;
1606 if (currentBit < 0 || currentBit >= drawn.size() || drawn.testBit(currentBit))
1608 drawn.setBit(currentBit);
1610 int col = horizontalHeader->logicalIndex(visualColumnIndex);
1611 if (horizontalHeader->isSectionHidden(col))
1613 int colp = columnViewportPosition(col);
1615 int colw = columnWidth(col) - gridSize;
1617 const QModelIndex index = d->model->index(row, col, d->root);
1618 if (index.isValid()) {
1619 option.rect = QRect(colp + (showGrid && rightToLeft ? 1 : 0), rowY, colw, rowh);
1622 option.features |= QStyleOptionViewItem::Alternate;
1624 option.features &= ~QStyleOptionViewItem::Alternate;
1626 d->drawCell(&painter, option, index);
1629 alternateBase = !alternateBase && alternate;
1634 while (verticalHeader->isSectionHidden(verticalHeader->logicalIndex(bottom))) --bottom;
1635 QPen old = painter.pen();
1636 painter.setPen(gridPen);
1638 for (
int visualIndex = top; visualIndex <= bottom; ++visualIndex) {
1639 int row = verticalHeader->logicalIndex(visualIndex);
1640 if (verticalHeader->isSectionHidden(row))
1642 int rowY = rowViewportPosition(row);
1644 int rowh = rowHeight(row) - gridSize;
1645 QLineF line(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
1646 painter.drawLine(line.translated(0.5, 0.5));
1650 for (
int h = left; h <= right; ++h) {
1651 int col = horizontalHeader->logicalIndex(h);
1652 if (horizontalHeader->isSectionHidden(col))
1654 int colp = columnViewportPosition(col);
1657 colp += columnWidth(col) - gridSize;
1658 QLineF line(colp, dirtyArea.top(), colp, dirtyArea.bottom());
1659 painter.drawLine(line.translated(0.5, 0.5));
1661 const bool drawWhenHidden = style()->styleHint(QStyle::SH_Table_AlwaysDrawLeftTopGridLines,
1663 if (drawWhenHidden && horizontalHeader->isHidden()) {
1664 const int row = verticalHeader->logicalIndex(top);
1665 if (!verticalHeader->isSectionHidden(row)) {
1666 const int rowY = rowViewportPosition(row) + offset.y();
1667 if (rowY == dirtyArea.top())
1668 painter.drawLine(dirtyArea.left(), rowY, dirtyArea.right(), rowY);
1671 if (drawWhenHidden && verticalHeader->isHidden()) {
1672 const int col = horizontalHeader->logicalIndex(left);
1673 if (!horizontalHeader->isSectionHidden(col)) {
1674 int colX = columnViewportPosition(col) + offset.x();
1675 if (!isLeftToRight())
1676 colX += columnWidth(left) - 1;
1677 if (isLeftToRight() && colX == dirtyArea.left())
1678 painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
1679 if (!isLeftToRight() && colX == dirtyArea.right())
1680 painter.drawLine(colX, dirtyArea.top(), colX, dirtyArea.bottom());
1683 painter.setPen(old);
1687#if QT_CONFIG(draganddrop)
1689 d->paintDropIndicator(&painter);
1750QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
1753 Q_UNUSED(modifiers);
1755 int bottom = d->model->rowCount(d->root) - 1;
1757 while (bottom >= 0 && isRowHidden(d->logicalRow(bottom)))
1760 int right = d->model->columnCount(d->root) - 1;
1762 while (right >= 0 && isColumnHidden(d->logicalColumn(right)))
1765 if (bottom == -1 || right == -1)
1766 return QModelIndex();
1768 QModelIndex current = currentIndex();
1770 if (!current.isValid()) {
1773 while (column < right && isColumnHidden(d->logicalColumn(column)))
1775 while (isRowHidden(d->logicalRow(row)) && row < bottom)
1777 d->visualCursor = QPoint(column, row);
1778 return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);
1782 QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));
1783 if (visualCurrent != d->visualCursor) {
1784 if (d->hasSpans()) {
1785 QSpanCollection::Span span = d->span(current.row(), current.column());
1786 if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()
1787 || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())
1788 d->visualCursor = visualCurrent;
1790 d->visualCursor = visualCurrent;
1794 int visualRow = d->visualCursor.y();
1795 if (visualRow > bottom)
1797 Q_ASSERT(visualRow != -1);
1798 int visualColumn = d->visualCursor.x();
1799 if (visualColumn > right)
1800 visualColumn = right;
1801 Q_ASSERT(visualColumn != -1);
1803 if (isRightToLeft()) {
1804 if (cursorAction == MoveLeft)
1805 cursorAction = MoveRight;
1806 else if (cursorAction == MoveRight)
1807 cursorAction = MoveLeft;
1810 switch (cursorAction) {
1812 int originalRow = visualRow;
1813#ifdef QT_KEYPAD_NAVIGATION
1814 if (QApplicationPrivate::keypadNavigationEnabled() && visualRow == 0)
1815 visualRow = d->visualRow(model()->rowCount() - 1) + 1;
1818 int r = d->logicalRow(visualRow);
1819 int c = d->logicalColumn(visualColumn);
1820 if (r != -1 && d->hasSpans()) {
1821 QSpanCollection::Span span = d->span(r, c);
1822 if (span.width() > 1 || span.height() > 1)
1823 visualRow = d->visualRow(span.top());
1825 while (visualRow >= 0) {
1827 r = d->logicalRow(visualRow);
1828 c = d->logicalColumn(visualColumn);
1829 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
1833 visualRow = originalRow;
1837 int originalRow = visualRow;
1838 if (d->hasSpans()) {
1839 QSpanCollection::Span span = d->span(current.row(), current.column());
1840 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
1842#ifdef QT_KEYPAD_NAVIGATION
1843 if (QApplicationPrivate::keypadNavigationEnabled() && visualRow >= bottom)
1846 int r = d->logicalRow(visualRow);
1847 int c = d->logicalColumn(visualColumn);
1848 if (r != -1 && d->hasSpans()) {
1849 QSpanCollection::Span span = d->span(r, c);
1850 if (span.width() > 1 || span.height() > 1)
1851 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
1853 while (visualRow <= bottom) {
1855 r = d->logicalRow(visualRow);
1856 c = d->logicalColumn(visualColumn);
1857 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
1860 if (visualRow > bottom)
1861 visualRow = originalRow;
1866 int originalRow = visualRow;
1867 int originalColumn = visualColumn;
1868 bool firstTime =
true;
1869 bool looped =
false;
1870 bool wrapped =
false;
1872 int r = d->logicalRow(visualRow);
1873 int c = d->logicalColumn(visualColumn);
1874 if (firstTime && c != -1 && d->hasSpans()) {
1876 QSpanCollection::Span span = d->span(r, c);
1877 if (span.width() > 1 || span.height() > 1)
1878 visualColumn = d->visualColumn(span.left());
1880 while (visualColumn >= 0) {
1882 r = d->logicalRow(visualRow);
1883 c = d->logicalColumn(visualColumn);
1884 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
1886 if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {
1891 if (cursorAction == MoveLeft || visualColumn >= 0)
1893 visualColumn = right + 1;
1894 if (visualRow == 0) {
1901 if (visualColumn < 0)
1902 visualColumn = originalColumn;
1907 int originalRow = visualRow;
1908 int originalColumn = visualColumn;
1909 bool firstTime =
true;
1910 bool looped =
false;
1911 bool wrapped =
false;
1913 int r = d->logicalRow(visualRow);
1914 int c = d->logicalColumn(visualColumn);
1915 if (firstTime && c != -1 && d->hasSpans()) {
1917 QSpanCollection::Span span = d->span(r, c);
1918 if (span.width() > 1 || span.height() > 1)
1919 visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
1921 while (visualColumn <= right) {
1923 r = d->logicalRow(visualRow);
1924 c = d->logicalColumn(visualColumn);
1925 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
1927 if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {
1932 if (cursorAction == MoveRight || visualColumn <= right)
1935 if (visualRow == bottom) {
1942 if (visualColumn > right)
1943 visualColumn = originalColumn;
1947 visualColumn = d->nextActiveVisualColumn(visualRow, 0, right,
1948 QTableViewPrivate::SearchDirection::Increasing);
1949 if (modifiers & Qt::ControlModifier)
1950 visualRow = d->nextActiveVisualRow(0, visualColumn, bottom,
1951 QTableViewPrivate::SearchDirection::Increasing);
1954 visualColumn = d->nextActiveVisualColumn(visualRow, right, -1,
1955 QTableViewPrivate::SearchDirection::Decreasing);
1956 if (modifiers & Qt::ControlModifier)
1957 visualRow = d->nextActiveVisualRow(bottom, visualColumn, -1,
1958 QTableViewPrivate::SearchDirection::Decreasing);
1961 int newLogicalRow = rowAt(visualRect(current).bottom() - d->viewport->height());
1962 int visualRow = (newLogicalRow == -1 ? 0 : d->visualRow(newLogicalRow));
1963 visualRow = d->nextActiveVisualRow(visualRow, current.column(), bottom,
1964 QTableViewPrivate::SearchDirection::Increasing);
1965 newLogicalRow = d->logicalRow(visualRow);
1966 return d->model->index(newLogicalRow, current.column(), d->root);
1968 case MovePageDown: {
1969 int newLogicalRow = rowAt(visualRect(current).top() + d->viewport->height());
1970 int visualRow = (newLogicalRow == -1 ? bottom : d->visualRow(newLogicalRow));
1971 visualRow = d->nextActiveVisualRow(visualRow, current.column(), -1,
1972 QTableViewPrivate::SearchDirection::Decreasing);
1973 newLogicalRow = d->logicalRow(visualRow);
1974 return d->model->index(newLogicalRow, current.column(), d->root);
1977 d->visualCursor = QPoint(visualColumn, visualRow);
1978 int logicalRow = d->logicalRow(visualRow);
1979 int logicalColumn = d->logicalColumn(visualColumn);
1980 if (!d->model->hasIndex(logicalRow, logicalColumn, d->root))
1981 return QModelIndex();
1983 QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
1984 if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) {
1985 if (d->hasSpans()) {
1986 QSpanCollection::Span span = d->span(result.row(), result.column());
1987 if (span.width() > 1 || span.height() > 1) {
1988 result = d->model->sibling(span.top(), span.left(), result);
1994 return QModelIndex();
2004void QTableView::setSelection(
const QRect &rect, QItemSelectionModel::SelectionFlags command)
2007 QModelIndex tl = indexAt(QPoint(isRightToLeft() ? qMax(rect.left(), rect.right())
2008 : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom())));
2009 QModelIndex br = indexAt(QPoint(isRightToLeft() ? qMin(rect.left(), rect.right()) :
2010 qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom())));
2011 if (!d->selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br))
2014 const bool verticalMoved = verticalHeader()->sectionsMoved();
2015 const bool horizontalMoved = horizontalHeader()->sectionsMoved();
2017 QItemSelection selection;
2019 int bottom = br.row();
2020 int left = tl.column();
2021 int right = br.column();
2023 if (d->hasSpans()) {
2027 bool intersectsSpan =
false;
2028 top = qMin(d->visualRow(tl.row()), d->visualRow(br.row()));
2029 left = qMin(d->visualColumn(tl.column()), d->visualColumn(br.column()));
2030 bottom = qMax(d->visualRow(tl.row()), d->visualRow(br.row()));
2031 right = qMax(d->visualColumn(tl.column()), d->visualColumn(br.column()));
2034 for (QSpanCollection::Span *it : d->spans.spans) {
2035 const QSpanCollection::Span &span = *it;
2036 const int t = d->visualRow(span.top());
2037 const int l = d->visualColumn(span.left());
2038 const int b = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
2039 const int r = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
2040 if ((t > bottom) || (l > right) || (top > b) || (left > r))
2042 intersectsSpan =
true;
2063 if (!intersectsSpan) {
2067 right = br.column();
2068 }
else if (!verticalMoved && !horizontalMoved) {
2070 tl = d->model->index(top, left, d->root);
2071 br = d->model->index(bottom, right, d->root);
2073 }
else if (verticalMoved && horizontalMoved) {
2074 top = d->visualRow(tl.row());
2075 bottom = d->visualRow(br.row());
2076 left = d->visualColumn(tl.column());
2077 right = d->visualColumn(br.column());
2078 }
else if (horizontalMoved) {
2081 left = d->visualColumn(tl.column());
2082 right = d->visualColumn(br.column());
2083 }
else if (verticalMoved) {
2084 top = d->visualRow(tl.row());
2085 bottom = d->visualRow(br.row());
2087 right = br.column();
2090 if (horizontalMoved && verticalMoved) {
2091 selection.reserve((right - left + 1) * (bottom - top + 1));
2092 for (
int horizontal = left; horizontal <= right; ++horizontal) {
2093 int column = d->logicalColumn(horizontal);
2094 for (
int vertical = top; vertical <= bottom; ++vertical) {
2095 int row = d->logicalRow(vertical);
2096 QModelIndex index = d->model->index(row, column, d->root);
2097 selection.append(QItemSelectionRange(index));
2100 }
else if (horizontalMoved) {
2101 selection.reserve(right - left + 1);
2102 for (
int visual = left; visual <= right; ++visual) {
2103 int column = d->logicalColumn(visual);
2104 QModelIndex topLeft = d->model->index(top, column, d->root);
2105 QModelIndex bottomRight = d->model->index(bottom, column, d->root);
2106 selection.append(QItemSelectionRange(topLeft, bottomRight));
2108 }
else if (verticalMoved) {
2109 selection.reserve(bottom - top + 1);
2110 for (
int visual = top; visual <= bottom; ++visual) {
2111 int row = d->logicalRow(visual);
2112 QModelIndex topLeft = d->model->index(row, left, d->root);
2113 QModelIndex bottomRight = d->model->index(row, right, d->root);
2114 selection.append(QItemSelectionRange(topLeft, bottomRight));
2117 QItemSelectionRange range(tl, br);
2118 if (!range.isEmpty())
2119 selection.append(range);
2122 d->selectionModel->select(selection, command);
2134QRegion QTableView::visualRegionForSelection(
const QItemSelection &selection)
const
2136 Q_D(
const QTableView);
2138 if (selection.isEmpty())
2141 QRegion selectionRegion;
2142 const QRect &viewportRect = d->viewport->rect();
2143 bool verticalMoved = verticalHeader()->sectionsMoved();
2144 bool horizontalMoved = horizontalHeader()->sectionsMoved();
2146 if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
2147 for (
const auto &range : selection) {
2148 if (range.parent() != d->root || !range.isValid())
2150 for (
int r = range.top(); r <= range.bottom(); ++r)
2151 for (
int c = range.left(); c <= range.right(); ++c) {
2152 const QRect &rangeRect = visualRect(d->model->index(r, c, d->root));
2153 if (viewportRect.intersects(rangeRect))
2154 selectionRegion += rangeRect;
2157 }
else if (horizontalMoved) {
2158 for (
const auto &range : selection) {
2159 if (range.parent() != d->root || !range.isValid())
2161 int top = rowViewportPosition(range.top());
2162 int bottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
2164 qSwap<
int>(top, bottom);
2165 int height = bottom - top;
2166 for (
int c = range.left(); c <= range.right(); ++c) {
2167 const QRect rangeRect(columnViewportPosition(c), top, columnWidth(c), height);
2168 if (viewportRect.intersects(rangeRect))
2169 selectionRegion += rangeRect;
2172 }
else if (verticalMoved) {
2173 for (
const auto &range : selection) {
2174 if (range.parent() != d->root || !range.isValid())
2176 int left = columnViewportPosition(range.left());
2177 int right = columnViewportPosition(range.right()) + columnWidth(range.right());
2179 qSwap<
int>(left, right);
2180 int width = right - left;
2181 for (
int r = range.top(); r <= range.bottom(); ++r) {
2182 const QRect rangeRect(left, rowViewportPosition(r), width, rowHeight(r));
2183 if (viewportRect.intersects(rangeRect))
2184 selectionRegion += rangeRect;
2188 const int gridAdjust = showGrid() ? 1 : 0;
2189 for (
auto range : selection) {
2190 if (range.parent() != d->root || !range.isValid())
2192 d->trimHiddenSelections(&range);
2194 const int rtop = rowViewportPosition(range.top());
2195 const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom());
2198 if (isLeftToRight()) {
2199 rleft = columnViewportPosition(range.left());
2200 rright = columnViewportPosition(range.right()) + columnWidth(range.right());
2202 rleft = columnViewportPosition(range.right());
2203 rright = columnViewportPosition(range.left()) + columnWidth(range.left());
2205 const QRect rangeRect(QPoint(rleft, rtop), QPoint(rright - 1 - gridAdjust, rbottom - 1 - gridAdjust));
2206 if (viewportRect.intersects(rangeRect))
2207 selectionRegion += rangeRect;
2208 if (d->hasSpans()) {
2209 const auto spansInRect = d->spans.spansInRect(range.left(), range.top(), range.width(), range.height());
2210 for (QSpanCollection::Span *s : spansInRect) {
2211 if (range.contains(s->top(), s->left(), range.parent())) {
2212 const QRect &visualSpanRect = d->visualSpanRect(*s);
2213 if (viewportRect.intersects(visualSpanRect))
2214 selectionRegion += visualSpanRect;
2221 return selectionRegion;
2278void QTableView::updateGeometries()
2281 if (d->geometryRecursionBlock)
2283 d->geometryRecursionBlock =
true;
2286 if (!d->verticalHeader->isHidden()) {
2287 width = qMax(d->verticalHeader->minimumWidth(), d->verticalHeader->sizeHint().width());
2288 width = qMin(width, d->verticalHeader->maximumWidth());
2291 if (!d->horizontalHeader->isHidden()) {
2292 height = qMax(d->horizontalHeader->minimumHeight(), d->horizontalHeader->sizeHint().height());
2293 height = qMin(height, d->horizontalHeader->maximumHeight());
2295 bool reverse = isRightToLeft();
2297 setViewportMargins(0, height, width, 0);
2299 setViewportMargins(width, height, 0, 0);
2303 QRect vg = d->viewport->geometry();
2305 int verticalLeft = reverse ? vg.right() + 1 : (vg.left() - width);
2306 d->verticalHeader->setGeometry(verticalLeft, vg.top(), width, vg.height());
2307 if (d->verticalHeader->isHidden())
2308 QMetaObject::invokeMethod(d->verticalHeader,
"updateGeometries");
2310 int horizontalTop = vg.top() - height;
2311 d->horizontalHeader->setGeometry(vg.left(), horizontalTop, vg.width(), height);
2312 if (d->horizontalHeader->isHidden())
2313 QMetaObject::invokeMethod(d->horizontalHeader,
"updateGeometries");
2315#if QT_CONFIG(abstractbutton)
2317 if (d->horizontalHeader->isHidden() || d->verticalHeader->isHidden()) {
2318 d->cornerWidget->setHidden(
true);
2320 d->cornerWidget->setHidden(
false);
2321 d->cornerWidget->setGeometry(verticalLeft, horizontalTop, width, height);
2328 QSize vsize = d->viewport->size();
2329 QSize max = maximumViewportSize();
2330 const int horizontalLength = d->horizontalHeader->length();
2331 const int verticalLength = d->verticalHeader->length();
2332 if (max.width() >= horizontalLength && max.height() >= verticalLength)
2336 const int columnCount = d->horizontalHeader->count();
2337 const int viewportWidth = vsize.width();
2338 int columnsInViewport = 0;
2339 for (
int width = 0, column = columnCount - 1; column >= 0; --column) {
2340 int logical = d->horizontalHeader->logicalIndex(column);
2341 if (!d->horizontalHeader->isSectionHidden(logical)) {
2342 width += d->horizontalHeader->sectionSize(logical);
2343 if (width > viewportWidth)
2345 ++columnsInViewport;
2348 columnsInViewport = qMax(columnsInViewport, 1);
2350 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
2351 const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();
2352 horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport);
2353 horizontalScrollBar()->setPageStep(columnsInViewport);
2354 if (columnsInViewport >= visibleColumns)
2355 d->horizontalHeader->setOffset(0);
2356 horizontalScrollBar()->setSingleStep(1);
2358 horizontalScrollBar()->setPageStep(vsize.width());
2359 horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());
2360 horizontalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
2364 const int rowCount = d->verticalHeader->count();
2365 const int viewportHeight = vsize.height();
2366 int rowsInViewport = 0;
2367 for (
int height = 0, row = rowCount - 1; row >= 0; --row) {
2368 int logical = d->verticalHeader->logicalIndex(row);
2369 if (!d->verticalHeader->isSectionHidden(logical)) {
2370 height += d->verticalHeader->sectionSize(logical);
2371 if (height > viewportHeight)
2376 rowsInViewport = qMax(rowsInViewport, 1);
2378 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
2379 const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();
2380 verticalScrollBar()->setRange(0, visibleRows - rowsInViewport);
2381 verticalScrollBar()->setPageStep(rowsInViewport);
2382 if (rowsInViewport >= visibleRows)
2383 d->verticalHeader->setOffset(0);
2384 verticalScrollBar()->setSingleStep(1);
2386 verticalScrollBar()->setPageStep(vsize.height());
2387 verticalScrollBar()->setRange(0, verticalLength - vsize.height());
2388 verticalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
2390 d->verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode());
2392 d->geometryRecursionBlock =
false;
2393 QAbstractItemView::updateGeometries();
2410int QTableView::sizeHintForRow(
int row)
const
2412 Q_D(
const QTableView);
2418 const int maximumProcessCols = d->verticalHeader->resizeContentsPrecision();
2421 int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
2422 int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
2424 right = d->model->columnCount(d->root) - 1;
2426 QStyleOptionViewItem option;
2427 initViewItemOption(&option);
2431 int columnsProcessed = 0;
2433 for (; column <= right; ++column) {
2434 int logicalColumn = d->horizontalHeader->logicalIndex(column);
2435 if (d->horizontalHeader->isSectionHidden(logicalColumn))
2437 index = d->model->index(row, logicalColumn, d->root);
2438 hint = d->heightHintForIndex(index, hint, option);
2441 if (columnsProcessed == maximumProcessCols)
2445 const int actualRight = d->model->columnCount(d->root) - 1;
2447 int idxRight = column - 1;
2449 if (maximumProcessCols == 0 || actualRight < idxLeft)
2450 columnsProcessed = maximumProcessCols;
2452 while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {
2453 int logicalIdx = -1;
2455 if ((columnsProcessed % 2 && idxLeft > 0) || idxRight == actualRight) {
2456 while (idxLeft > 0) {
2458 int logcol = d->horizontalHeader->logicalIndex(idxLeft);
2459 if (d->horizontalHeader->isSectionHidden(logcol))
2461 logicalIdx = logcol;
2465 while (idxRight < actualRight) {
2467 int logcol = d->horizontalHeader->logicalIndex(idxRight);
2468 if (d->horizontalHeader->isSectionHidden(logcol))
2470 logicalIdx = logcol;
2474 if (logicalIdx >= 0) {
2475 index = d->model->index(row, logicalIdx, d->root);
2476 hint = d->heightHintForIndex(index, hint, option);
2481 return d->showGrid ? hint + 1 : hint;
2499int QTableView::sizeHintForColumn(
int column)
const
2501 Q_D(
const QTableView);
2507 const int maximumProcessRows = d->horizontalHeader->resizeContentsPrecision();
2509 int top = qMax(0, d->verticalHeader->visualIndexAt(0));
2510 int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
2511 if (!isVisible() || bottom == -1)
2512 bottom = d->model->rowCount(d->root) - 1;
2514 QStyleOptionViewItem option;
2515 initViewItemOption(&option);
2518 int rowsProcessed = 0;
2521 for (; row <= bottom; ++row) {
2522 int logicalRow = d->verticalHeader->logicalIndex(row);
2523 if (d->verticalHeader->isSectionHidden(logicalRow))
2525 index = d->model->index(logicalRow, column, d->root);
2527 hint = d->widthHintForIndex(index, hint, option);
2529 if (rowsProcessed == maximumProcessRows)
2533 const int actualBottom = d->model->rowCount(d->root) - 1;
2535 int idxBottom = row - 1;
2537 if (maximumProcessRows == 0 || actualBottom < idxTop)
2538 rowsProcessed = maximumProcessRows;
2540 while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {
2541 int logicalIdx = -1;
2543 if ((rowsProcessed % 2 && idxTop > 0) || idxBottom == actualBottom) {
2544 while (idxTop > 0) {
2546 int logrow = d->verticalHeader->logicalIndex(idxTop);
2547 if (d->verticalHeader->isSectionHidden(logrow))
2549 logicalIdx = logrow;
2553 while (idxBottom < actualBottom) {
2555 int logrow = d->verticalHeader->logicalIndex(idxBottom);
2556 if (d->verticalHeader->isSectionHidden(logrow))
2558 logicalIdx = logrow;
2562 if (logicalIdx >= 0) {
2563 index = d->model->index(logicalIdx, column, d->root);
2564 hint = d->widthHintForIndex(index, hint, option);
2569 return d->showGrid ? hint + 1 : hint;
2896void QTableView::scrollTo(
const QModelIndex &index, ScrollHint hint)
2901 if (!d->isIndexValid(index)
2902 || (d->model->parent(index) != d->root)
2903 || isRowHidden(index.row()) || isColumnHidden(index.column()))
2906 QSpanCollection::Span span;
2908 span = d->span(index.row(), index.column());
2912 int viewportWidth = d->viewport->width();
2913 int horizontalOffset = d->horizontalHeader->offset();
2914 int horizontalPosition = d->horizontalHeader->sectionPosition(index.column());
2915 int horizontalIndex = d->horizontalHeader->visualIndex(index.column());
2916 int cellWidth = d->hasSpans()
2917 ? d->columnSpanWidth(index.column(), span.width())
2918 : d->horizontalHeader->sectionSize(index.column());
2920 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
2922 bool positionAtLeft = (horizontalPosition - horizontalOffset < 0);
2923 bool positionAtRight = (horizontalPosition - horizontalOffset + cellWidth > viewportWidth);
2925 if (hint == PositionAtCenter || positionAtRight) {
2926 int w = (hint == PositionAtCenter ? viewportWidth / 2 : viewportWidth);
2928 while (horizontalIndex > 0) {
2929 x += columnWidth(d->horizontalHeader->logicalIndex(horizontalIndex-1));
2936 if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {
2937 int hiddenSections = 0;
2938 if (d->horizontalHeader->sectionsHidden()) {
2939 for (
int s = horizontalIndex - 1; s >= 0; --s) {
2940 int column = d->horizontalHeader->logicalIndex(s);
2941 if (d->horizontalHeader->isSectionHidden(column))
2945 horizontalScrollBar()->setValue(horizontalIndex - hiddenSections);
2949 if (hint == PositionAtCenter) {
2950 horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
2952 if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
2953 horizontalScrollBar()->setValue(horizontalPosition);
2954 else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
2955 horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
2961 int viewportHeight = d->viewport->height();
2962 int verticalOffset = d->verticalHeader->offset();
2963 int verticalPosition = d->verticalHeader->sectionPosition(index.row());
2964 int verticalIndex = d->verticalHeader->visualIndex(index.row());
2965 int cellHeight = d->hasSpans()
2966 ? d->rowSpanHeight(index.row(), span.height())
2967 : d->verticalHeader->sectionSize(index.row());
2969 if (verticalPosition - verticalOffset < 0 || cellHeight > viewportHeight) {
2970 if (hint == EnsureVisible)
2971 hint = PositionAtTop;
2972 }
else if (verticalPosition - verticalOffset + cellHeight > viewportHeight) {
2973 if (hint == EnsureVisible)
2974 hint = PositionAtBottom;
2977 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
2979 if (hint == PositionAtBottom || hint == PositionAtCenter) {
2980 int h = (hint == PositionAtCenter ? viewportHeight / 2 : viewportHeight);
2982 while (verticalIndex > 0) {
2983 int row = d->verticalHeader->logicalIndex(verticalIndex - 1);
2984 y += d->verticalHeader->sectionSize(row);
2991 if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {
2992 int hiddenSections = 0;
2993 if (d->verticalHeader->sectionsHidden()) {
2994 for (
int s = verticalIndex - 1; s >= 0; --s) {
2995 int row = d->verticalHeader->logicalIndex(s);
2996 if (d->verticalHeader->isSectionHidden(row))
3000 verticalScrollBar()->setValue(verticalIndex - hiddenSections);
3004 if (hint == PositionAtTop) {
3005 verticalScrollBar()->setValue(verticalPosition);
3006 }
else if (hint == PositionAtBottom) {
3007 verticalScrollBar()->setValue(verticalPosition - viewportHeight + cellHeight);
3008 }
else if (hint == PositionAtCenter) {
3009 verticalScrollBar()->setValue(verticalPosition - ((viewportHeight - cellHeight) / 2));
3049void QTableView::timerEvent(QTimerEvent *event)
3053 if (event->id() == d->columnResizeTimer.id()) {
3054 const int oldScrollMax = horizontalScrollBar()->maximum();
3055 if (horizontalHeader()->d_func()->state != QHeaderViewPrivate::ResizeSection) {
3057 d->columnResizeTimer.stop();
3059 updateEditorGeometries();
3063 int viewportHeight = d->viewport->height();
3064 int viewportWidth = d->viewport->width();
3065 if (d->hasSpans() || horizontalScrollBar()->value() == oldScrollMax) {
3066 rect = QRect(0, 0, viewportWidth, viewportHeight);
3068 for (
int i = d->columnsToUpdate.size()-1; i >= 0; --i) {
3069 int column = d->columnsToUpdate.at(i);
3070 int x = columnViewportPosition(column);
3071 if (isRightToLeft())
3072 rect |= QRect(0, 0, x + columnWidth(column), viewportHeight);
3074 rect |= QRect(x, 0, viewportWidth - x, viewportHeight);
3078 d->viewport->update(rect.normalized());
3079 d->columnsToUpdate.clear();
3082 if (event->id() == d->rowResizeTimer.id()) {
3083 const int oldScrollMax = verticalScrollBar()->maximum();
3084 if (verticalHeader()->d_func()->state != QHeaderViewPrivate::ResizeSection) {
3086 d->rowResizeTimer.stop();
3088 updateEditorGeometries();
3091 int viewportHeight = d->viewport->height();
3092 int viewportWidth = d->viewport->width();
3094 if (d->hasSpans() || verticalScrollBar()->value() == oldScrollMax) {
3097 top = viewportHeight;
3098 for (
int i = d->rowsToUpdate.size()-1; i >= 0; --i) {
3099 int y = rowViewportPosition(d->rowsToUpdate.at(i));
3104 d->viewport->update(QRect(0, top, viewportWidth, viewportHeight - top));
3105 d->rowsToUpdate.clear();
3108 QAbstractItemView::timerEvent(event);
3464void QTableViewPrivate::selectRow(
int row,
bool anchor)
3468 if (q->selectionBehavior() == QTableView::SelectColumns
3469 || (q->selectionMode() == QTableView::SingleSelection
3470 && q->selectionBehavior() == QTableView::SelectItems))
3473 if (row >= 0 && row < model->rowCount(root)) {
3474 int column = horizontalHeader->logicalIndexAt(q->isRightToLeft() ? viewport->width() : 0);
3475 QModelIndex index = model->index(row, column, root);
3476 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
3480 const auto startIndex = currentSelectionStartIndex;
3481 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
3482 currentSelectionStartIndex = startIndex;
3485 if ((anchor && !(command & QItemSelectionModel::Current))
3486 || (q->selectionMode() == QTableView::SingleSelection))
3487 currentSelectionStartIndex = model->index(row, column, root);
3489 if (q->selectionMode() != QTableView::SingleSelection
3490 && command.testFlag(QItemSelectionModel::Toggle)) {
3492 ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows(column).contains(index)
3493 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
3494 command &= ~QItemSelectionModel::Toggle;
3495 command |= ctrlDragSelectionFlag;
3497 command |= QItemSelectionModel::Current;
3500 const auto rowSectionAnchor = currentSelectionStartIndex.row();
3501 QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root);
3502 QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root);
3503 if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) {
3504 q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows);
3506 selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows);
3511void QTableViewPrivate::selectColumn(
int column,
bool anchor)
3515 if (q->selectionBehavior() == QTableView::SelectRows
3516 || (q->selectionMode() == QTableView::SingleSelection
3517 && q->selectionBehavior() == QTableView::SelectItems))
3520 if (column >= 0 && column < model->columnCount(root)) {
3521 int row = verticalHeader->logicalIndexAt(0);
3522 QModelIndex index = model->index(row, column, root);
3523 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index);
3527 const auto startIndex = currentSelectionStartIndex;
3528 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
3529 currentSelectionStartIndex = startIndex;
3532 if ((anchor && !(command & QItemSelectionModel::Current))
3533 || (q->selectionMode() == QTableView::SingleSelection))
3534 currentSelectionStartIndex = model->index(row, column, root);
3536 if (q->selectionMode() != QTableView::SingleSelection
3537 && command.testFlag(QItemSelectionModel::Toggle)) {
3539 ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns(row).contains(index)
3540 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
3541 command &= ~QItemSelectionModel::Toggle;
3542 command |= ctrlDragSelectionFlag;
3544 command |= QItemSelectionModel::Current;
3547 const auto columnSectionAnchor = currentSelectionStartIndex.column();
3548 QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root);
3549 QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root);
3550 if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) {
3551 q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns);
3553 selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns);