QIdentityProxyModel: add setHandleSourceLayoutChanges(bool)
Some sub-classes have special handling of source model layout changes (abbreviated as SMLC from here on out), 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 recent changes (and the method were renamed to remove _q_ prefix). 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 SMLC to them. Thanks to David Faure for the idea/solution. [ChangeLog][QtCore][QIdentityProxyModel] Added setHandleSourceLayoutChanges(bool) method to allow sub-classes to indicate to QIdentityProxyModel that they will handle source model layout changes on their own. Also added a getter, isHandleSourceLayoutChanges(). Change-Id: I1de79dd693ce32a6e2df9a7c81dd4abdc5f00248 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
parent
1648d2d93a
commit
675b4f63fe
@ -335,16 +335,52 @@ void QIdentityProxyModel::setSourceModel(QAbstractItemModel* newSourceModel)
|
||||
&QIdentityProxyModelPrivate::sourceDataChanged),
|
||||
QObjectPrivate::connect(m, &QAbstractItemModel::headerDataChanged, d,
|
||||
&QIdentityProxyModelPrivate::sourceHeaderDataChanged),
|
||||
QObjectPrivate::connect(m, &QAbstractItemModel::layoutAboutToBeChanged, d,
|
||||
&QIdentityProxyModelPrivate::sourceLayoutAboutToBeChanged),
|
||||
QObjectPrivate::connect(m, &QAbstractItemModel::layoutChanged, d,
|
||||
&QIdentityProxyModelPrivate::sourceLayoutChanged),
|
||||
};
|
||||
|
||||
if (d->m_handleLayoutChanges) {
|
||||
d->m_sourceModelConnections.emplace_back(
|
||||
QObjectPrivate::connect(m, &QAbstractItemModel::layoutAboutToBeChanged, d,
|
||||
&QIdentityProxyModelPrivate::sourceLayoutAboutToBeChanged));
|
||||
d->m_sourceModelConnections.emplace_back(
|
||||
QObjectPrivate::connect(m, &QAbstractItemModel::layoutChanged, d,
|
||||
&QIdentityProxyModelPrivate::sourceLayoutChanged));
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.7
|
||||
|
||||
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).
|
||||
|
||||
The default is for this proxy model to handle the source model layout
|
||||
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 layout changes.
|
||||
|
||||
\note Calling this method will only have an effect after calling setSourceModel().
|
||||
*/
|
||||
void QIdentityProxyModel::setHandleSourceLayoutChanges(bool b)
|
||||
{
|
||||
d_func()->m_handleLayoutChanges = b;
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.7
|
||||
|
||||
Returns \c true if this proxy model handles the source model layout
|
||||
changes, otherwise returns \c false.
|
||||
*/
|
||||
bool QIdentityProxyModel::isHandleSourceLayoutChanges() const
|
||||
{
|
||||
return d_func()->m_handleLayoutChanges;
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
|
@ -44,8 +44,11 @@ public:
|
||||
bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
|
||||
bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) override;
|
||||
|
||||
bool isHandleSourceLayoutChanges() const;
|
||||
|
||||
protected:
|
||||
QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
|
||||
void setHandleSourceLayoutChanges(bool);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QIdentityProxyModel)
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
void sourceModelReset();
|
||||
|
||||
private:
|
||||
bool m_handleLayoutChanges = true;
|
||||
QVarLengthArray<QMetaObject::Connection, 18> m_sourceModelConnections;
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,16 @@ public:
|
||||
const QModelIndex idx = index(0, 0, QModelIndex());
|
||||
Q_EMIT dataChanged(idx, idx, QList<int>() << 1);
|
||||
}
|
||||
|
||||
// Workaround QObject::isSignalConnected() being a protected method
|
||||
bool isConnected(const QMetaMethod &m) const { return isSignalConnected(m); }
|
||||
};
|
||||
|
||||
class IdentityProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
public:
|
||||
// The name has to be different than the method from the base class
|
||||
void setHandleSLC(bool b) { setHandleSourceLayoutChanges(b); }
|
||||
};
|
||||
|
||||
class tst_QIdentityProxyModel : public QObject
|
||||
@ -53,6 +63,9 @@ private slots:
|
||||
|
||||
void persistIndexOnLayoutChange();
|
||||
void createPersistentOnLayoutAboutToBeChanged();
|
||||
|
||||
void testSetHandleLayoutChanges();
|
||||
|
||||
protected:
|
||||
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
|
||||
|
||||
@ -513,5 +526,27 @@ void tst_QIdentityProxyModel::createPersistentOnLayoutAboutToBeChanged() // QTBU
|
||||
QCOMPARE(layoutChangedSpy.size(), 1);
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::testSetHandleLayoutChanges()
|
||||
{
|
||||
const std::array layoutSignals = {
|
||||
QMetaMethod::fromSignal(&QAbstractItemModel::layoutChanged),
|
||||
QMetaMethod::fromSignal(&QAbstractItemModel::layoutAboutToBeChanged),
|
||||
};
|
||||
|
||||
DataChangedModel model;
|
||||
IdentityProxyModel proxy;
|
||||
proxy.setSourceModel(&model);
|
||||
for (const auto &m : layoutSignals)
|
||||
QVERIFY(model.isConnected(m)); // Connected by default
|
||||
|
||||
proxy.setSourceModel(nullptr);
|
||||
|
||||
// Disable handling (connecting to layotu signals) of source model layout changes
|
||||
proxy.setHandleSLC(false);
|
||||
proxy.setSourceModel(&model);
|
||||
for (const auto &m : layoutSignals)
|
||||
QVERIFY(!model.isConnected(m));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QIdentityProxyModel)
|
||||
#include "tst_qidentityproxymodel.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user