StatusQ: ModelEntryChangeTracker component introduced

This commit is contained in:
Michał Cieślak 2024-11-13 16:47:50 +01:00 committed by Michał
parent 8afc80dc18
commit 6b334a4085
4 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,100 @@
import QtQuick 2.15
import QtTest 1.15
import StatusQ.Core.Utils 0.1
Item {
id: root
width: 600
height: 400
Component {
id: componentUnderTest
ModelEntryChangeTracker {
id: tracker
model: ListModel {
ListElement { key: "a"; name: "AA" }
ListElement { key: "b"; name: "BB" }
ListElement { key: "c"; name: "CC" }
}
role: "key"
key: "b"
readonly property SignalSpy itemChangedSpy: SignalSpy {
target: tracker
signalName: "itemChanged"
}
}
}
TestCase {
name: "ModelEntryChangeTracker"
function test_change() {
const tracker = createTemporaryObject(componentUnderTest, this)
compare(tracker.itemChangedSpy.count, 0)
tracker.model.setProperty(0, "name", "AAA")
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.setProperty(1, "name", "BBB")
compare(tracker.itemChangedSpy.count, 1)
compare(tracker.revision, 1)
}
function test_insertion() {
const tracker = createTemporaryObject(componentUnderTest, this,
{ key: "d" })
compare(tracker.itemChangedSpy.count, 0)
tracker.model.setProperty(0, "name", "AAA")
tracker.model.setProperty(1, "name", "BBB")
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.insert(1, { "key": "d", name: "DD" })
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.setProperty(1, "name", "DDD")
compare(tracker.itemChangedSpy.count, 1)
compare(tracker.revision, 1)
}
function test_reinitOnRemoval() {
const tracker = createTemporaryObject(componentUnderTest, this)
compare(tracker.itemChangedSpy.count, 0)
tracker.model.append({ "key": "b", name: "BB2" })
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.setProperty(3, "name", "BBB2")
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.remove(1)
compare(tracker.itemChangedSpy.count, 0)
compare(tracker.revision, 0)
tracker.model.setProperty(2, "name", "BBBB2")
compare(tracker.itemChangedSpy.count, 1)
compare(tracker.revision, 1)
}
function test_modelChanged() {
const tracker = createTemporaryObject(componentUnderTest, this)
const model = tracker.model
tracker.model = null
model.setProperty(1, "name", "BBB")
compare(tracker.itemChangedSpy.count, 0)
}
}
}

View File

@ -0,0 +1,77 @@
import QtQml 2.15
QObject {
id: root
property var model
property string role
property var key
readonly property alias revision: d.revision
signal itemChanged
onModelChanged: d.initPersistentIndex()
onRoleChanged: d.initPersistentIndex()
onKeyChanged: d.initPersistentIndex()
QtObject {
id: d
property var persistentIndex
property int revision: 0
function initPersistentIndex() {
d.persistentIndex = null
if (!model)
return
const idx = ModelUtils.indexOf(root.model, root.role, root.key)
if (idx === -1)
return
d.persistentIndex = ModelUtils.persistentIndex(root.model, idx)
}
Component.onCompleted: initPersistentIndex()
}
Connections {
target: root.model ?? null
function onDataChanged(topLeft, bottomRight) {
if (!d.persistentIndex || !d.persistentIndex.valid)
return
const row = d.persistentIndex.row
if (topLeft.row >= row && bottomRight.row <= row) {
d.revision++
root.itemChanged()
}
}
function onRowsInserted() {
if (d.persistentIndex && d.valid)
return
d.initPersistentIndex()
}
function onRowsRemoved() {
if (!!d.persistentIndex && !d.valid)
d.initPersistentIndex()
}
function onLayoutChanged() {
if (!!d.persistentIndex || !d.valid)
d.initPersistentIndex()
}
function onModelReset() {
d.initPersistentIndex()
}
}
}

View File

@ -8,6 +8,7 @@ JSONListModel 0.1 JSONListModel.qml
LazyStackLayout 0.1 LazyStackLayout.qml LazyStackLayout 0.1 LazyStackLayout.qml
ModelChangeGuard 0.1 ModelChangeGuard.qml ModelChangeGuard 0.1 ModelChangeGuard.qml
ModelChangeTracker 0.1 ModelChangeTracker.qml ModelChangeTracker 0.1 ModelChangeTracker.qml
ModelEntryChangeTracker 0.1 ModelEntryChangeTracker.qml
ModelsComparator 0.1 ModelsComparator.qml ModelsComparator 0.1 ModelsComparator.qml
QObject 0.1 QObject.qml QObject 0.1 QObject.qml
SearchFilter 0.1 SearchFilter.qml SearchFilter 0.1 SearchFilter.qml

View File

@ -199,6 +199,7 @@
<file>StatusQ/Core/Utils/LazyStackLayout.qml</file> <file>StatusQ/Core/Utils/LazyStackLayout.qml</file>
<file>StatusQ/Core/Utils/ModelChangeGuard.qml</file> <file>StatusQ/Core/Utils/ModelChangeGuard.qml</file>
<file>StatusQ/Core/Utils/ModelChangeTracker.qml</file> <file>StatusQ/Core/Utils/ModelChangeTracker.qml</file>
<file>StatusQ/Core/Utils/ModelEntryChangeTracker.qml</file>
<file>StatusQ/Core/Utils/ModelUtils.qml</file> <file>StatusQ/Core/Utils/ModelUtils.qml</file>
<file>StatusQ/Core/Utils/ModelsComparator.qml</file> <file>StatusQ/Core/Utils/ModelsComparator.qml</file>
<file>StatusQ/Core/Utils/OperatorsUtils.qml</file> <file>StatusQ/Core/Utils/OperatorsUtils.qml</file>