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
ModelChangeGuard 0.1 ModelChangeGuard.qml
ModelChangeTracker 0.1 ModelChangeTracker.qml
ModelEntryChangeTracker 0.1 ModelEntryChangeTracker.qml
ModelsComparator 0.1 ModelsComparator.qml
QObject 0.1 QObject.qml
SearchFilter 0.1 SearchFilter.qml

View File

@ -199,6 +199,7 @@
<file>StatusQ/Core/Utils/LazyStackLayout.qml</file>
<file>StatusQ/Core/Utils/ModelChangeGuard.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/ModelsComparator.qml</file>
<file>StatusQ/Core/Utils/OperatorsUtils.qml</file>