QIdentityProxyModel: add setHandleSourceDataChanges(bool)

Some sub-classes have special handling of source model data changes,
they relied on disconnecting the connections to the _q_*layout* slots
in the private class using the SLOT macro. This isn't possible any more
after the recent port to PMF connects.

Sub-classes resorting to using private API is a clear sign some
functionality is missing from the public API, so a cleaner solution for
this issue is adding this setter which enables sub-classes to tell
QIdentityProxyModel to leave handling of the dataChanged signal to them.

Similar to commit 675b4f63feab7c81c75e49f6dea82a39dd18f489 (but
this should be the last one needed).

[ChangeLog][QtCore][QIdentityProxyModel] Added
setHandleSourceDataChanges(bool) method to allow sub-classes to
indicate to QIdentityProxyModel that they will handle source model
data changes on their own. Also added a getter,
isHandleSourceDataChanges().

Task-number: QTBUG-127959
Change-Id: Id8f567c330e4ee834940a62b6497d8cbb8ba4a46
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 5a31800d41273a14436c543438a142562f74f857)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
David Faure 2024-08-11 11:45:56 +02:00 committed by Qt Cherry-pick Bot
parent 4ba6cd2dcd
commit 2b50551923
4 changed files with 59 additions and 4 deletions

View File

@ -331,12 +331,15 @@ void QIdentityProxyModel::setSourceModel(QAbstractItemModel* newSourceModel)
&QIdentityProxyModelPrivate::sourceModelAboutToBeReset),
QObjectPrivate::connect(m, &QAbstractItemModel::modelReset, d,
&QIdentityProxyModelPrivate::sourceModelReset),
QObjectPrivate::connect(m, &QAbstractItemModel::dataChanged, d,
&QIdentityProxyModelPrivate::sourceDataChanged),
QObjectPrivate::connect(m, &QAbstractItemModel::headerDataChanged, d,
&QIdentityProxyModelPrivate::sourceHeaderDataChanged),
};
if (d->m_handleDataChanges) {
d->m_sourceModelConnections.emplace_back(
QObjectPrivate::connect(m, &QAbstractItemModel::dataChanged, d,
&QIdentityProxyModelPrivate::sourceDataChanged));
}
if (d->m_handleLayoutChanges) {
d->m_sourceModelConnections.emplace_back(
QObjectPrivate::connect(m, &QAbstractItemModel::layoutAboutToBeChanged, d,
@ -355,7 +358,7 @@ void QIdentityProxyModel::setSourceModel(QAbstractItemModel* newSourceModel)
If \a b is \c true, this proxy model will handle the source model layout
changes (by connecting to \c QAbstractItemModel::layoutAboutToBeChanged
and \c QAbstractItemModel::layoutChanged singals).
and \c QAbstractItemModel::layoutChanged signals).
The default is for this proxy model to handle the source model layout
changes.
@ -381,6 +384,36 @@ bool QIdentityProxyModel::handleSourceLayoutChanges() const
return d_func()->m_handleLayoutChanges;
}
/*!
\since 6.8
If \a b is \c true, this proxy model will handle the source model data
changes (by connecting to \c QAbstractItemModel::dataChanged signal).
The default is for this proxy model to handle the source model data
changes.
In sub-classes of QIdentityProxyModel, it may be useful to set this to
\c false if you need to specially handle the source model data changes.
\note Calling this method will only have an effect after calling setSourceModel().
*/
void QIdentityProxyModel::setHandleSourceDataChanges(bool b)
{
d_func()->m_handleDataChanges = b;
}
/*!
\since 6.8
Returns \c true if this proxy model handles the source model data
changes, otherwise returns \c false.
*/
bool QIdentityProxyModel::handleSourceDataChanges() const
{
return d_func()->m_handleDataChanges;
}
void QIdentityProxyModelPrivate::sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
{
Q_ASSERT(parent.isValid() ? parent.model() == model : true);

View File

@ -45,10 +45,12 @@ public:
bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) override;
bool handleSourceLayoutChanges() const;
bool handleSourceDataChanges() const;
protected:
QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
void setHandleSourceLayoutChanges(bool);
void setHandleSourceDataChanges(bool);
private:
Q_DECLARE_PRIVATE(QIdentityProxyModel)

View File

@ -64,6 +64,7 @@ public:
private:
bool m_handleLayoutChanges = true;
bool m_handleDataChanges = true;
QVarLengthArray<QMetaObject::Connection, 18> m_sourceModelConnections;
};

View File

@ -37,6 +37,7 @@ class IdentityProxyModel : public QIdentityProxyModel
public:
// The name has to be different than the method from the base class
void setHandleSLC(bool b) { setHandleSourceLayoutChanges(b); }
void setHandleSDC(bool b) { setHandleSourceDataChanges(b); }
};
class tst_QIdentityProxyModel : public QObject
@ -65,6 +66,7 @@ private slots:
void createPersistentOnLayoutAboutToBeChanged();
void testSetHandleLayoutChanges();
void testSetHandleDataChanges();
protected:
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
@ -541,12 +543,29 @@ void tst_QIdentityProxyModel::testSetHandleLayoutChanges()
proxy.setSourceModel(nullptr);
// Disable handling (connecting to layotu signals) of source model layout changes
// Disable handling (connecting to layout signals) of source model layout changes
proxy.setHandleSLC(false);
proxy.setSourceModel(&model);
for (const auto &m : layoutSignals)
QVERIFY(!model.isConnected(m));
}
void tst_QIdentityProxyModel::testSetHandleDataChanges()
{
const auto signal = QMetaMethod::fromSignal(&QAbstractItemModel::dataChanged);
DataChangedModel model;
IdentityProxyModel proxy;
proxy.setSourceModel(&model);
QVERIFY(model.isConnected(signal)); // Connected by default
proxy.setSourceModel(nullptr);
// Disable handling (connecting to data signals) of source model data changes
proxy.setHandleSDC(false);
proxy.setSourceModel(&model);
QVERIFY(!model.isConnected(signal));
}
QTEST_MAIN(tst_QIdentityProxyModel)
#include "tst_qidentityproxymodel.moc"