Provide the resetInternalData slot to cleanly reset data in proxy subclasses.
This was part of Qt 4.8, but Qt 5.0 was branched before that, so the commit was lost. Change-Id: I2a2ab3c75a0943ac734d588ebd74bc158dd6aaaf Reviewed-by: Nils Jeisecke <jeisecke@saltation.de> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
b28d56588a
commit
8eae3a923a
@ -97,3 +97,37 @@ beginResetModel();
|
||||
myData.clear();
|
||||
endResetModel();
|
||||
//! [11]
|
||||
|
||||
//! [12]
|
||||
class CustomDataProxy : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CustomDataProxy(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
QVariant data(const QModelIndex &index, int role)
|
||||
{
|
||||
if (role != Qt::BackgroundRole)
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
|
||||
if (m_customData.contains(index.row()))
|
||||
return m_customData.value(index.row());
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void resetInternalData()
|
||||
{
|
||||
m_customData.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
QHash<int, QVariant> m_customData;
|
||||
};
|
||||
//! [12]
|
||||
|
||||
|
@ -865,6 +865,27 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.8
|
||||
|
||||
This slot is called just after the internal data of a model is cleared
|
||||
while it is being reset.
|
||||
|
||||
This slot is provided the convenience of subclasses of concrete proxy
|
||||
models, such as subclasses of QSortFilterProxyModel which maintain extra
|
||||
data.
|
||||
|
||||
\snippet code/src_corelib_kernel_qabstractitemmodel.cpp 12
|
||||
|
||||
\note Due to a mistake, this slot is missing in Qt 5.0.
|
||||
|
||||
\sa modelAboutToBeReset(), modelReset()
|
||||
*/
|
||||
void QAbstractItemModel::resetInternalData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QModelIndex
|
||||
\inmodule QtCore
|
||||
@ -3055,6 +3076,7 @@ void QAbstractItemModel::endResetModel()
|
||||
{
|
||||
Q_D(QAbstractItemModel);
|
||||
d->invalidatePersistentIndexes();
|
||||
QMetaObject::invokeMethod(this, "resetInternalData");
|
||||
emit modelReset(QPrivateSignal());
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,10 @@ public Q_SLOTS:
|
||||
virtual bool submit();
|
||||
virtual void revert();
|
||||
|
||||
protected Q_SLOTS:
|
||||
// Qt 6: Make virtual
|
||||
void resetInternalData();
|
||||
|
||||
protected:
|
||||
QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0);
|
||||
|
||||
|
@ -136,6 +136,7 @@ private slots:
|
||||
|
||||
void testMultipleProxiesWithSelection();
|
||||
void mapSelectionFromSource();
|
||||
void testResetInternalData();
|
||||
void filteredColumns();
|
||||
void headerDataChanged();
|
||||
|
||||
@ -3242,6 +3243,143 @@ void tst_QSortFilterProxyModel::resetInvalidate()
|
||||
QCOMPARE(ok, works);
|
||||
}
|
||||
|
||||
/**
|
||||
* A proxy which changes the background color for items ending in 'y' or 'r'
|
||||
*/
|
||||
class CustomDataProxy : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CustomDataProxy(QObject *parent = 0)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setDynamicSortFilter(true);
|
||||
}
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
// It would be possible to use only the modelReset signal of the source model to clear
|
||||
// the data in *this, however, this requires that the slot is connected
|
||||
// before QSortFilterProxyModel::setSourceModel is called, and even then depends
|
||||
// on the order of invocation of slots being the same as the order of connection.
|
||||
// ie, not reliable.
|
||||
// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
|
||||
QSortFilterProxyModel::setSourceModel(sourceModel);
|
||||
// Making the connect after the setSourceModel call clears the data too late.
|
||||
// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData()));
|
||||
|
||||
// This could be done in data(), but the point is to need to cache something in the proxy
|
||||
// which needs to be cleared on reset.
|
||||
for (int i = 0; i < sourceModel->rowCount(); ++i)
|
||||
{
|
||||
if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y')))
|
||||
{
|
||||
m_backgroundColours.insert(i, Qt::blue);
|
||||
} else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r')))
|
||||
{
|
||||
m_backgroundColours.insert(i, Qt::red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::BackgroundRole)
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
return m_backgroundColours.value(index.row());
|
||||
}
|
||||
|
||||
private slots:
|
||||
void resetInternalData()
|
||||
{
|
||||
m_backgroundColours.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
QHash<int, QColor> m_backgroundColours;
|
||||
};
|
||||
|
||||
class ModelObserver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ModelObserver(QAbstractItemModel *model, QObject *parent = 0)
|
||||
: QObject(parent), m_model(model)
|
||||
{
|
||||
connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset()));
|
||||
connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
|
||||
}
|
||||
|
||||
public slots:
|
||||
void modelAboutToBeReset()
|
||||
{
|
||||
int reds = 0, blues = 0;
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
|
||||
if (color == Qt::blue)
|
||||
++blues;
|
||||
if (color == Qt::red)
|
||||
++reds;
|
||||
}
|
||||
QCOMPARE(blues, 11);
|
||||
QCOMPARE(reds, 4);
|
||||
}
|
||||
|
||||
void modelReset()
|
||||
{
|
||||
int reds = 0, blues = 0;
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>();
|
||||
if (color == Qt::blue)
|
||||
++blues;
|
||||
if (color == Qt::red)
|
||||
++reds;
|
||||
}
|
||||
QCOMPARE(reds, 0);
|
||||
QCOMPARE(blues, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
QAbstractItemModel * const m_model;
|
||||
|
||||
};
|
||||
|
||||
void tst_QSortFilterProxyModel::testResetInternalData()
|
||||
{
|
||||
|
||||
QStringListModel model(QStringList() << "Monday"
|
||||
<< "Tuesday"
|
||||
<< "Wednesday"
|
||||
<< "Thursday"
|
||||
<< "Friday"
|
||||
<< "January"
|
||||
<< "February"
|
||||
<< "March"
|
||||
<< "April"
|
||||
<< "May"
|
||||
<< "Saturday"
|
||||
<< "June"
|
||||
<< "Sunday"
|
||||
<< "July"
|
||||
<< "August"
|
||||
<< "September"
|
||||
<< "October"
|
||||
<< "November"
|
||||
<< "December");
|
||||
|
||||
CustomDataProxy proxy;
|
||||
proxy.setSourceModel(&model);
|
||||
|
||||
ModelObserver observer(&proxy);
|
||||
|
||||
// Cause the source model to reset.
|
||||
model.setStringList(QStringList() << "Spam" << "Eggs");
|
||||
|
||||
}
|
||||
|
||||
void tst_QSortFilterProxyModel::testParentLayoutChanged()
|
||||
{
|
||||
QStandardItemModel model;
|
||||
|
Loading…
x
Reference in New Issue
Block a user