Implement event model in C++

Filtering events in JS is too slow with >20,000 events. This moves the
event data model into C++.
This commit is contained in:
Timotej Lazar 2021-09-01 17:13:51 +02:00
parent e9b70c585c
commit cb76fedcbc
No known key found for this signature in database
GPG key ID: B6F38793D143456F
14 changed files with 375 additions and 342 deletions

View file

@ -7,61 +7,77 @@ import QtQuick.Layouts 1.6
import 'util.js' as Util
// This is the delegate for event list items.
Pane {
id: control
ItemDelegate {
required property var model
required property int index
required property int time
property int time
property alias tag: tag.text
property alias fields: inputs.model
property alias fields: inputs.model // field definitions
property bool editing: false
signal remove
clip: true
height: visible ? stuff.height + 2*padding : 0 // TODO fix filtering and remove this
padding: 2
// set to current value or default
background: Rectangle {
anchors.fill: parent
color: highlighted ? Util.alphize(border.color, 0.1) :
(index % 2 === 0 ? palette.base : palette.alternateBase)
border {
color: editing ? palette.highlight : palette.dark
width: highlighted ? 1 : 0
}
radius: border.width
}
// Set inputs to current model values.
function reset() {
for (var i = 0; i < fields.count; i++) {
for (var i = 0; i < fields.length; i++) {
const child = inputs.itemAt(i)
if (child && child.item)
child.item.set(fields.get(i).value)
child.item.set(model.values[fields[i].name])
}
}
// Store current inputs in model.
function store() {
for (var i = 0; i < fields.count; i++)
fields.setProperty(i, 'value', inputs.itemAt(i).item.value)
var values = {}
for (var i = 0; i < fields.length; i++)
values[fields[i].name] = inputs.itemAt(i).item.value
model.values = values
}
// Pass keys to each field input in order.
Component.onCompleted: reset()
onEditingChanged: {
if (editing)
forceActiveFocus()
}
// Try passing key to each field input in order.
Keys.forwardTo: Array.from({ length: inputs.count }, (_, i) => inputs.itemAt(i).item)
Behavior on height { NumberAnimation { duration: 50 } }
ColumnLayout {
id: stuff
contentItem: ColumnLayout {
anchors { left: parent.left; right: parent.right; margins: 5 }
// Event time, tag and summary.
RowLayout {
Label {
text: new Date(time).toISOString().substr(12, 9)
text: new Date(model.time).toISOString().substr(12, 9)
font.pixelSize: 10
Layout.alignment: Qt.AlignBaseline
}
Label {
id: tag
text: model.tag
font.weight: Font.DemiBold
Layout.alignment: Qt.AlignBaseline
}
Label {
text: {
var str = ''
for (var i = 0; i < fields.count; i++) {
const field = fields.get(i)
if (field.value && field.type !== 'TextArea')
str += (field.type === 'Bool' ? field.name : field.value) + ' '
for (var i = 0; i < inputs.count; i++) {
const field = inputs.model[i]
const value = inputs.itemAt(i).item.value
if (value && field.type !== 'TextArea')
str += (field.type === 'Bool' ? field.name : value) + ' '
}
return str
}
@ -72,10 +88,8 @@ Pane {
}
}
// Eventspecific inputs.
// Eventspecific input fields.
GridLayout {
id: fieldset
flow: GridLayout.TopToBottom
rows: inputs.count
@ -86,7 +100,7 @@ Pane {
Repeater {
model: inputs.model
delegate: Label {
text: Util.addShortcut(model.name, model.key)
text: Util.addShortcut(modelData.name, modelData.key)
Layout.alignment: Qt.AlignRight
}
}
@ -95,12 +109,12 @@ Pane {
Repeater {
id: inputs
delegate: Loader {
source: 'qrc:/Fields/' + model.type + '.qml'
source: 'qrc:/Fields/' + modelData.type + '.qml'
Layout.fillHeight: true
Layout.fillWidth: true
Binding {
target: item; property: 'definition'
value: model
target: item; property: 'model'
value: modelData
}
}
}