KItemModels
kselectionproxymodel.cpp
152 // F is selected, then C then D. When inserting D into the model, the commonParent is B (the parent of C).
153 // The next existing sibling of B is F (in the proxy model). bestParentRow will then refer to an index on
154 // the level of a child of F (which doesn't exist - Boom!). If it doesn't exist, then we've already found
189 // and requiring a similar result if the next sibling in the proxy model does not have children.
228 // If D, E and J are already selected, and H is newly selected, we need to put H between E and J in the proxy model.
231 // selected (F above has siblings B, E and I which have descendants which are already selected).
281 if (isDescendantOf(rootSelection, range.topLeft()) || isDescendantOf(selection, range.topLeft())) {
416 // A unique id is generated for each parent. It is used for the internalPointer of its children in the proxy
418 // If an index newly gets children it is added to this hash. If its last child is removed it is removed from this map.
419 // If this map contains an index, that index hasChildren(). This hash is populated when new rows are inserted in the
433 Instead of using persistentindexes for proxy indexes in m_mappedParents, we maintain them ourselves with this method.
469 * Maps @p parent to source if it is already mapped, and otherwise returns an invalid QModelIndex.
488 This method works only if the index has children in the proxy model which already has a mapping from the source.
490 This means that if the proxy is a flat list, this method will always return QModelIndex(). Additionally, it means that m_mappedParents is not populated
500 This method works only if the index has children in the proxy model which already has a mapping from the source.
538 void sourceRowsAboutToBeMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow);
539 void sourceRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow);
544 void emitContinuousRanges(const QModelIndex &sourceFirst, const QModelIndex &sourceLast, const QModelIndex &proxyFirst, const QModelIndex &proxyLast);
563 If m_startWithChildTrees is true, this method returns the row in the proxy model to insert newIndex
566 This is a special case because the items above rootListRow in the list are not in the model, but
640 // const QModelIndex sourceHalfWay = sourceFirst.sibling(sourceFirst.row() + (sourceRangeSize / 2));
641 // const QModelIndex proxyHalfWay = proxyFirst.sibling(proxyFirst.row() + (proxyRangeSize / 2));
649 // Q_EMIT q->dataChanged(proxyFirst, proxyLast.sibling(proxyFirst.row() + proxyRangeSize, proxyLast.column()));
656void KSelectionProxyModelPrivate::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
664 if (!sourceRangeParent.isValid() && m_startWithChildTrees && !m_rootIndexList.contains(sourceRangeParent)) {
681 if ((m_omitChildren && !m_startWithChildTrees && m_includeAllSelected) || (!proxyRangeParent.isValid() && !m_startWithChildTrees)) {
791 // The problem is that anything can happen between emissions of layoutAboutToBeChanged and layoutChanged.
792 // We can't assume anything is the same about the structure anymore. items have been sorted, items which
793 // were parents before are now not, items which were not parents before now are, items which used to be the
794 // first child are now the Nth child and items which used to be the Nth child are now the first child.
795 // We effectively can't update our mapping because we don't have enough information to update everything.
812 q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i)));
910 // If parentPosition == 0, then parent.parent() is not also in the model. (ordering is preserved)
940 const QPersistentModelIndex previousFirstChild = q->sourceModel()->index(offset, column, parent);
942 SourceIndexProxyRowMapping::left_iterator it = m_mappedFirstChildren.findLeft(previousFirstChild);
953 // The proxy row in the mapping has already been updated by the offset in updateInternalTopIndexes
958QPair<int, int> KSelectionProxyModelPrivate::beginInsertRows(const QModelIndex &parent, int start, int end) const
993void KSelectionProxyModelPrivate::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1009 // topLevel insertions can be ignored because topLevel items would need to be selected to affect the proxy.
1042 // We already have a first child mapping, but what we have mapped is not the first child anymore
1058void KSelectionProxyModelPrivate::sourceRowsInserted(const QModelIndex &parent, int start, int end)
1076static bool rootWillBeRemovedFrom(const QModelIndex &ancestor, int start, int end, const QModelIndex &root)
1091bool KSelectionProxyModelPrivate::rootWillBeRemoved(const QItemSelection &selection, const QModelIndex &root)
1109QPair<int, int> KSelectionProxyModelPrivate::beginRemoveRows(const QModelIndex &parent, int start, int end) const
1167void KSelectionProxyModelPrivate::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1186 m_recreateFirstChildMappingOnRemoval = m_mappedFirstChildren.leftContains(q->sourceModel()->index(start, 0, parent));
1190void KSelectionProxyModelPrivate::endRemoveRows(const QModelIndex &sourceParent, int proxyStart, int proxyEnd)
1203 // to row 0 instead of row 1. If that is done before removing the mapping for B, then the mapping
1204 // for D would overwrite the mapping for B and then the code for removing mappings would incorrectly
1258void KSelectionProxyModelPrivate::sourceRowsRemoved(const QModelIndex &parent, int start, int end)
1290void KSelectionProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow)
1302void KSelectionProxyModelPrivate::sourceRowsMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow)
1314QModelIndex KSelectionProxyModelPrivate::mapParentToSource(const QModelIndex &proxyParent) const
1319QModelIndex KSelectionProxyModelPrivate::mapParentFromSource(const QModelIndex &sourceParent) const
1325indexIsValid(bool startWithChildTrees, int row, const QList<QPersistentModelIndex> &rootIndexList, const SourceIndexProxyRowMapping &mappedFirstChildren)
1332 SourceIndexProxyRowMapping::right_const_iterator result = std::prev(mappedFirstChildren.rightUpperBound(row));
1340 Q_ASSERT(row <= proxyFirstRow + sourceFirstChild.model()->rowCount(sourceFirstChild.parent()));
1353QModelIndex KSelectionProxyModelPrivate::mapTopLevelFromSource(const QModelIndex &sourceIndex) const
1383 // Q_ASSERT((!d->m_startWithChildTrees && d->m_rootIndexList.contains(maybeMapped)) ? maybeMapped.row() < 0 : true );
1416 const SourceIndexProxyRowMapping::right_const_iterator result = std::prev(m_mappedFirstChildren.rightConstEnd());
1456 // sourceIndex can be mapped to the proxy. We just need to create mappings for its ancestors first.
1463 const QModelIndex newProxyParent = q->createIndex(newSourceParent.row(), newSourceParent.column(), ansId);
1496void KSelectionProxyModelPrivate::updateInternalIndexes(const QModelIndex &parent, int start, int offset)
1534 const QModelIndex newIndex = q->createIndex(proxyIndex.row() + offset, proxyIndex.column(), proxyIndex.internalPointer());
1544 const QHash<QPersistentModelIndex, QModelIndex>::const_iterator end = updatedParents.constEnd();
1575void KSelectionProxyModelPrivate::createFirstChildMapping(const QModelIndex &parent, int proxyRow) const
1594void KSelectionProxyModelPrivate::createParentMappings(const QModelIndex &parent, int start, int end) const
1628 const SourceIndexProxyRowMapping::right_iterator endIt = m_mappedFirstChildren.rightUpperBound(end);
1634void KSelectionProxyModelPrivate::removeParentMappings(const QModelIndex &parent, int start, int end)
1679 SourceIndexProxyRowMapping::right_iterator result = std::prev(m_mappedFirstChildren.rightUpperBound(row));
1755void KSelectionProxyModelPrivate::selectionChanged(const QItemSelection &_selected, const QItemSelection &_deselected)
1773 // indexes in the selected range which are not a descendant of one of the already selected indexes
1776 // All ranges from the selection model need to be split into individual rows. Ranges which are contiguous in
1777 // the selection model may not be contiguous in the source model if there's a sort filter proxy model in the chain.
1779 // Some descendants of deselected indexes may still be selected. The ranges in m_selectionModel->selection()
1785 const QItemSelection selected = kNormalizeSelection(m_indexMapper->mapSelectionRightToLeft(_selected));
1786 const QItemSelection deselected = kNormalizeSelection(m_indexMapper->mapSelectionRightToLeft(_deselected));
1795 QItemSelection fullSelection = m_indexMapper->mapSelectionRightToLeft(m_selectionModel->selection());
1809 // This is similar to m_rootRanges, but that m_rootRanges at this point still contains the roots
1843 // range is not a descendant of the selection, but maybe the selection is a descendant of range.
1851 // But D is also a descendant of part of the new selection C, which is already set to be a new root
1992KSelectionProxyModel::KSelectionProxyModel(QItemSelectionModel *selectionModel, QObject *parent)
2098 d->m_indexMapper = new KModelIndexProxyMapper(_sourceModel, d->m_selectionModel->model(), this);
2104 connect(_sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, [d](const QModelIndex &parent, int start, int end) {
2108 connect(_sourceModel, &QAbstractItemModel::rowsInserted, this, [d](const QModelIndex &parent, int start, int end) {
2112 connect(_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, [d](const QModelIndex &parent, int start, int end) {
2116 connect(_sourceModel, &QAbstractItemModel::rowsRemoved, this, [d](const QModelIndex &parent, int start, int end) {
2123 [d](const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow) {
2130 [d](const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow) {
2142 connect(_sourceModel, &QAbstractItemModel::dataChanged, this, [d](const QModelIndex &topLeft, const QModelIndex &bottomRight) {
2297QVariant KSelectionProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
2386 connect(d->m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection)));
2398 connect(d->m_selectionModel->model(), SIGNAL(modelAboutToBeReset()), this, SLOT(sourceModelAboutToBeReset()));
2399 d->selectionModelModelResetConnection = connect(d->m_selectionModel->model(), SIGNAL(modelReset()), this, SLOT(sourceModelReset()));
2402 d->m_indexMapper = new KModelIndexProxyMapper(sourceModel(), d->m_selectionModel->model(), this);
2406 connect(d->m_selectionModel.data(), &QItemSelectionModel::modelChanged, this, handleSelectionModelModel);
2412 d->m_indexMapper = new KModelIndexProxyMapper(sourceModel(), d->m_selectionModel->model(), this);
2420bool KSelectionProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
2445 return sourceModel()->dropMimeData(data, action, source_destination_row, source_destination_column, source_parent);
2454QModelIndexList KSelectionProxyModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
2472QItemSelection KSelectionProxyModel::mapSelectionFromSource(const QItemSelection &selection) const
2509QItemSelection KSelectionProxyModel::mapSelectionToSource(const QItemSelection &selection) const
2558 const QModelIndex sourceBottomRight = sourceModel()->index(rowCount - 1, it->right(), sourceParent);
2563 extraSelection.append(QItemSelectionRange(createIndex(it->top() - rowCount, it->right()), it->bottomRight()));
ContentIndex index() const
This class facilitates easy mapping of indexes and selections through proxy models.
Definition kmodelindexproxymapper.h:75
QItemSelection mapSelectionRightToLeft(const QItemSelection &selection) const
Maps the selection from the right model to the left model.
Definition kmodelindexproxymapper.cpp:236
A Proxy Model which presents a subset of its source model to observers.
Definition kselectionproxymodel.h:77
void setFilterBehavior(FilterBehavior behavior)
Set the filter behaviors of this model.
Definition kselectionproxymodel.cpp:2007
void setSourceModel(QAbstractItemModel *sourceModel) override
reimp.
Definition kselectionproxymodel.cpp:2075
Q_SCRIPTABLE Q_NOREPLY void start()
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & end()
MESSAGECORE_EXPORT KMime::Content * firstChild(const KMime::Content *node)
MESSAGECORE_EXPORT KMime::Content * nextSibling(const KMime::Content *node)
void beginResetModel()
QModelIndex createIndex(int row, int column, const void *ptr) const const
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles)
void endResetModel()
bool hasIndex(int row, int column, const QModelIndex &parent) const const
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const const
void modelAboutToBeReset()
void modelReset()
virtual int rowCount(const QModelIndex &parent) const const=0
void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
void rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
void rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
void rowsInserted(const QModelIndex &parent, int first, int last)
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
void rowsRemoved(const QModelIndex &parent, int first, int last)
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
virtual QMimeData * mimeData(const QModelIndexList &indexes) const const override
virtual QStringList mimeTypes() const const override
virtual void setSourceModel(QAbstractItemModel *sourceModel)
sourceModel
virtual Qt::DropActions supportedDropActions() const const override
const_iterator constBegin() const const
const_iterator constEnd() const const
iterator insert(const Key &key, const T &value)
bool contains(const QModelIndex &index) const const
QModelIndexList indexes() const const
void merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command)
Deselect
void modelChanged(QAbstractItemModel *model)
const QPersistentModelIndex & bottomRight() const const
bool contains(const QModelIndex &index) const const
const QPersistentModelIndex & topLeft() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
iterator begin()
void clear()
const_iterator constBegin() const const
const_iterator constEnd() const const
bool contains(const AT &value) const const
iterator end()
iterator erase(const_iterator begin, const_iterator end)
T & first()
qsizetype indexOf(const AT &value, qsizetype from) const const
iterator insert(const_iterator before, parameter_type value)
bool isEmpty() const const
qsizetype size() const const
int column() const const
void * internalPointer() const const
bool isValid() const const
const QAbstractItemModel * model() const const
QModelIndex parent() const const
int row() const const
QModelIndex sibling(int row, int column) const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
T qobject_cast(QObject *object)
bool isValid() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
typedef DropActions
UserRole
typedef ItemFlags
typedef MatchFlags
Orientation
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.