📄 qlistview.cpp
字号:
} // FIXME: Until the we can provide a proper drop indicator // in IconMode, it makes no sense to show it if (d->viewMode == ListMode) d->paintDropIndicator(&painter);#endif#ifndef QT_NO_RUBBERBAND // #### move this implementation into a dynamic class if (d->showElasticBand && d->elasticBand.isValid()) { QStyleOptionRubberBand opt; opt.initFrom(this); opt.shape = QRubberBand::Rectangle; opt.opaque = false; opt.rect = d->mapToViewport(d->elasticBand, false).intersected( d->viewport->rect().adjusted(-16, -16, 16, 16)); painter.save(); style()->drawControl(QStyle::CE_RubberBand, &opt, &painter); painter.restore(); }#endif}/*! \reimp*/QModelIndex QListView::indexAt(const QPoint &p) const{ Q_D(const QListView); QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); d->intersectingSet(rect); QModelIndex index = d->intersectVector.count() > 0 ? d->intersectVector.last() : QModelIndex(); if (index.isValid() && visualRect(index).contains(p)) return index; return QModelIndex();}/*! \reimp*/int QListView::horizontalOffset() const{ Q_D(const QListView); // ### split into static and dynamic if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) { if (d->isWrapping()) { if (d->flow == TopToBottom && !d->staticListView->segmentPositions.isEmpty()) { const int max = d->staticListView->segmentPositions.count() - 1; int currentValue = qBound(0, horizontalScrollBar()->value(), max); int position = d->staticListView->segmentPositions.at(currentValue); int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max); int maximum = d->staticListView->segmentPositions.at(maximumValue); return (isRightToLeft() ? maximum - position : position); } //return 0; } else { if (d->flow == LeftToRight && !d->staticListView->flowPositions.isEmpty()) { int position = d->staticListView->flowPositions.at(horizontalScrollBar()->value()); int maximum = d->staticListView->flowPositions.at(horizontalScrollBar()->maximum()); return (isRightToLeft() ? maximum - position : position); } //return 0; } } return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value());}/*! \reimp*/int QListView::verticalOffset() const{ // ## split into static and dynamic Q_D(const QListView); if (verticalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) { if (d->isWrapping()) { if (d->flow == LeftToRight && !d->staticListView->segmentPositions.isEmpty()) { int value = verticalScrollBar()->value(); if (value >= d->staticListView->segmentPositions.count()) { //qWarning("QListView: Vertical scroll bar is out of bounds"); return 0; } return d->staticListView->segmentPositions.at(value); } } else { if (d->flow == TopToBottom && !d->staticListView->flowPositions.isEmpty()) { int value = verticalScrollBar()->value(); if (value >= d->staticListView->flowPositions.count()) { //qWarning("QListView: Vertical scroll bar is out of bounds"); return 0; } return d->staticListView->flowPositions.at(value) - d->spacing(); } } } return verticalScrollBar()->value();}/*! \reimp*/QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers){ Q_D(QListView); Q_UNUSED(modifiers); QModelIndex current = currentIndex(); if (!current.isValid()) { int rowCount = d->model->rowCount(d->root); if (!rowCount) return QModelIndex(); int row = 0; while (row < rowCount && isRowHidden(row)) ++row; if (row >= rowCount) return QModelIndex(); return d->model->index(row, 0, d->root); } QRect rect = rectForIndex(current); if (rect.isEmpty()) { return d->model->index(0, 0, d->root); } if (d->gridSize().isValid()) rect.setSize(d->gridSize()); QSize contents = d->contentsSize(); QPoint pos = rect.center(); d->intersectVector.clear(); switch (cursorAction) { case MoveLeft: while (d->intersectVector.isEmpty()) { rect.translate(-rect.width(), 0); if (rect.right() <= 0) return current; if (rect.left() < 0) rect.setLeft(0); d->intersectingSet(rect); // don't get current in this set int idx = d->intersectVector.indexOf(current); if (idx > -1) d->intersectVector.remove(idx); } return d->closestIndex(pos, d->intersectVector); case MoveRight: while (d->intersectVector.isEmpty()) { rect.translate(rect.width(), 0); if (rect.left() >= contents.width()) return current; if (rect.right() > contents.width()) rect.setRight(contents.width()); d->intersectingSet(rect); // don't get current in this set int idx = d->intersectVector.indexOf(current); if (idx > -1) d->intersectVector.remove(idx); } return d->closestIndex(pos, d->intersectVector); case MovePageUp: rect.moveTop(rect.top() - d->viewport->height()); if (rect.top() < rect.height()) rect.moveTop(rect.height()); case MovePrevious: case MoveUp: while (d->intersectVector.isEmpty()) { rect.translate(0, -rect.height()); if (rect.bottom() <= 0) {#ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) return d->model->index(d->batchStartRow() - 1, d->column, d->root);#endif return current; } if (rect.top() < 0) rect.setTop(0); d->intersectingSet(rect); // don't get current in this set int idx = d->intersectVector.indexOf(current); if (idx > -1) d->intersectVector.remove(idx); } return d->closestIndex(pos, d->intersectVector); case MovePageDown: rect.moveTop(rect.top() + d->viewport->height()); if (rect.bottom() > contents.height() - rect.height()) rect.moveBottom(contents.height() - rect.height()); case MoveNext: case MoveDown: while (d->intersectVector.isEmpty()) { rect.translate(0, rect.height()); if (rect.top() >= contents.height()) {#ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) return d->model->index(0, d->column, d->root);#endif return current; } if (rect.bottom() > contents.height()) rect.setBottom(contents.height()); d->intersectingSet(rect); // don't get current in this set int idx = d->intersectVector.indexOf(current); if (idx > -1) d->intersectVector.remove(idx); } return d->closestIndex(pos, d->intersectVector); case MoveHome: return d->model->index(0, d->column, d->root); case MoveEnd: return d->model->index(d->batchStartRow() - 1, d->column, d->root);} return current;}/*! Returns the rectangle of the item at position \a index in the model. The rectangle is in contents coordinates. \sa visualRect()*/QRect QListView::rectForIndex(const QModelIndex &index) const{ Q_D(const QListView); if (!d->isIndexValid(index) || index.parent() != d->root || index.column() != d->column || isIndexHidden(index)) return QRect(); d->executePostedLayout(); QListViewItem item = d->indexToListViewItem(index); return d->viewItemRect(item);}/*! \since 4.1 Sets the contents position of the item at \a index in the model to the given \a position. If the list view's movement mode is Static, this function will have no effect.*/void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index){ Q_D(QListView); if (d->movement == Static || !d->isIndexValid(index) || index.parent() != d->root || index.column() != d->column) return; d->executePostedLayout(); if (index.row() >= d->dynamicListView->items.count()) return; const QSize oldContents = d->contentsSize(); d->setDirtyRegion(visualRect(index)); // update old position d->dynamicListView->moveItem(index.row(), position); d->setDirtyRegion(visualRect(index)); // update new position if (d->contentsSize() != oldContents) updateGeometries(); // update the scroll bars}/*! \reimp*/void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command){ Q_D(QListView); if (!d->selectionModel) return; // if we are wrapping, we can only selecte inside the contents rectangle if (d->wrap && !QRect(QPoint(0, 0), d->contentsSize()).intersects(rect)) return; QItemSelection selection; if (rect.width() == 1 && rect.height() == 1) { d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); QModelIndex tl; if (!d->intersectVector.isEmpty()) tl = d->intersectVector.last(); // special case for mouse press; only select the top item if (tl.isValid()) selection.select(tl, tl); } else { if (state() == DragSelectingState) { // visual selection mode (rubberband selection) selection = d->selection(rect.translated(horizontalOffset(), verticalOffset())); } else { // logical selection mode (key and mouse click selection) QModelIndex tl, br; // get the first item const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1); d->intersectingSet(topLeft); if (!d->intersectVector.isEmpty()) tl = d->intersectVector.last(); // get the last item const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1); d->intersectingSet(bottomRight); if (!d->intersectVector.isEmpty()) br = d->intersectVector.last(); // get the ranges if (tl.isValid() && br.isValid()) { QRect first = rectForIndex(tl); QRect last = rectForIndex(br); QRect middle; if (d->flow == TopToBottom) { } if (d->flow == LeftToRight) { QRect &top = first; QRect &bottom = last; // if bottom is above top, swap them if (top.center().y() > bottom.center().y()) { QRect tmp = top; top = bottom; bottom = tmp; } // if the rect are on differnet lines, expand if (top.top() != bottom.top()) { // top rectangle if (isRightToLeft()) top.setLeft(0); else top.setRight(contentsSize().width()); // bottom rectangle if (isRightToLeft()) bottom.setRight(contentsSize().width()); else bottom.setLeft(0); } else if (top.left() > bottom.right()) { if (isRightToLeft()) bottom.setLeft(top.right()); else bottom.setRight(top.left()); } else { if (isRightToLeft()) top.setLeft(bottom.right()); else top.setRight(bottom.left()); } // middle rectangle if (top.bottom() < bottom.top()) { middle.setTop(top.bottom() + 1); middle.setLeft(qMin(top.left(), bottom.left())); middle.setBottom(bottom.top() - 1); middle.setRight(qMax(top.right(), bottom.right())); } } else { // TopToBottom QRect &left = first; QRect &right = last; if (left.center().x() > right.center().x()) qSwap(left, right); int ch = contentsSize().height(); if (left.left() != right.left()) { // left rectangle if (isRightToLeft()) left.setTop(0); else left.setBottom(ch); // top rectangle if (isRightToLeft()) right.setBottom(ch); else right.setTop(0); // only set middle if the middle.setTop(0); middle.setBottom(ch); middle.setLeft(left.right() + 1); middle.setRight(right.left() - 1); } else if (left.bottom() < right.top()) { left.setBottom(right.top() - 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -