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();
|
myData.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
//! [11]
|
//! [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
|
\class QModelIndex
|
||||||
\inmodule QtCore
|
\inmodule QtCore
|
||||||
@ -3055,6 +3076,7 @@ void QAbstractItemModel::endResetModel()
|
|||||||
{
|
{
|
||||||
Q_D(QAbstractItemModel);
|
Q_D(QAbstractItemModel);
|
||||||
d->invalidatePersistentIndexes();
|
d->invalidatePersistentIndexes();
|
||||||
|
QMetaObject::invokeMethod(this, "resetInternalData");
|
||||||
emit modelReset(QPrivateSignal());
|
emit modelReset(QPrivateSignal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +330,10 @@ public Q_SLOTS:
|
|||||||
virtual bool submit();
|
virtual bool submit();
|
||||||
virtual void revert();
|
virtual void revert();
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
// Qt 6: Make virtual
|
||||||
|
void resetInternalData();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0);
|
QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0);
|
||||||
|
|
||||||
|
@ -136,6 +136,7 @@ private slots:
|
|||||||
|
|
||||||
void testMultipleProxiesWithSelection();
|
void testMultipleProxiesWithSelection();
|
||||||
void mapSelectionFromSource();
|
void mapSelectionFromSource();
|
||||||
|
void testResetInternalData();
|
||||||
void filteredColumns();
|
void filteredColumns();
|
||||||
void headerDataChanged();
|
void headerDataChanged();
|
||||||
|
|
||||||
@ -3242,6 +3243,143 @@ void tst_QSortFilterProxyModel::resetInvalidate()
|
|||||||
QCOMPARE(ok, works);
|
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()
|
void tst_QSortFilterProxyModel::testParentLayoutChanged()
|
||||||
{
|
{
|
||||||
QStandardItemModel model;
|
QStandardItemModel model;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user