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 + -
显示快捷键?