QAbstractProxyModel: Use QCompatProperty with custom getter
Use new API for QCompatProperty with custom getter instead of ad-hoc solution. Task-number: QTBUG-89655 Change-Id: I06481ad4d360b178be001ceb9c6c8460b73391f6 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
eb5cae26a4
commit
de641fbc14
@ -161,8 +161,7 @@ QAbstractItemModel *QAbstractProxyModel::sourceModel() const
|
||||
QBindable<QAbstractItemModel *> QAbstractProxyModel::bindableSourceModel()
|
||||
{
|
||||
Q_D(QAbstractProxyModel);
|
||||
return QBindable<QAbstractItemModel *>(QAbstractProxyModelBindable(
|
||||
&d->model, &QtPrivate::QBindableInterfaceForSourceModel::iface));
|
||||
return QBindable<QAbstractItemModel *>(&d->model);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -59,16 +59,6 @@ QT_REQUIRE_CONFIG(proxymodel);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractProxyModelBindable : public QUntypedBindable
|
||||
{
|
||||
public:
|
||||
explicit QAbstractProxyModelBindable(QUntypedPropertyData *d,
|
||||
const QtPrivate::QBindableInterface *i)
|
||||
: QUntypedBindable(d, i)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QAbstractProxyModelPrivate : public QAbstractItemModelPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QAbstractProxyModel)
|
||||
@ -82,69 +72,17 @@ public:
|
||||
{
|
||||
Q_EMIT q_func()->sourceModelChanged(QAbstractProxyModel::QPrivateSignal());
|
||||
}
|
||||
QAbstractItemModel *getModelForwarder() const { return q_func()->sourceModel(); }
|
||||
|
||||
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QAbstractProxyModelPrivate, QAbstractItemModel *, model,
|
||||
&QAbstractProxyModelPrivate::setModelForwarder,
|
||||
&QAbstractProxyModelPrivate::modelChangedForwarder, nullptr)
|
||||
&QAbstractProxyModelPrivate::modelChangedForwarder,
|
||||
&QAbstractProxyModelPrivate::getModelForwarder, nullptr)
|
||||
virtual void _q_sourceModelDestroyed();
|
||||
void mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
|
||||
int *source_row, int *source_column, QModelIndex *source_parent) const;
|
||||
|
||||
using ModelPropertyType = decltype(model);
|
||||
};
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
/*!
|
||||
The biggest trick for adding new QProperty binding support here is the
|
||||
getter for the sourceModel property (QAbstractProxyModel::sourceModel),
|
||||
which returns nullptr, while internally using a global staticEmptyModel()
|
||||
instance.
|
||||
This lead to inconsistency while binding to a proxy model without source
|
||||
model. The bound object would point to staticEmptyModel() instance, while
|
||||
sourceModel() getter returns nullptr.
|
||||
To solve this issue we need to implement a custom QBindableInterface, with
|
||||
custom getter and makeBinding methods, that would introduce the required
|
||||
logic.
|
||||
*/
|
||||
|
||||
inline QAbstractItemModel *normalizePotentiallyEmptyModel(QAbstractItemModel *model)
|
||||
{
|
||||
if (model == QAbstractItemModelPrivate::staticEmptyModel())
|
||||
return nullptr;
|
||||
return model;
|
||||
}
|
||||
|
||||
class QBindableInterfaceForSourceModel
|
||||
{
|
||||
using PropertyType = QAbstractProxyModelPrivate::ModelPropertyType;
|
||||
using Parent = QBindableInterfaceForProperty<PropertyType>;
|
||||
using T = typename PropertyType::value_type;
|
||||
|
||||
public:
|
||||
static constexpr QBindableInterface iface = {
|
||||
[](const QUntypedPropertyData *d, void *value) -> void {
|
||||
const auto val = static_cast<const PropertyType *>(d)->value();
|
||||
*static_cast<T *>(value) = normalizePotentiallyEmptyModel(val);
|
||||
},
|
||||
Parent::iface.setter,
|
||||
Parent::iface.getBinding,
|
||||
Parent::iface.setBinding,
|
||||
[](const QUntypedPropertyData *d,
|
||||
const QPropertyBindingSourceLocation &location) -> QUntypedPropertyBinding {
|
||||
return Qt::makePropertyBinding(
|
||||
[d]() -> T {
|
||||
return normalizePotentiallyEmptyModel(
|
||||
static_cast<const PropertyType *>(d)->value());
|
||||
},
|
||||
location);
|
||||
},
|
||||
Parent::iface.setObserver,
|
||||
Parent::iface.metaType
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTPROXYMODEL_P_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user