fix(ModelSyncedContainer): Proper disconnection from previously used model
This commit is contained in:
parent
675ef05eaa
commit
2868d22a3a
|
@ -4,21 +4,26 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class ModelSyncedContainer
|
class ModelSyncedContainer
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setModel(QAbstractItemModel* model)
|
void setModel(QAbstractItemModel* model)
|
||||||
{
|
{
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
|
|
||||||
|
// create context object for connections, disconnect from previous model
|
||||||
|
// by destroying previous context object if present
|
||||||
|
m_ctx = std::make_unique<QObject>();
|
||||||
|
|
||||||
if (model == nullptr)
|
if (model == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_container.resize(model->rowCount());
|
m_container.resize(model->rowCount());
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::rowsRemoved, &m_ctx,
|
QObject::connect(model, &QAbstractItemModel::rowsRemoved, m_ctx.get(),
|
||||||
[this] (const QModelIndex& parent, int first, int last)
|
[this] (const QModelIndex& parent, int first, int last)
|
||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
|
@ -28,7 +33,7 @@ public:
|
||||||
m_container.cbegin() + last + 1);
|
m_container.cbegin() + last + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::rowsInserted, &m_ctx,
|
QObject::connect(model, &QAbstractItemModel::rowsInserted, m_ctx.get(),
|
||||||
[this] (const QModelIndex& parent, int first, int last)
|
[this] (const QModelIndex& parent, int first, int last)
|
||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
|
@ -45,8 +50,8 @@ public:
|
||||||
std::make_move_iterator(toBeInserted.end()));
|
std::make_move_iterator(toBeInserted.end()));
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeMoved, &m_ctx,
|
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeMoved,
|
||||||
[this, model] (const QModelIndex& parent)
|
m_ctx.get(), [this, model] (const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return;
|
return;
|
||||||
|
@ -55,7 +60,7 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::rowsMoved,
|
QObject::connect(model, &QAbstractItemModel::rowsMoved,
|
||||||
&m_ctx, [this] (const QModelIndex& parent)
|
m_ctx.get(), [this] (const QModelIndex& parent)
|
||||||
{
|
{
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return;
|
return;
|
||||||
|
@ -67,26 +72,26 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::layoutAboutToBeChanged,
|
QObject::connect(model, &QAbstractItemModel::layoutAboutToBeChanged,
|
||||||
&m_ctx, [this, model]
|
m_ctx.get(), [this, model]
|
||||||
{
|
{
|
||||||
storePersistentIndexes(model);
|
storePersistentIndexes(model);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::layoutChanged,
|
QObject::connect(model, &QAbstractItemModel::layoutChanged,
|
||||||
&m_ctx, [this]
|
m_ctx.get(), [this]
|
||||||
{
|
{
|
||||||
updateFromPersistentIndexes();
|
updateFromPersistentIndexes();
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::modelReset,
|
QObject::connect(model, &QAbstractItemModel::modelReset,
|
||||||
&m_ctx, [this, model]
|
m_ctx.get(), [this, model]
|
||||||
{
|
{
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
m_container.resize(model->rowCount());
|
m_container.resize(model->rowCount());
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(model, &QAbstractItemModel::destroyed,
|
QObject::connect(model, &QAbstractItemModel::destroyed,
|
||||||
&m_ctx, [this, model]
|
m_ctx.get(), [this, model]
|
||||||
{
|
{
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
});
|
});
|
||||||
|
@ -144,5 +149,6 @@ private:
|
||||||
|
|
||||||
QList<QPersistentModelIndex> m_persistentIndexes;
|
QList<QPersistentModelIndex> m_persistentIndexes;
|
||||||
std::vector<T> m_container;
|
std::vector<T> m_container;
|
||||||
QObject m_ctx;
|
|
||||||
|
std::unique_ptr<QObject> m_ctx;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,42 @@ private slots:
|
||||||
QCOMPARE(container.size(), 0);
|
QCOMPARE(container.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void modelChangeDisconnectionTest()
|
||||||
|
{
|
||||||
|
struct Model : public QIdentityProxyModel
|
||||||
|
{
|
||||||
|
void connectNotify(const QMetaMethod&) override
|
||||||
|
{
|
||||||
|
connectionsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnectNotify(const QMetaMethod&) override
|
||||||
|
{
|
||||||
|
connectionsCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int connectionsCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Model model1, model2;
|
||||||
|
ModelSyncedContainer<int> container;
|
||||||
|
|
||||||
|
QCOMPARE(model1.connectionsCount, 0);
|
||||||
|
|
||||||
|
container.setModel(&model1);
|
||||||
|
QVERIFY(model1.connectionsCount > 0);
|
||||||
|
|
||||||
|
container.setModel(nullptr);
|
||||||
|
QCOMPARE(model1.connectionsCount, 0);
|
||||||
|
|
||||||
|
container.setModel(&model1);
|
||||||
|
QVERIFY(model1.connectionsCount > 0);
|
||||||
|
|
||||||
|
container.setModel(&model2);
|
||||||
|
QCOMPARE(model1.connectionsCount, 0);
|
||||||
|
QVERIFY(model2.connectionsCount > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void appendTest()
|
void appendTest()
|
||||||
{
|
{
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
|
|
Loading…
Reference in New Issue