chore(ModelEntry): Emit itemChanged event when the ModelEntry points to another model item
+ emit row changed after data is avaialble to squash - modelEntry
This commit is contained in:
parent
357ba99495
commit
73bcacbfc0
|
@ -1,6 +1,8 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.15
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
@ -20,6 +22,32 @@ Control {
|
|||
sourceModel: usersModel
|
||||
key: "pubKey"
|
||||
value: pubKeySelector.currentText
|
||||
|
||||
onItemChanged: signalsModel.append({ signal: "Item changed", value: "", row: itemData.row, item: itemData.item, roles: JSON.stringify(itemData.roles), available: itemData.available})
|
||||
onRowChanged: signalsModel.append({ signal: "Row changed", value: "", row: itemData.row, item: itemData.item, roles: JSON.stringify(itemData.roles), available: itemData.available})
|
||||
onAvailableChanged: signalsModel.append({ signal: "Available changed",value: "", row: itemData.row, item: itemData.item, roles: JSON.stringify(itemData.roles), available: itemData.available})
|
||||
onRolesChanged: signalsModel.append({ signal: "Roles changed", value: "", row: itemData.row, item: itemData.item, roles: JSON.stringify(itemData.roles), available: itemData.available})
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
model: itemData.roles
|
||||
delegate: QtObject {
|
||||
property var connection: {
|
||||
return Qt.createQmlObject(`
|
||||
import QtQml 2.15
|
||||
Connections {
|
||||
target: itemData.item
|
||||
function on${modelData.charAt(0).toUpperCase() + modelData.slice(1)}Changed() {
|
||||
signalsModel.append({ signal: "${modelData} changed", value: itemData.item.${modelData}, row: itemData.row, item: itemData.item, roles: JSON.stringify(itemData.roles), available: itemData.available})
|
||||
}
|
||||
}
|
||||
`, this, "dynamicConnectionOn${modelData}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: signalsModel
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
|
@ -97,9 +125,28 @@ Control {
|
|||
}
|
||||
}
|
||||
}
|
||||
GenericListView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: showSignals.checked && !!count
|
||||
model: signalsModel
|
||||
header: Label {
|
||||
width: parent.width
|
||||
text: "Item Signals"
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
bottomPadding: 20
|
||||
Button {
|
||||
anchors.right: parent.right
|
||||
text: "clear"
|
||||
onClicked: signalsModel.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
Pane {
|
||||
contentItem: RowLayout {
|
||||
ComboBox {
|
||||
Layout.preferredWidth: 250
|
||||
id: pubKeySelector
|
||||
model: [...ModelUtils.modelToFlatArray(usersModel, "pubKey"), "none"]
|
||||
}
|
||||
|
@ -110,6 +157,10 @@ Control {
|
|||
itemData.cacheOnRemoval = checked
|
||||
}
|
||||
}
|
||||
CheckBox {
|
||||
id: showSignals
|
||||
text: "Show signals"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QPointer>
|
||||
#include <QQmlEngine>
|
||||
#include <QQmlPropertyMap>
|
||||
#include <QStringList>
|
||||
|
||||
class ModelEntry : public QObject
|
||||
{
|
||||
|
@ -60,6 +61,8 @@ protected:
|
|||
void tryItemResetOrUpdate();
|
||||
void resetItem();
|
||||
void updateItem(const QList<int>& roles = {});
|
||||
QStringList fillItem(const QList<int>& roles = {});
|
||||
void notifyItemChanges(const QStringList& roles);
|
||||
|
||||
QModelIndex findIndexInRange(int start, int end, const QList<int>& roles = {}) const;
|
||||
bool itemHasCorrectRoles() const;
|
||||
|
|
|
@ -105,7 +105,7 @@ void ModelEntry::setSourceModel(QAbstractItemModel* sourceModel)
|
|||
setRow(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
setAvailable(false);
|
||||
setIndex({});
|
||||
});
|
||||
connect(m_sourceModel,
|
||||
|
@ -168,8 +168,8 @@ void ModelEntry::setIndex(const QModelIndex& index)
|
|||
|
||||
m_index = index;
|
||||
|
||||
tryItemResetOrUpdate();
|
||||
setRow(m_index.row());
|
||||
setRow(m_index.row());
|
||||
tryItemResetOrUpdate();
|
||||
}
|
||||
|
||||
void ModelEntry::setAvailable(bool available)
|
||||
|
@ -265,7 +265,7 @@ void ModelEntry::resetItem()
|
|||
|
||||
m_item.reset(new QQmlPropertyMap());
|
||||
|
||||
updateItem();
|
||||
fillItem();
|
||||
|
||||
if(!m_index.isValid())
|
||||
{
|
||||
|
@ -283,8 +283,17 @@ void ModelEntry::resetItem()
|
|||
|
||||
void ModelEntry::updateItem(const QList<int>& roles /*{}*/)
|
||||
{
|
||||
if(!m_index.isValid() || !m_sourceModel) return;
|
||||
const auto updatedRoles = fillItem(roles);
|
||||
notifyItemChanges(updatedRoles);
|
||||
|
||||
setItemRemovedFromModel(false);
|
||||
}
|
||||
|
||||
QStringList ModelEntry::fillItem(const QList<int>& roles /*{}*/)
|
||||
{
|
||||
if(!m_index.isValid() || !m_sourceModel) return {};
|
||||
|
||||
QStringList filledRoles;
|
||||
const auto& rolesRef = roles.isEmpty() ? m_sourceModel->roleNames().keys() : roles;
|
||||
|
||||
for(auto role : rolesRef)
|
||||
|
@ -294,10 +303,26 @@ void ModelEntry::updateItem(const QList<int>& roles /*{}*/)
|
|||
|
||||
if(roleValue == m_item->value(roleName)) continue;
|
||||
|
||||
filledRoles.append(roleName);
|
||||
m_item->insert(roleName, roleValue);
|
||||
emit m_item->valueChanged(roleName, roleValue);
|
||||
}
|
||||
setItemRemovedFromModel(false);
|
||||
|
||||
return filledRoles;
|
||||
}
|
||||
|
||||
void ModelEntry::notifyItemChanges(const QStringList& roles)
|
||||
{
|
||||
if (roles.contains(m_key))
|
||||
{
|
||||
emit itemChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto role : roles)
|
||||
{
|
||||
auto value = m_item->value(role);
|
||||
emit m_item->valueChanged(role, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelEntry::itemHasCorrectRoles() const
|
||||
|
|
|
@ -1215,7 +1215,7 @@ private slots:
|
|||
QCOMPARE(sourceModelChangedSpy.count(), 1);
|
||||
QCOMPARE(keyChangedSpy.count(), 1);
|
||||
QCOMPARE(valueChangedSpy.count(), 2);
|
||||
QCOMPARE(itemChangedSpy.count(), 1);
|
||||
QCOMPARE(itemChangedSpy.count(), 2);
|
||||
QCOMPARE(availableChangedSpy.count(), 1);
|
||||
QCOMPARE(rolesChangedSpy.count(), 1);
|
||||
QCOMPARE(testObject->row(), 0);
|
||||
|
@ -1444,6 +1444,10 @@ private slots:
|
|||
QCOMPARE(testObject->item()->isEmpty(), false);
|
||||
QCOMPARE(testObject->roles().size(), 2);
|
||||
QVERIFY(testObject->item()->value("key") != QVariant{});
|
||||
if(testObject->available())
|
||||
QCOMPARE(testObject->row(), 0);
|
||||
else
|
||||
QCOMPARE(testObject->row(), -1);
|
||||
});
|
||||
|
||||
auto itemChangedConnection = connect(testObject, &ModelEntry::itemChanged, this, [this]() {
|
||||
|
@ -1497,6 +1501,47 @@ private slots:
|
|||
QCOMPARE(testObject->item()->value("color"), {});
|
||||
}
|
||||
|
||||
void itemSignalsTest()
|
||||
{
|
||||
// Testing the signals of the item object
|
||||
// Expected:
|
||||
// 1. changes in model role values produce valueChanged signals only for the roles that changed
|
||||
// 2. changes in the model role used for filtering should produce itemChanged signals and no valueChanged signals
|
||||
|
||||
QQmlEngine engine;
|
||||
ListModelWrapper sourceModel(
|
||||
engine, QJsonArray{QJsonObject{{"key", 1}, {"color", "red"}, {"size", "small"}}, QJsonObject{{"key", 2}, {"color", "blue"}, {"size", "medium"}}});
|
||||
|
||||
QSignalSpy itemChangedSpy(testObject, &ModelEntry::itemChanged);
|
||||
|
||||
// setting the initial source model
|
||||
QCOMPARE(sourceModelProperty.write(testObject, QVariant::fromValue<QAbstractItemModel*>(sourceModel.model())),
|
||||
true);
|
||||
// setting the filter
|
||||
QCOMPARE(keyProperty.write(testObject, "key"), true);
|
||||
QCOMPARE(valueProperty.write(testObject, 1), true);
|
||||
|
||||
QCOMPARE(itemChangedSpy.count(), 1);
|
||||
|
||||
QSignalSpy valueChangedSpy(testObject->item(), &QQmlPropertyMap::valueChanged);
|
||||
|
||||
// change the value of the item
|
||||
sourceModel.setProperty(0, "color", "yellow");
|
||||
QCOMPARE(valueChangedSpy.count(), 1);
|
||||
QCOMPARE(valueChangedSpy.at(0).at(0).toString(), "color");
|
||||
QCOMPARE(valueChangedSpy.at(0).at(1).toString(), "yellow");
|
||||
|
||||
sourceModel.setProperty(0, "size", "large");
|
||||
QCOMPARE(valueChangedSpy.count(), 2);
|
||||
QCOMPARE(valueChangedSpy.at(1).at(0).toString(), "size");
|
||||
QCOMPARE(valueChangedSpy.at(1).at(1).toString(), "large");
|
||||
|
||||
// change the filter to the second item
|
||||
QCOMPARE(valueProperty.write(testObject, 2), true);
|
||||
QCOMPARE(itemChangedSpy.count(), 2);
|
||||
QCOMPARE(valueChangedSpy.count(), 2);
|
||||
}
|
||||
|
||||
void itemObjectCleanupTest()
|
||||
{
|
||||
TestModel sourceModel1({{"key", {1, 2, 3}}, {"color", {"red", "blue", "green"}}});
|
||||
|
|
Loading…
Reference in New Issue