qsortfilterproxymodel.cpp
来自「QT 开发环境里面一个很重要的文件」· C++ 代码 · 共 1,765 行 · 第 1/5 页
CPP
1,765 行
for (int proxy_item = 0; proxy_item < proxy_count; ++proxy_item) { int source_item = proxy_to_source.at(proxy_item); if (source_item >= start) proxy_to_source.replace(proxy_item, source_item - delta_item_count); } build_source_to_proxy_mapping(proxy_to_source, source_to_proxy); // see if any mapped children should be (re)moved QVector<QModelIndex>::iterator it2 = m->mapped_children.begin(); for ( ; it2 != m->mapped_children.end(); ) { const QModelIndex source_child_index = *it2; const int pos = (orient == Qt::Vertical) ? source_child_index.row() : source_child_index.column(); if (pos < start) { // not affected by removal ++it2; continue; } else if (pos <= end) { // in the removed interval it2 = m->mapped_children.erase(it2); remove_from_mapping(source_child_index); } else { // below the removed items -- recompute the index QModelIndex new_index; if (orient == Qt::Vertical) { new_index = model->index(pos - delta_item_count, source_child_index.column(), source_parent); } else { new_index = model->index(source_child_index.row(), pos - delta_item_count, source_parent); } *it2 = new_index; ++it2; // update mapping Mapping *cm = source_index_mapping.take(source_child_index); Q_ASSERT(cm); source_index_mapping.insert(new_index, cm); } }}/*! \internal*/void QSortFilterProxyModelPrivate::proxy_item_range( const QVector<int> &source_to_proxy, const QVector<int> &source_items, int &proxy_low, int &proxy_high) const{ proxy_low = INT_MAX; proxy_high = INT_MIN; foreach (int source_item, source_items) { int proxy_item = source_to_proxy.at(source_item); Q_ASSERT(proxy_item != -1); if (proxy_item < proxy_low) proxy_low = proxy_item; if (proxy_item > proxy_high) proxy_high = proxy_item; }}/*! \internal*/void QSortFilterProxyModelPrivate::build_source_to_proxy_mapping( const QVector<int> &proxy_to_source, QVector<int> &source_to_proxy) const{ source_to_proxy.fill(-1); int proxy_count = proxy_to_source.size(); for (int i = 0; i < proxy_count; ++i) source_to_proxy[proxy_to_source.at(i)] = i;}/*! \internal Maps the persistent proxy indexes to source indexes and returns the list of source indexes.*/QModelIndexList QSortFilterProxyModelPrivate::store_persistent_indexes(){ QModelIndexList source_indexes; int persistent_count = persistent.indexes.count(); for (int i = 0; i < persistent_count; ++i) { QModelIndex proxy_index = persistent.indexes.at(i)->index; QModelIndex source_index = proxy_to_source(proxy_index); source_indexes.append(source_index); } return source_indexes;}/*! \internal Maps \a source_indexes to proxy indexes and stores those as persistent indexes.*/void QSortFilterProxyModelPrivate::update_persistent_indexes( const QModelIndexList &source_indexes){ for (int i = 0; i < source_indexes.count(); ++i) { QModelIndex source_index = source_indexes.at(i); create_mapping(source_index.parent()); QModelIndex proxy_index = source_to_proxy(source_index); persistent.indexes[i]->index = proxy_index; }}/*! \internal Updates the proxy model (adds/removes rows) based on the new filter.*/void QSortFilterProxyModelPrivate::filter_changed(){ QMap<QModelIndex, Mapping *>::const_iterator it; for (it = source_index_mapping.constBegin(); it != source_index_mapping.constEnd(); ++it) { QModelIndex source_parent = it.key(); Mapping *m = it.value(); handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); }}/*! \internal*/void QSortFilterProxyModelPrivate::handle_filter_changed( QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, const QModelIndex &source_parent, Qt::Orientation orient){ Q_Q(QSortFilterProxyModel); // Figure out which mapped items to remove QVector<int> source_items_remove; foreach (int source_item, proxy_to_source) { if ((orient == Qt::Vertical) ? !q->filterAcceptsRow(source_item, source_parent) : !q->filterAcceptsColumn(source_item, source_parent)) { // This source item does not satisfy the filter, so it must be removed source_items_remove.append(source_item); } } // Figure out which non-mapped items to insert QVector<int> source_items_insert; int source_count = source_to_proxy.size(); for (int source_item = 0; source_item < source_count; ++source_item) { if (source_to_proxy.at(source_item) == -1) { if ((orient == Qt::Vertical) ? q->filterAcceptsRow(source_item, source_parent) : q->filterAcceptsColumn(source_item, source_parent)) { // This source item satisfies the filter, so it must be added source_items_insert.append(source_item); } } } if (!source_items_remove.isEmpty() || !source_items_insert.isEmpty()) { // Do item removal and insertion remove_source_items(source_to_proxy, proxy_to_source, source_items_remove, source_parent, orient); if (orient == Qt::Vertical) sort_source_rows(source_items_insert, source_parent); insert_source_items(source_to_proxy, proxy_to_source, source_items_insert, source_parent, orient); }}void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right){ Q_Q(QSortFilterProxyModel); if (!source_top_left.isValid() || !source_bottom_right.isValid()) return; QModelIndex source_parent = source_top_left.parent(); IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); if (it == source_index_mapping.constEnd()) { // Don't care, since we don't have mapping for this index return; } Mapping *m = it.value(); // Figure out how the source changes affect us QVector<int> source_rows_remove; QVector<int> source_rows_insert; QVector<int> source_rows_change; QVector<int> source_rows_resort; int end = qMin(source_bottom_right.row(), m->proxy_rows.count() - 1); for (int source_row = source_top_left.row(); source_row <= end; ++source_row) { if (dynamic_sortfilter) { if (m->proxy_rows.at(source_row) != -1) { if (!q->filterAcceptsRow(source_row, source_parent)) { // This source row no longer satisfies the filter, so it must be removed source_rows_remove.append(source_row); } else if (sort_column >= source_top_left.column() && sort_column <= source_bottom_right.column()) { // This source row has changed in a way that may affect sorted order source_rows_resort.append(source_row); } else { // This row has simply changed, without affecting filtering nor sorting source_rows_change.append(source_row); } } else { if (q->filterAcceptsRow(source_row, source_parent)) { // This source row now satisfies the filter, so it must be added source_rows_insert.append(source_row); } } } else { if (m->proxy_rows.at(source_row) != -1) source_rows_change.append(source_row); } } if (!source_rows_remove.isEmpty()) remove_source_items(m->proxy_rows, m->source_rows, source_rows_remove, source_parent, Qt::Vertical); if (!source_rows_resort.isEmpty()) { // Re-sort the rows emit q->layoutAboutToBeChanged(); QModelIndexList source_indexes = store_persistent_indexes(); remove_source_items(m->proxy_rows, m->source_rows, source_rows_resort, source_parent, Qt::Vertical, false); sort_source_rows(source_rows_resort, source_parent); insert_source_items(m->proxy_rows, m->source_rows, source_rows_resort, source_parent, Qt::Vertical, false); update_persistent_indexes(source_indexes); emit q->layoutChanged(); } else if (!source_rows_change.isEmpty()) { // Find the proxy row range int proxy_start_row; int proxy_end_row; proxy_item_range(m->proxy_rows, source_rows_change, proxy_start_row, proxy_end_row); // ### Find the proxy column range also if (proxy_end_row >= 0) { QModelIndex proxy_top_left = create_index( proxy_start_row, m->proxy_columns.at(source_top_left.column()), it); QModelIndex proxy_bottom_right = create_index( proxy_end_row, m->proxy_columns.at(source_bottom_right.column()), it); emit q->dataChanged(proxy_top_left, proxy_bottom_right); } } if (!source_rows_insert.isEmpty()) { sort_source_rows(source_rows_insert, source_parent); insert_source_items(m->proxy_rows, m->source_rows, source_rows_insert, source_parent, Qt::Vertical); }}void QSortFilterProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end){ Q_Q(QSortFilterProxyModel); Mapping *m = create_mapping(QModelIndex()).value(); int proxy_start = (orientation == Qt::Vertical ? m->proxy_rows.at(start) : m->proxy_columns.at(start)); int proxy_end = (orientation == Qt::Vertical ? m->proxy_rows.at(end) : m->proxy_columns.at(end)); emit q->headerDataChanged(orientation, proxy_start, proxy_end);}void QSortFilterProxyModelPrivate::_q_sourceReset(){ Q_Q(QSortFilterProxyModel); // All internal structures are deleted in clear() q->reset();}void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(){ Q_Q(QSortFilterProxyModel); saved_persistent_indexes.clear(); if (persistent.indexes.isEmpty()) return; emit q->layoutAboutToBeChanged(); QModelIndexList source_indexes = store_persistent_indexes(); QModelIndexList::const_iterator it; for(it = source_indexes.constBegin(); it != source_indexes.constEnd(); ++it) saved_persistent_indexes << (*it);}void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(){ Q_Q(QSortFilterProxyModel); if (saved_persistent_indexes.isEmpty()) { q->clear(); return; } QModelIndexList source_indexes; QList<QPersistentModelIndex>::const_iterator it; it = saved_persistent_indexes.constBegin(); for ( ; it != saved_persistent_indexes.constEnd(); ++it) source_indexes << (*it); qDeleteAll(source_index_mapping); source_index_mapping.clear(); update_persistent_indexes(source_indexes); saved_persistent_indexes.clear(); emit q->layoutChanged();}void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( const QModelIndex &source_parent, int start, int end){ Q_UNUSED(source_parent); Q_UNUSED(start); Q_UNUSED(end);}void QSortFilterProxyModelPrivate::_q_sourceRowsInserted( const QModelIndex &source_parent, int start, int end){ source_items_inserted(source_parent, start, end, Qt::Vertical);}void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeRemoved( const QModelIndex &source_parent, int start, int end){ source_items_about_to_be_removed(source_parent, start, end, Qt::Vertical);}void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( const QModelIndex &source_parent, int start, int end){ source_items_removed(source_parent, start, end, Qt::Vertical);}void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( const QModelIndex &source_parent, int start, int end){ Q_UNUSED(source_parent); Q_UNUSED(start); Q_UNUSED(end);}void QSortFilterProxyModelPrivate::_q_sourceColumnsInserted( const QModelIndex &source_parent, int start, int end){ source_items_inserted(source_parent, start, end, Qt::Horizontal);}void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved( const QModelIndex &source_parent, int start, int end)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?