fix(ConcatModel): Changed behavior on submodel destruction to not emit signals
The general rule should be to avoid any actions on destruction different than setting relevant pointers to null. Other actions like emiting signals are potentially dangerous when the whole objects hierarchy is under destruction. Closes: #13065
This commit is contained in:
parent
790add8ea5
commit
6fe2067c22
|
@ -3,6 +3,7 @@
|
|||
#include <QAbstractListModel>
|
||||
#include <QQmlListProperty>
|
||||
#include <QQmlParserStatus>
|
||||
#include <QPointer>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
@ -27,13 +28,11 @@ public:
|
|||
|
||||
signals:
|
||||
void modelAboutToBeChanged();
|
||||
void modelChanged(bool deleted);
|
||||
void modelChanged();
|
||||
void markerRoleValueChanged();
|
||||
|
||||
private:
|
||||
void onModelDestroyed();
|
||||
|
||||
QAbstractItemModel* m_model = nullptr;
|
||||
QPointer<QAbstractItemModel> m_model;
|
||||
QString m_markerRoleValue;
|
||||
};
|
||||
|
||||
|
|
|
@ -90,18 +90,11 @@ void SourceModel::setModel(QAbstractItemModel* model)
|
|||
if (m_model == model)
|
||||
return;
|
||||
|
||||
if (model)
|
||||
connect(model, &QObject::destroyed, this, &SourceModel::onModelDestroyed);
|
||||
|
||||
if (m_model)
|
||||
disconnect(m_model, &QObject::destroyed, this, &SourceModel::onModelDestroyed);
|
||||
|
||||
emit modelAboutToBeChanged();
|
||||
m_model = model;
|
||||
emit modelChanged(false);
|
||||
emit modelChanged();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\qmlproperty any StatusQ::SourceModel::model
|
||||
|
||||
|
@ -133,12 +126,6 @@ const QString& SourceModel::markerRoleValue() const
|
|||
return m_markerRoleValue;
|
||||
}
|
||||
|
||||
void SourceModel::onModelDestroyed()
|
||||
{
|
||||
m_model = nullptr;
|
||||
emit modelChanged(true);
|
||||
}
|
||||
|
||||
|
||||
ConcatModel::ConcatModel(QObject* parent)
|
||||
: QAbstractListModel{parent}
|
||||
|
@ -350,15 +337,10 @@ void ConcatModel::componentComplete()
|
|||
});
|
||||
|
||||
connect(source, &SourceModel::modelChanged, this,
|
||||
[this, source, i](bool deleted)
|
||||
[this, source, i]()
|
||||
{
|
||||
auto previousRowCount = m_rowCounts[i];
|
||||
|
||||
if (deleted) {
|
||||
auto prefix = countPrefix(i);
|
||||
beginRemoveRows({}, prefix, prefix + previousRowCount - 1);
|
||||
}
|
||||
|
||||
if (previousRowCount) {
|
||||
m_rowCounts[i] = 0;
|
||||
endRemoveRows();
|
||||
|
|
|
@ -1379,13 +1379,13 @@ private slots:
|
|||
QSignalSpy rowsAboutToBeRemovedSpy(&model, &ConcatModel::rowsAboutToBeRemoved);
|
||||
QSignalSpy rowsRemovedSpy(&model, &ConcatModel::rowsRemoved);
|
||||
|
||||
// checking validity inside rowsAboutToBeRemoved signal
|
||||
{
|
||||
QObject context;
|
||||
connect(&model, &ConcatModel::rowsAboutToBeRemoved, &context,
|
||||
[this, &model, &roles] {
|
||||
sourceModel2.reset();
|
||||
|
||||
QCOMPARE(model.rowCount(), 6);
|
||||
|
||||
QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
|
||||
QCOMPARE(rowsRemovedSpy.count(), 0);
|
||||
|
||||
QCOMPARE(model.data(model.index(0, 0), roleForName(roles, "key")), 1);
|
||||
QCOMPARE(model.data(model.index(1, 0), roleForName(roles, "key")), 2);
|
||||
QCOMPARE(model.data(model.index(2, 0), roleForName(roles, "key")), {});
|
||||
|
@ -1399,23 +1399,6 @@ private slots:
|
|||
QCOMPARE(model.data(model.index(3, 0), roleForName(roles, "whichModel")), "");
|
||||
QCOMPARE(model.data(model.index(4, 0), roleForName(roles, "whichModel")), "");
|
||||
QCOMPARE(model.data(model.index(5, 0), roleForName(roles, "whichModel")), "");
|
||||
});
|
||||
|
||||
sourceModel2.reset();
|
||||
}
|
||||
|
||||
QCOMPARE(model.rowCount(), 4);
|
||||
|
||||
QCOMPARE(rowsAboutToBeRemovedSpy.count(), 1);
|
||||
QCOMPARE(rowsRemovedSpy.count(), 1);
|
||||
|
||||
QCOMPARE(rowsAboutToBeRemovedSpy.at(0).at(0), QModelIndex{});
|
||||
QCOMPARE(rowsAboutToBeRemovedSpy.at(0).at(1), 2);
|
||||
QCOMPARE(rowsAboutToBeRemovedSpy.at(0).at(2), 3);
|
||||
|
||||
QCOMPARE(rowsRemovedSpy.at(0).at(0), QModelIndex{});
|
||||
QCOMPARE(rowsRemovedSpy.at(0).at(1), 2);
|
||||
QCOMPARE(rowsRemovedSpy.at(0).at(2), 3);
|
||||
}
|
||||
|
||||
void removalTest()
|
||||
|
|
Loading…
Reference in New Issue