📄 qlistview.cpp
字号:
// plus adding viewitems to the draggedItems list. // We need these items to draw the drag items Q_D(QListView); QModelIndexList indexes = selectionModel()->selectedIndexes(); if (indexes.count() > 0 ) { QModelIndexList::ConstIterator it = indexes.begin(); for (; it != indexes.end(); ++it) if (model()->flags(*it) & Qt::ItemIsDragEnabled) d->draggedItems.push_back(*it); QDrag *drag = new QDrag(this); drag->setMimeData(model()->mimeData(indexes)); Qt::DropAction action = drag->start(supportedActions); d->draggedItems.clear(); if (action == Qt::MoveAction) d->removeSelectedRows(); }}#endif // QT_NO_DRAGANDDROP/*! \reimp*/QStyleOptionViewItem QListView::viewOptions() const{ Q_D(const QListView); QStyleOptionViewItem option = QAbstractItemView::viewOptions(); if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview int pm = (d->viewMode == ListMode ? style()->pixelMetric(QStyle::PM_ListViewIconSize) : style()->pixelMetric(QStyle::PM_IconViewIconSize)); option.decorationSize = QSize(pm, pm); } if (d->viewMode == IconMode) { option.showDecorationSelected = false; option.decorationPosition = QStyleOptionViewItem::Top; option.displayAlignment = Qt::AlignCenter; } else { option.decorationPosition = QStyleOptionViewItem::Left; } return option;}/*! \reimp*/void QListView::paintEvent(QPaintEvent *e){ Q_D(QListView); QStyleOptionViewItem option = viewOptions(); QPainter painter(d->viewport); QRect area = e->rect(); // if there's nothing to do, clear the area and return if (!model()) { painter.fillRect(area, option.palette.brush(QPalette::Base)); return; } QVector<QModelIndex> toBeRendered;// QVector<QRect> rects = e->region().rects();// for (int i = 0; i < rects.size(); ++i) {// d->intersectingSet(rects.at(i).translated(horizontalOffset(), verticalOffset()));// toBeRendered += d->intersectVector;// } d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); toBeRendered = d->intersectVector; const QPoint offset = d->scrollDelayOffset; const QModelIndex current = currentIndex(); const QModelIndex hover = d->hover; const QAbstractItemModel *itemModel = model(); const QAbstractItemDelegate *delegate = itemDelegate(); const QItemSelectionModel *selections = selectionModel(); const bool focus = (hasFocus() || d->viewport->hasFocus()) && current.isValid(); const bool alternate = d->alternatingColors; const QStyle::State state = option.state; const QAbstractItemView::State viewState = this->state(); const bool enabled = (state & QStyle::State_Enabled) != 0; bool alternateBase = false; if (alternate && !toBeRendered.isEmpty()) { int first = toBeRendered.first().row(); if (!d->hiddenRows.isEmpty()) { for (int row = 0; row < first; ++row) { if (!d->hiddenRows.contains(row)) alternateBase = !alternateBase; } } else { alternateBase = (first & 1) != 0; } } QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd(); for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { Q_ASSERT((*it).isValid()); option.rect = visualRect(*it).translated(offset); option.state = state; if (selections && selections->isSelected(*it)) option.state |= QStyle::State_Selected; if (enabled) { QPalette::ColorGroup cg; if ((itemModel->flags(*it) & Qt::ItemIsEnabled) == 0) { option.state &= ~QStyle::State_Enabled; cg = QPalette::Disabled; } else { cg = QPalette::Normal; } option.palette.setCurrentColorGroup(cg); } if (focus && current == *it) { option.state |= QStyle::State_HasFocus; if (viewState == EditingState) option.state |= QStyle::State_Editing; } if (*it == hover) option.state |= QStyle::State_MouseOver; else option.state &= ~QStyle::State_MouseOver; if (alternate) { QBrush fill = alternateBase ? option.palette.brush(QPalette::AlternateBase) : option.palette.brush(QPalette::Base); alternateBase = !alternateBase; painter.fillRect(option.rect, fill); } delegate->paint(&painter, option, *it); }#ifndef QT_NO_DRAGANDDROP if (!d->draggedItems.isEmpty() && d->viewport->rect().contains(d->draggedItemsPos)) { QPoint delta = d->draggedItemsDelta(); painter.translate(delta.x(), delta.y()); d->drawItems(&painter, d->draggedItems); } // Paint the dropIndicator d_func()->paintDropIndicator(&painter);#endif#ifndef QT_NO_RUBBERBAND if (d->elasticBand.isValid()) { QStyleOptionRubberBand opt; opt.initFrom(this); opt.shape = QRubberBand::Rectangle; opt.opaque = false; opt.rect = d->mapToViewport(d->elasticBand).intersect( 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.first() : QModelIndex(); if (index.isValid() && visualRect(index).contains(p)) return index; return QModelIndex();}/*! \reimp*/int QListView::horizontalOffset() const{ return isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value();}/*! \reimp*/int QListView::verticalOffset() const{ return verticalScrollBar()->value();}/*! \reimp*/QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers){ Q_D(QListView); Q_UNUSED(modifiers); if (!model()) return QModelIndex(); QModelIndex current = currentIndex(); if (!current.isValid()) { int rowCount = model()->rowCount(rootIndex()); if (!rowCount) return QModelIndex(); int row = 0; while (row < rowCount && isRowHidden(row)) ++row; if (row >= rowCount) return QModelIndex(); return model()->index(row, 0, rootIndex()); } QRect rect = rectForIndex(current); if (rect.isEmpty()) { return model()->index(0, 0, rootIndex()); } 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 model()->index(d->batchStartRow - 1, d->column, rootIndex());#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 model()->index(0, d->column, rootIndex());#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 model()->index(0, d->column, rootIndex()); case MoveEnd: return model()->index(d->batchStartRow - 1, d->column, rootIndex()); } return current;}/*! Returns the rectangle of the item at position \a index in the model. The rectangle is in contents coordinates.*/QRect QListView::rectForIndex(const QModelIndex &index) const{ Q_D(const QListView); if (!index.isValid() || index.parent() != rootIndex() || 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 || !index.isValid() || index.parent() != rootIndex() || index.column() != d->column) return; d->executePostedLayout(); if (index.row() >= d->items.count()) return; d->setDirtyRegion(visualRect(index)); // update old position d->moveItem(index.row(), position); d->setDirtyRegion(visualRect(index)); // update new position}/*! \reimp*/void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command){ Q_D(QListView); if (!selectionModel()) return; d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); QItemSelection selection; QModelIndex tl; QModelIndex br; QVector<QModelIndex>::iterator it = d->intersectVector.begin(); for (; it != d->intersectVector.end(); ++it) { if (!tl.isValid() && !br.isValid()) { tl = br = *it; } else if ((*it).row() == (tl.row() - 1)) { tl = *it; // expand current range } else if ((*it).row() == (br.row() + 1)) { br = (*it); // expand current range } else { selection.select(tl, br); // select current range tl = br = *it; // start new range } } if (tl.isValid() && br.isValid()) selection.select(tl, br); selectionModel()->select(selection, command);}/*! \reimp*/QRegion QListView::visualRegionForSelection(const QItemSelection &selection) const{ Q_D(const QListView); // ### NOTE: this is a potential bottleneck in non-static mode int c = d->column; QRegion selectionRegion; for (int i = 0; i < selection.count(); ++i) { if (!selection.at(i).isValid()) continue; QModelIndex parent = selection.at(i).topLeft().parent(); int t = selection.at(i).topLeft().row(); int b = selection.at(i).bottomRight().row(); if (d->movement != Static || d->wrap) { // in non-static mode, we have to go through all selected items for (int r = t; r <= b; ++r) selectionRegion += QRegion(visualRect(d->model->index(r, c, parent))); } else { // in static mode, we can optimize a bit QRect rect(visualRect(d->model->index(t, c, parent)).topLeft(), visualRect(d->model->index(b, c, parent)).bottomRight()); selectionRegion += QRegion(rect); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -