Allow proxy models access to the parent-child hierarchy of source

As discussed in the related bug report, the current way proxy models
access the parent-child hierarchy of the source model requires modifying
Qt sources. This changes adds a method to allow easy implementation
of this common feature to proxy model subclasses.

Fixes: QTBUG-83911
Change-Id: Ic88d40c13c2be7b6b44fcc58118bac471a11da95
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Luca Beldi 2021-04-19 16:51:37 +01:00
parent fed2c0d236
commit 3c74ee5682
5 changed files with 24 additions and 6 deletions

View File

@ -272,8 +272,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject
friend class QPersistentModelIndexData;
friend class QAbstractItemViewPrivate;
friend class QIdentityProxyModel;
friend class QTransposeProxyModelPrivate;
friend class QAbstractProxyModel;
public:
explicit QAbstractItemModel(QObject *parent = nullptr);

View File

@ -474,6 +474,25 @@ QHash<int,QByteArray> QAbstractProxyModel::roleNames() const
return d->model->roleNames();
}
/*!
Equivalent to calling createIndex on the source model.
This method is useful if your proxy model wants to maintain the
parent-child relationship of items in the source model.
When reimplementing mapToSource(), you can call this method to
create an index of the source model.
A typical use would be to save the internal pointer coming from the source model
in the proxy index when reimplementing mapFromSource() and use the same internal
pointer as \a internalPtr to recover the original source index when
reimplementing mapToSource().
\since 6.2
*/
QModelIndex QAbstractProxyModel::createSourceIndex(int row, int col, void *internalPtr) const
{
if (sourceModel())
return sourceModel()->createIndex(row, col, internalPtr);
return QModelIndex();
}
QT_END_NAMESPACE

View File

@ -102,6 +102,7 @@ Q_SIGNALS:
void sourceModelChanged(QPrivateSignal);
protected:
QModelIndex createSourceIndex(int row, int col, void *internalPtr) const;
QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
private:

View File

@ -257,7 +257,7 @@ QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) cons
if (!d->model || !proxyIndex.isValid())
return QModelIndex();
Q_ASSERT(proxyIndex.model() == this);
return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
return createSourceIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
}
/*!

View File

@ -49,9 +49,8 @@ QModelIndex QTransposeProxyModelPrivate::uncheckedMapToSource(const QModelIndex
{
if (!model || !proxyIndex.isValid())
return QModelIndex();
if (proxyIndex.internalPointer())
return model->createIndex(proxyIndex.column(), proxyIndex.row(), proxyIndex.internalPointer());
return model->index(proxyIndex.column(), proxyIndex.row());
Q_Q(const QTransposeProxyModel);
return q->createSourceIndex(proxyIndex.column(), proxyIndex.row(), proxyIndex.internalPointer());
}
QModelIndex QTransposeProxyModelPrivate::uncheckedMapFromSource(const QModelIndex &sourceIndex) const