feat(StatusQ): Ability to change sources in LeftJoinModel
- ability to change left/right models - improved handling of model deletion - base class changed to QAbstractListModel, dataChanged signal emision improved Closes: #12912
This commit is contained in:
parent
6fe2067c22
commit
fbe6cc95d1
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
#include <QAbstractListModel>
|
||||
#include <QPointer>
|
||||
|
||||
class LeftJoinModel : public QIdentityProxyModel
|
||||
class LeftJoinModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -27,9 +28,9 @@ public:
|
|||
void setJoinRole(const QString& joinRole);
|
||||
const QString& joinRole() const;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QVariant data(const QModelIndex& index, int role) const override;
|
||||
void setSourceModel(QAbstractItemModel* newSourceModel) override;
|
||||
|
||||
signals:
|
||||
void leftModelChanged();
|
||||
|
@ -37,10 +38,15 @@ signals:
|
|||
void joinRoleChanged();
|
||||
|
||||
private:
|
||||
void initializeIfReady();
|
||||
void initialize();
|
||||
void initializeIfReady(bool reset);
|
||||
void initialize(bool reset);
|
||||
|
||||
void connectLeftModelSignals();
|
||||
void connectRightModelSignals();
|
||||
|
||||
int m_rightModelRolesOffset = 0;
|
||||
QHash<int, QByteArray> m_leftRoleNames;
|
||||
QHash<int, QByteArray> m_rightRoleNames;
|
||||
QHash<int, QByteArray> m_roleNames;
|
||||
QVector<int> m_joinedRoles;
|
||||
|
||||
|
@ -48,11 +54,10 @@ private:
|
|||
int m_leftModelJoinRole = 0;
|
||||
int m_rightModelJoinRole = 0;
|
||||
|
||||
QAbstractItemModel* m_leftModel = nullptr;
|
||||
QAbstractItemModel* m_rightModel = nullptr;
|
||||
QPointer<QAbstractItemModel> m_leftModel;
|
||||
QPointer<QAbstractItemModel> m_rightModel;
|
||||
|
||||
bool m_leftModelDestroyed = false;
|
||||
bool m_rightModelDestroyed = false;
|
||||
bool m_initialized = false;
|
||||
|
||||
mutable QPersistentModelIndex m_lastUsedRightModelIndex;
|
||||
};
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
#include <algorithm>
|
||||
|
||||
LeftJoinModel::LeftJoinModel(QObject* parent)
|
||||
: QIdentityProxyModel{parent}
|
||||
: QAbstractListModel{parent}
|
||||
{
|
||||
}
|
||||
|
||||
void LeftJoinModel::initializeIfReady()
|
||||
void LeftJoinModel::initializeIfReady(bool reset)
|
||||
{
|
||||
if (m_leftModel && m_rightModel && !m_joinRole.isEmpty()
|
||||
&& !m_leftModel->roleNames().empty()
|
||||
&& !m_rightModel->roleNames().empty())
|
||||
initialize();
|
||||
initialize(reset);
|
||||
}
|
||||
|
||||
void LeftJoinModel::initialize()
|
||||
void LeftJoinModel::initialize(bool reset)
|
||||
{
|
||||
auto leftRoleNames = m_leftModel->roleNames();
|
||||
auto rightRoleNames = m_rightModel->roleNames();
|
||||
|
@ -51,6 +51,9 @@ void LeftJoinModel::initialize()
|
|||
return;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
beginResetModel();
|
||||
|
||||
auto leftRoles = leftRoleNames.keys();
|
||||
auto maxLeftRole = std::max_element(leftRoles.cbegin(), leftRoles.cend());
|
||||
auto rightRolesOffset = *maxLeftRole + 1;
|
||||
|
@ -73,6 +76,92 @@ void LeftJoinModel::initialize()
|
|||
m_rightModelJoinRole = rightRoleNames.key(m_joinRole.toUtf8());
|
||||
m_rightModelRolesOffset = rightRolesOffset;
|
||||
|
||||
m_leftRoleNames = std::move(leftRoleNames);
|
||||
m_rightRoleNames = std::move(rightRoleNames);
|
||||
|
||||
disconnect(m_leftModel, nullptr, this, nullptr);
|
||||
disconnect(m_rightModel, nullptr, this, nullptr);
|
||||
|
||||
connectRightModelSignals();
|
||||
connectLeftModelSignals();
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
if (reset)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void LeftJoinModel::connectLeftModelSignals()
|
||||
{
|
||||
connect(m_leftModel, &QAbstractItemModel::dataChanged, this,
|
||||
[this](auto& topLeft, auto& bottomRight, auto& roles) {
|
||||
|
||||
auto tl = index(topLeft.row());
|
||||
auto br = index(bottomRight.row());
|
||||
|
||||
if (roles.contains(m_leftModelJoinRole))
|
||||
emit dataChanged(tl, br, m_joinedRoles + roles);
|
||||
else
|
||||
emit dataChanged(tl, br, roles);
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsAboutToBeInserted,
|
||||
this, [this](const QModelIndex& parent, int first, int last) {
|
||||
if (!parent.isValid())
|
||||
beginInsertRows({}, first, last);
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsInserted,
|
||||
this, [this](const QModelIndex& parent, int first, int last) {
|
||||
if (!parent.isValid())
|
||||
endInsertRows();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsAboutToBeRemoved,
|
||||
this, [this](const QModelIndex& parent, int first, int last) {
|
||||
if (!parent.isValid())
|
||||
beginRemoveRows({}, first, last);
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsRemoved,
|
||||
this, [this](const QModelIndex& parent, int first, int last) {
|
||||
if (!parent.isValid())
|
||||
endRemoveRows();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsAboutToBeMoved,
|
||||
this, [this](const QModelIndex &sourceParent, int sourceStart,
|
||||
int sourceEnd, const QModelIndex &destinationParent, int destinationRow) {
|
||||
if (!sourceParent.isValid() && !destinationParent.isValid())
|
||||
beginMoveRows({}, sourceStart, sourceEnd, {}, destinationRow);
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsMoved,
|
||||
this, [this](const QModelIndex &sourceParent, int sourceStart,
|
||||
int sourceEnd, const QModelIndex &destinationParent, int destinationRow) {
|
||||
if (!sourceParent.isValid() && !destinationParent.isValid())
|
||||
endMoveRows();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::layoutAboutToBeChanged, this, [this]() {
|
||||
emit layoutAboutToBeChanged();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::layoutChanged, this, [this]() {
|
||||
emit layoutChanged();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::modelAboutToBeReset, this, [this]() {
|
||||
beginResetModel();
|
||||
});
|
||||
|
||||
connect(m_leftModel, &QAbstractItemModel::modelReset, this, [this]() {
|
||||
endResetModel();
|
||||
});
|
||||
}
|
||||
|
||||
void LeftJoinModel::connectRightModelSignals()
|
||||
{
|
||||
connect(m_rightModel, &QAbstractItemModel::dataChanged, this,
|
||||
[this](auto& topLeft, auto& bottomRight, auto& roles) {
|
||||
QVector<int> rolesTranslated;
|
||||
|
@ -86,16 +175,11 @@ void LeftJoinModel::initialize()
|
|||
role += m_rightModelRolesOffset;
|
||||
}
|
||||
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, 0), rolesTranslated);
|
||||
emit dataChanged(index(0), index(rowCount() - 1), rolesTranslated);
|
||||
});
|
||||
|
||||
disconnect(m_leftModel, &QAbstractItemModel::rowsInserted,
|
||||
this, &LeftJoinModel::initializeIfReady);
|
||||
disconnect(m_rightModel, &QAbstractItemModel::rowsInserted,
|
||||
this, &LeftJoinModel::initializeIfReady);
|
||||
|
||||
auto emitJoinedRolesChanged = [this] {
|
||||
emit dataChanged(index(0, 0), index(rowCount() - 1, 0), m_joinedRoles);
|
||||
emit dataChanged(index(0), index(rowCount() - 1), m_joinedRoles);
|
||||
};
|
||||
|
||||
connect(m_rightModel, &QAbstractItemModel::rowsRemoved, this,
|
||||
|
@ -106,19 +190,11 @@ void LeftJoinModel::initialize()
|
|||
emitJoinedRolesChanged);
|
||||
connect(m_rightModel, &QAbstractItemModel::layoutChanged, this,
|
||||
emitJoinedRolesChanged);
|
||||
|
||||
connect(this, &QAbstractItemModel::dataChanged, this,
|
||||
[this](auto& topLeft, auto& bottomRight, auto& roles) {
|
||||
if (roles.contains(m_leftModelJoinRole))
|
||||
emit dataChanged(topLeft, bottomRight, m_joinedRoles);
|
||||
});
|
||||
|
||||
QIdentityProxyModel::setSourceModel(m_leftModel);
|
||||
}
|
||||
|
||||
QVariant LeftJoinModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
if (!index.isValid() || m_leftModel == nullptr)
|
||||
return {};
|
||||
|
||||
auto idx = m_leftModel->index(index.row(), index.column());
|
||||
|
@ -126,7 +202,7 @@ QVariant LeftJoinModel::data(const QModelIndex& index, int role) const
|
|||
if (role < m_rightModelRolesOffset)
|
||||
return m_leftModel->data(idx, role);
|
||||
|
||||
if (m_rightModelDestroyed)
|
||||
if (m_rightModel == nullptr)
|
||||
return {};
|
||||
|
||||
auto joinRoleLeftValue = m_leftModel->data(idx, m_leftModelJoinRole);
|
||||
|
@ -154,27 +230,29 @@ void LeftJoinModel::setLeftModel(QAbstractItemModel* model)
|
|||
if (m_leftModel == model)
|
||||
return;
|
||||
|
||||
if (m_leftModel != nullptr || m_leftModelDestroyed) {
|
||||
qWarning("Changing left model is not supported!");
|
||||
return;
|
||||
}
|
||||
if (m_leftModel)
|
||||
disconnect(m_leftModel, nullptr, this, nullptr);
|
||||
|
||||
bool was_initialized = m_initialized;
|
||||
|
||||
if (was_initialized)
|
||||
beginResetModel();
|
||||
|
||||
m_initialized = false;
|
||||
m_leftModel = model;
|
||||
|
||||
// Some models may have roles undefined until first row is inserted,
|
||||
// like ListModel, therefore in such cases initialization must be deferred
|
||||
// until first insertion.
|
||||
connect(m_leftModel, &QAbstractItemModel::rowsInserted,
|
||||
this, &LeftJoinModel::initializeIfReady);
|
||||
|
||||
connect(m_leftModel, &QObject::destroyed, this, [this] {
|
||||
this->m_leftModel = nullptr;
|
||||
this->m_leftModelDestroyed = true;
|
||||
});
|
||||
this, [this]() { initializeIfReady(true); });
|
||||
|
||||
emit leftModelChanged();
|
||||
|
||||
initializeIfReady();
|
||||
initializeIfReady(!was_initialized);
|
||||
|
||||
if (was_initialized)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QAbstractItemModel* LeftJoinModel::leftModel() const
|
||||
|
@ -187,25 +265,41 @@ void LeftJoinModel::setRightModel(QAbstractItemModel* model)
|
|||
if (m_rightModel == model)
|
||||
return;
|
||||
|
||||
if (m_rightModel != nullptr || m_rightModelDestroyed) {
|
||||
qWarning("Changing right model is not supported!");
|
||||
if (m_rightModel)
|
||||
disconnect(m_rightModel, nullptr, this, nullptr);
|
||||
|
||||
if (m_initialized &&
|
||||
(model == nullptr || model->roleNames() == m_rightRoleNames)) {
|
||||
|
||||
m_rightModel = model;
|
||||
emit rightModelChanged();
|
||||
|
||||
auto count = rowCount();
|
||||
|
||||
if (count > 0)
|
||||
emit dataChanged(index(0), index(count - 1), m_joinedRoles);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool was_initialized = m_initialized;
|
||||
|
||||
if (was_initialized)
|
||||
beginResetModel();
|
||||
|
||||
m_initialized = false;
|
||||
m_rightModel = model;
|
||||
|
||||
// see: LeftJoinModel::setLeftModel
|
||||
connect(m_rightModel, &QAbstractItemModel::rowsInserted,
|
||||
this, &LeftJoinModel::initializeIfReady);
|
||||
|
||||
connect(m_rightModel, &QObject::destroyed, this, [this] {
|
||||
this->m_rightModel = nullptr;
|
||||
this->m_rightModelDestroyed = true;
|
||||
});
|
||||
this, [this]() { initializeIfReady(true); });
|
||||
|
||||
emit rightModelChanged();
|
||||
|
||||
initializeIfReady();
|
||||
initializeIfReady(!was_initialized);
|
||||
|
||||
if (was_initialized)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QAbstractItemModel* LeftJoinModel::rightModel() const
|
||||
|
@ -227,7 +321,7 @@ void LeftJoinModel::setJoinRole(const QString& joinRole)
|
|||
|
||||
emit joinRoleChanged();
|
||||
|
||||
initializeIfReady();
|
||||
initializeIfReady(true);
|
||||
}
|
||||
|
||||
const QString& LeftJoinModel::joinRole() const
|
||||
|
@ -235,10 +329,13 @@ const QString& LeftJoinModel::joinRole() const
|
|||
return m_joinRole;
|
||||
}
|
||||
|
||||
void LeftJoinModel::setSourceModel(QAbstractItemModel* newSourceModel)
|
||||
int LeftJoinModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
qWarning() << "Source model is not intended to be set directly on this model."
|
||||
" Use setLeftModel and setRightModel instead!";
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return m_leftModel == nullptr || !m_initialized
|
||||
? 0 : m_leftModel->rowCount();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> LeftJoinModel::roleNames() const
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
#include <StatusQ/concatmodel.h>
|
||||
|
||||
namespace {
|
||||
|
||||
// Workaround for a bug in QIdentityProxyModel (returning roleNames improperly)
|
||||
// Workaround for https://bugreports.qt.io/browse/QTBUG-57971 (ListModel doesn't
|
||||
// emit modelReset when role names are initially set, therefore QIdentityProxyModel
|
||||
// doesn't update role names appropriately)
|
||||
class IdentityModel : public QIdentityProxyModel {
|
||||
public:
|
||||
QHash<int,QByteArray> roleNames() const override {
|
||||
|
|
|
@ -103,25 +103,6 @@ private slots:
|
|||
QCOMPARE(model.roleNames(), {});
|
||||
}
|
||||
|
||||
void setSourceModelDirectlyTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "title", { "Token 1", "Token 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Source model is not intended to be set directly "
|
||||
"on this model. Use setLeftModel and setRightModel instead!");
|
||||
model.setSourceModel(&leftModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QCOMPARE(model.roleNames(), {});
|
||||
}
|
||||
|
||||
void initializationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
|
@ -488,6 +469,64 @@ private slots:
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: cover also move and layoutChanged
|
||||
void insertRemovePropagationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "title", { "Token 1", "Token 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
TestSourceModel rightModel({
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }},
|
||||
{ "color", { "red", "green" }}
|
||||
});
|
||||
|
||||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
model.setLeftModel(&leftModel);
|
||||
model.setRightModel(&rightModel);
|
||||
model.setJoinRole("communityId");
|
||||
|
||||
QSignalSpy rowsInsertedSpy(&model, &LeftJoinModel::rowsInserted);
|
||||
QSignalSpy rowsRemovedSpy(&model, &LeftJoinModel::rowsRemoved);
|
||||
|
||||
leftModel.insert(1, {"Token 1_1", "community_2"});
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1_1"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 2"));
|
||||
|
||||
leftModel.remove(1);
|
||||
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
|
||||
|
||||
QCOMPARE(rowsInsertedSpy.count(), 1);
|
||||
QCOMPARE(rowsInsertedSpy.first().at(0), QModelIndex{});
|
||||
QCOMPARE(rowsInsertedSpy.first().at(1), 1);
|
||||
QCOMPARE(rowsInsertedSpy.first().at(2), 1);
|
||||
|
||||
QCOMPARE(rowsRemovedSpy.count(), 1);
|
||||
QCOMPARE(rowsRemovedSpy.first().at(0), QModelIndex{});
|
||||
QCOMPARE(rowsRemovedSpy.first().at(1), 1);
|
||||
QCOMPARE(rowsRemovedSpy.first().at(2), 1);
|
||||
}
|
||||
|
||||
void rightModelJoinRoleChangesPropagationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
|
@ -624,15 +663,14 @@ private slots:
|
|||
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
|
||||
|
||||
leftModel.update(1, 1, "community_1");
|
||||
QCOMPARE(dataChangedSpy.count(), 2);
|
||||
QCOMPARE(dataChangedSpy.count(), 1);
|
||||
|
||||
QCOMPARE(dataChangedSpy.first().at(0), model.index(1, 0));
|
||||
QCOMPARE(dataChangedSpy.first().at(1), model.index(1, 0));
|
||||
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
|
||||
|
||||
QCOMPARE(dataChangedSpy.at(1).at(0), model.index(1, 0));
|
||||
QCOMPARE(dataChangedSpy.at(1).at(1), model.index(1, 0));
|
||||
QCOMPARE(dataChangedSpy.at(1).at(2).value<QVector<int>>(), {1});
|
||||
auto changedRoles = dataChangedSpy.first().at(2).value<QVector<int>>();
|
||||
QVERIFY(changedRoles.contains(1));
|
||||
QVERIFY(changedRoles.contains(2));
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
|
@ -649,20 +687,22 @@ private slots:
|
|||
void modelsDeletedBeforeInitializationTest()
|
||||
{
|
||||
auto leftModel = std::make_unique<TestSourceModel>(
|
||||
QList<QPair<QString, QVariantList>>{
|
||||
{ "title", { "Token 1", "Token 2", "Token 3"}},
|
||||
{ "communityId", { "community_1", "community_2", "community_1" }}
|
||||
});
|
||||
QList<QPair<QString, QVariantList>>{
|
||||
{ "title", { "Token 1", "Token 2", "Token 3"}},
|
||||
{ "communityId", { "community_1", "community_2", "community_1" }}
|
||||
});
|
||||
|
||||
auto rightModel = std::make_unique<TestSourceModel>(
|
||||
QList<QPair<QString, QVariantList>>{
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
QList<QPair<QString, QVariantList>>{
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
|
||||
|
||||
model.setLeftModel(leftModel.get());
|
||||
model.setRightModel(rightModel.get());
|
||||
|
||||
|
@ -686,13 +726,21 @@ private slots:
|
|||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing left model is not supported!");
|
||||
model.setLeftModel(&newLeftModel);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing right model is not supported!");
|
||||
model.setRightModel(&newRightModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
|
||||
|
||||
QCOMPARE(modelResetSpy.count(), 1);
|
||||
}
|
||||
|
||||
void modelsDeletedAfterInitializationTest()
|
||||
|
@ -712,11 +760,15 @@ private slots:
|
|||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
|
||||
|
||||
model.setLeftModel(leftModel.get());
|
||||
model.setRightModel(rightModel.get());
|
||||
|
||||
model.setJoinRole("communityId");
|
||||
|
||||
QCOMPARE(modelResetSpy.count(), 1);
|
||||
|
||||
leftModel.reset();
|
||||
rightModel.reset();
|
||||
|
||||
|
@ -736,13 +788,25 @@ private slots:
|
|||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing left model is not supported!");
|
||||
model.setLeftModel(&newLeftModel);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing right model is not supported!");
|
||||
QCOMPARE(modelResetSpy.count(), 2);
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
|
||||
model.setRightModel(&newRightModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
|
||||
|
||||
QCOMPARE(modelResetSpy.count(), 3);
|
||||
}
|
||||
|
||||
void rightModelDeletedAfterInitializationTest()
|
||||
|
@ -786,13 +850,120 @@ private slots:
|
|||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing left model is not supported!");
|
||||
model.setLeftModel(&newLeftModel);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Changing right model is not supported!");
|
||||
model.setRightModel(&newRightModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
|
||||
}
|
||||
|
||||
void rightModelChangedWithSameRolesAfterInitializationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "title", { "Token 1", "Token 2", "Token 3"}},
|
||||
{ "communityId", { "community_1", "community_2", "community_1" }}
|
||||
});
|
||||
|
||||
TestSourceModel rightModel({
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
model.setLeftModel(&leftModel);
|
||||
model.setRightModel(&rightModel);
|
||||
|
||||
model.setJoinRole("communityId");
|
||||
|
||||
TestSourceModel newRightModel({
|
||||
{ "name", { "Community A", "Community B" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
|
||||
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
|
||||
|
||||
model.setRightModel(&newRightModel);
|
||||
|
||||
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
|
||||
QCOMPARE(model.roleNames(), roles);
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community A"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community B"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community A"));
|
||||
|
||||
QCOMPARE(modelResetSpy.count(), 0);
|
||||
QCOMPARE(dataChangedSpy.count(), 1);
|
||||
|
||||
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
|
||||
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
|
||||
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
|
||||
}
|
||||
|
||||
void rightModelChangedWithDifferentRolesAfterInitializationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "title", { "Token 1", "Token 2", "Token 3"}},
|
||||
{ "communityId", { "community_1", "community_2", "community_1" }}
|
||||
});
|
||||
|
||||
TestSourceModel rightModel({
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
LeftJoinModel model;
|
||||
QAbstractItemModelTester tester(&model);
|
||||
|
||||
model.setLeftModel(&leftModel);
|
||||
model.setRightModel(&rightModel);
|
||||
|
||||
model.setJoinRole("communityId");
|
||||
|
||||
TestSourceModel newRightModel({
|
||||
{ "communityId", { "community_1", "community_2" }},
|
||||
{ "name", { "Community A", "Community B" }}
|
||||
});
|
||||
|
||||
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
|
||||
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
|
||||
|
||||
model.setRightModel(&newRightModel);
|
||||
|
||||
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {3, "name"}};
|
||||
QCOMPARE(model.roleNames(), roles);
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
|
||||
QCOMPARE(model.data(model.index(0, 0), 3), QString("Community A"));
|
||||
QCOMPARE(model.data(model.index(1, 0), 3), QString("Community B"));
|
||||
QCOMPARE(model.data(model.index(2, 0), 3), QString("Community A"));
|
||||
|
||||
QCOMPARE(modelResetSpy.count(), 1);
|
||||
QCOMPARE(dataChangedSpy.count(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue