From 3c74ee568289af7500f165c4d29f380eefa1f4b9 Mon Sep 17 00:00:00 2001 From: Luca Beldi Date: Mon, 19 Apr 2021 16:51:37 +0100 Subject: [PATCH] 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 --- src/corelib/itemmodels/qabstractitemmodel.h | 3 +-- .../itemmodels/qabstractproxymodel.cpp | 19 +++++++++++++++++++ src/corelib/itemmodels/qabstractproxymodel.h | 1 + .../itemmodels/qidentityproxymodel.cpp | 2 +- .../itemmodels/qtransposeproxymodel.cpp | 5 ++--- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 789ed60ce4..0b61275d23 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -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); diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index e5d8c68e72..207ff80f2e 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -474,6 +474,25 @@ QHash 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 diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h index ef4feb5564..ae7b8e1a2d 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.h +++ b/src/corelib/itemmodels/qabstractproxymodel.h @@ -102,6 +102,7 @@ Q_SIGNALS: void sourceModelChanged(QPrivateSignal); protected: + QModelIndex createSourceIndex(int row, int col, void *internalPtr) const; QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent); private: diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index 8634ddd520..b2bc43d126 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -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()); } /*! diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp index 83a86d1a97..899f93c2a5 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel.cpp +++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp @@ -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