📄 qitemselectionmodel.cpp
字号:
QModelIndex br = bottomRight.sibling(bottom, right); append(QItemSelectionRange(tl, br)); return; } append(QItemSelectionRange(topLeft, bottomRight));}/*! Returns true if the selection contains the given \a index; otherwise returns false.*/bool QItemSelection::contains(const QModelIndex &index) const{ QList<QItemSelectionRange>::const_iterator it = begin(); for (; it != end(); ++it) if ((*it).contains(index)) return true; return false;}/*! Returns a list of model indexes that correspond to the selected items.*/QModelIndexList QItemSelection::indexes() const{ QModelIndexList result; QList<QItemSelectionRange>::const_iterator it = begin(); for (; it != end(); ++it) result += (*it).indexes(); return result;}/*! Merges the \a other selection with this QItemSelection using the \a command given. This method guarantees that no ranges are overlapping. Note that only QItemSelectionModel::Select, QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are supported. \sa split()*/void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command){ if (other.isEmpty() || !(command & QItemSelectionModel::Select || command & QItemSelectionModel::Deselect || command & QItemSelectionModel::Toggle)) return; QItemSelection newSelection = other; // Collect intersections QItemSelection intersections; QItemSelection::iterator it = newSelection.begin(); while (it != newSelection.end()) { if (!(*it).isValid()) { it = newSelection.erase(it); continue; } for (int t = 0; t < count(); ++t) { if ((*it).intersects(at(t))) intersections.append(at(t).intersected(*it)); } ++it; } // Split the old (and new) ranges using the intersections for (int i = 0; i < intersections.count(); ++i) { // for each intersection for (int t = 0; t < count();) { // splitt each old range if (at(t).intersects(intersections.at(i))) { split(at(t), intersections.at(i), this); removeAt(t); } else { ++t; } } // only split newSelection if Toggle is specified for (int n = 0; (command & QItemSelectionModel::Toggle) && n < newSelection.count();) { if (newSelection.at(n).intersects(intersections.at(i))) { split(newSelection.at(n), intersections.at(i), &newSelection); newSelection.removeAt(n); } else { ++n; } } } // do not add newSelection for Deselect if (!(command & QItemSelectionModel::Deselect)) operator+=(newSelection);}/*! Splits the selection \a range using the selection \a other range. Removes all items in \a other from \a range and puts the result in \a result. This can be compared with the semantics of the \e subtract operation of a set. \sa merge()*/void QItemSelection::split(const QItemSelectionRange &range, const QItemSelectionRange &other, QItemSelection *result){ if (range.parent() != other.parent()) return; QModelIndex parent = other.parent(); int top = range.top(); int left = range.left(); int bottom = range.bottom(); int right = range.right(); int other_top = other.top(); int other_left = other.left(); int other_bottom = other.bottom(); int other_right = other.right(); const QAbstractItemModel *model = range.model(); Q_ASSERT(model); if (other_top > top) { QModelIndex tl = model->index(top, left, parent); QModelIndex br = model->index(other_top - 1, right, parent); result->append(QItemSelectionRange(tl, br)); top = other_top; } if (other_bottom < bottom) { QModelIndex tl = model->index(other_bottom + 1, left, parent); QModelIndex br = model->index(bottom, right, parent); result->append(QItemSelectionRange(tl, br)); bottom = other_bottom; } if (other_left > left) { QModelIndex tl = model->index(top, left, parent); QModelIndex br = model->index(bottom, other_left - 1, parent); result->append(QItemSelectionRange(tl, br)); left = other_left; } if (other_right < right) { QModelIndex tl = model->index(top, other_right + 1, parent); QModelIndex br = model->index(bottom, right, parent); result->append(QItemSelectionRange(tl, br)); right = other_right; }}/*! \internal returns a QItemSelection where all ranges have been expanded to: Rows: left: 0 and right: columnCount()-1 Columns: top: 0 and bottom: rowCount()-1*/QItemSelection QItemSelectionModelPrivate::expandSelection(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) const{ if (selection.isEmpty() && !((command & QItemSelectionModel::Rows) || (command & QItemSelectionModel::Columns))) return selection; QItemSelection expanded; if (command & QItemSelectionModel::Rows) { for (int i = 0; i < selection.count(); ++i) { QModelIndex parent = selection.at(i).parent(); int colCount = model->columnCount(parent); QModelIndex tl = model->index(selection.at(i).top(), 0, parent); QModelIndex br = model->index(selection.at(i).bottom(), colCount - 1, parent); expanded.append(QItemSelectionRange(tl, br)); } } if (command & QItemSelectionModel::Columns) { for (int i = 0; i < selection.count(); ++i) { QModelIndex parent = selection.at(i).parent(); int rowCount = model->rowCount(parent); QModelIndex tl = model->index(0, selection.at(i).left(), parent); QModelIndex br = model->index(rowCount - 1, selection.at(i).right(), parent); expanded.append(QItemSelectionRange(tl, br)); } } return expanded;}/*! \internal*/void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end){ Q_Q(QItemSelectionModel); // update current index if (currentIndex.isValid() && parent == currentIndex.parent() && currentIndex.row() >= start && currentIndex.row() <= end) { QModelIndex old = currentIndex; if (start > 0) // there are rows left above the change currentIndex = model->index(start - 1, old.column(), parent); else if (model && end < model->rowCount(parent) - 1) // there are rows left below the change currentIndex = model->index(end + 1, old.column(), parent); else // there are no rows left in the table currentIndex = QModelIndex(); emit q->currentChanged(currentIndex, old); emit q->currentRowChanged(currentIndex, old); if (currentIndex.column() != old.column()) emit q->currentColumnChanged(currentIndex, old); } // update selectionsx QModelIndex tl = model->index(start, 0, parent); QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent); q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect); finalize();}/*! \internal*/void QItemSelectionModelPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end){ Q_Q(QItemSelectionModel); // update current index if (currentIndex.isValid() && parent == currentIndex.parent() && currentIndex.column() >= start && currentIndex.column() <= end) { QModelIndex old = currentIndex; if (start > 0) // there are columns to the left of the change currentIndex = model->index(old.row(), start - 1, parent); else if (model && end < model->columnCount() - 1) // there are columns to the right of the change currentIndex = model->index(old.row(), end + 1, parent); else // there are no columns left in the table currentIndex = QModelIndex(); emit q->currentChanged(currentIndex, old); if (currentIndex.row() != old.row()) emit q->currentRowChanged(currentIndex, old); emit q->currentColumnChanged(currentIndex, old); } // update selections QModelIndex tl = model->index(0, start, parent); QModelIndex br = model->index(model->rowCount(parent) - 1, end, parent); q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect); finalize();}/*! \internal Split selection ranges if columns are about to be inserted in the middle.*/void QItemSelectionModelPrivate::_q_columnsAboutToBeInserted(const QModelIndex &parent, int start, int end){ Q_UNUSED(end); finalize(); QList<QItemSelectionRange> split; QList<QItemSelectionRange>::iterator it = ranges.begin(); for (; it != ranges.end(); ) { if ((*it).isValid() && (*it).parent() == parent && (*it).left() <= start && (*it).right() >= start) { QModelIndex bottomMiddle = model->index((*it).bottom(), start - 1, (*it).parent()); QItemSelectionRange left((*it).topLeft(), bottomMiddle); QModelIndex topMiddle = model->index((*it).top(), start, (*it).parent()); QItemSelectionRange right(topMiddle, (*it).bottomRight()); it = ranges.erase(it); split.append(left); split.append(right); } else { ++it; } } ranges += split;}/*! \internal Split selection ranges if rows are about to be inserted in the middle.*/void QItemSelectionModelPrivate::_q_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end){ Q_UNUSED(end); finalize(); QList<QItemSelectionRange> split; QList<QItemSelectionRange>::iterator it = ranges.begin(); for (; it != ranges.end(); ) { if ((*it).isValid() && (*it).parent() == parent && (*it).top() <= start && (*it).bottom() >= start) { QModelIndex middleRight = model->index(start - 1, (*it).right(), (*it).parent()); QItemSelectionRange top((*it).topLeft(), middleRight); QModelIndex middleLeft = model->index(start, (*it).left(), (*it).parent()); QItemSelectionRange bottom(middleLeft, (*it).bottomRight()); it = ranges.erase(it); split.append(top); split.append(bottom); } else { ++it; } } ranges += split;}/*! \internal Split selection into individual (persistent) indexes. This is done in preparation for the layoutChanged() signal, where the indexes can be merged again.*/void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged(){ savedPersistentIndexes.clear(); savedPersistentCurrentIndexes.clear(); QModelIndexList indexes = ranges.indexes(); QModelIndexList::const_iterator it; for (it = indexes.constBegin(); it != indexes.constEnd(); ++it) savedPersistentIndexes.append(QPersistentModelIndex(*it)); indexes = currentSelection.indexes(); for (it = indexes.constBegin(); it != indexes.constEnd(); ++it) savedPersistentCurrentIndexes.append(QPersistentModelIndex(*it));}/*! \internal Merges \a indexes into an item selection made up of ranges. Assumes that the indexes are sorted.*/static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes){ QItemSelection colSpans; // merge columns int i = 0; while (i < indexes.count()) { QModelIndex tl = indexes.at(i); QModelIndex br = tl; while (++i < indexes.count()) { QModelIndex next = indexes.at(i); if ((next.parent() == br.parent()) && (next.row() == br.row()) && (next.column() == br.column() + 1)) br = next; else break; } colSpans.append(QItemSelectionRange(tl, br)); } // merge rows QItemSelection rowSpans; i = 0; while (i < colSpans.count()) { QModelIndex tl = colSpans.at(i).topLeft(); QModelIndex br = colSpans.at(i).bottomRight(); QModelIndex prevTl = tl; while (++i < colSpans.count()) { QModelIndex nextTl = colSpans.at(i).topLeft(); QModelIndex nextBr = colSpans.at(i).bottomRight(); if ((nextTl.column() == prevTl.column()) && (nextBr.column() == br.column()) && (nextTl.row() == prevTl.row() + 1) && (nextBr.row() == br.row() + 1)) { br = nextBr; prevTl = nextTl; } else { break; } } rowSpans.append(QItemSelectionRange(tl, br)); } return rowSpans;}/*! \internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -