This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
2018-12-10 00:29:14 +01:00

292 lines
10 KiB
QML

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import QtQuick.Layouts 1.1
import Nymea 1.0
import "../components"
import "../customviews"
Page {
id: root
property Device device: null
property var filterTypeIds: []
header: GuhHeader {
text: qsTr("History for %1").arg(root.device.name)
onBackPressed: pageStack.pop()
HeaderButton {
imageSource: "../images/filters.svg"
color: logsModelNg.filterEnabled ? app.accentColor : keyColor
onClicked: logsModelNg.filterEnabled = !logsModelNg.filterEnabled
visible: root.filterTypeIds.length === 0
}
}
LogsModelNg {
id: logsModelNg
engine: _engine
deviceId: root.device.id
typeIds: root.filterTypeIds.length > 0
? root.filterTypeIds
: filterEnabled
? [filterDeviceModel.getData(filterComboBox.currentIndex, DeviceModel.RoleId)]
: []
live: true
property bool filterEnabled: false
}
DeviceModel {
id: filterDeviceModel
device: root.device
}
Pane {
id: filterPane
anchors { left: parent.left; top: parent.top; right: parent.right }
Behavior on height { NumberAnimation { duration: 120; easing.type: Easing.InOutQuad } }
height: logsModelNg.filterEnabled ? implicitHeight + app.margins * 2 : 0
Material.elevation: 1
leftPadding: 0; rightPadding: 0; topPadding: 0; bottomPadding: 0
contentItem: Rectangle {
color: app.primaryColor
clip: true
RowLayout {
anchors.fill: parent
anchors.margins: app.margins
spacing: app.margins
Label {
text: qsTr("Filter by")
}
ComboBox {
id: filterComboBox
Layout.fillWidth: true
textRole: "displayName"
model: filterDeviceModel
}
}
}
}
Loader {
id: graphLoader
anchors {
left: parent.left
top: filterPane.bottom
right: parent.right
}
readonly property StateType stateType: root.device.deviceClass.stateTypes.getStateType(root.filterTypeIds[0])
readonly property bool canShowGraph: {
if (stateType === null) {
return false
}
if (stateType.unit === Types.UnitUnixTime) {
return false;
}
switch (stateType.type) {
case "Int":
case "Double":
return true;
case "Bool":
return engine.jsonRpcClient.ensureServerVersion("1.10")
}
print("not showing graph for", root.stateType.type)
return false;
}
Component.onCompleted: {
if (root.filterTypeIds.length === 0) {
return;
}
if (!canShowGraph) {
return;
}
var source;
if (engine.jsonRpcClient.ensureServerVersion("1.10")) {
source = Qt.resolvedUrl("../customviews/GenericTypeGraph.qml");
} else {
source = Qt.resolvedUrl("../customviews/GenericTypeGraphPre110.qml");
}
setSource(source, {device: root.device, stateType: stateType})
}
}
ListView {
anchors { left: parent.left; top: graphLoader.bottom; right: parent.right; bottom: parent.bottom }
clip: true
model: logsModelNg
ScrollBar.vertical: ScrollBar {}
BusyIndicator {
anchors.centerIn: parent
visible: logsModelNg.busy
}
delegate: ItemDelegate {
id: entryDelegate
width: parent.width
property StateType stateType: model.source === LogEntry.LoggingSourceStates ? root.device.deviceClass.stateTypes.getStateType(model.typeId) : null
property EventType eventType: model.source === LogEntry.LoggingSourceEvents || model.source === LogEntry.LoggingSourceStates ? root.device.deviceClass.eventTypes.getEventType(model.typeId) : null
property ActionType actionType: model.source === LogEntry.LoggingSourceActions ? root.device.deviceClass.actionTypes.getActionType(model.typeId) : null
contentItem: RowLayout {
ColorIcon {
Layout.preferredWidth: app.iconSize
Layout.preferredHeight: width
Layout.alignment: Qt.AlignVCenter
color: {
switch (model.source) {
case LogEntry.LoggingSourceStates:
case LogEntry.LoggingSourceSystem:
case LogEntry.LoggingSourceActions:
case LogEntry.LoggingSourceEvents:
return app.accentColor
case LogEntry.LoggingSourceRules:
if (model.loggingEventType === LogEntry.LoggingEventTypeActiveChange) {
return model.value === true ? "green" : keyColor
}
return app.accentColor
}
}
name: {
switch (model.source) {
case LogEntry.LoggingSourceStates:
return "../images/state.svg"
case LogEntry.LoggingSourceSystem:
return "../images/system-shutdown.svg"
case LogEntry.LoggingSourceActions:
return "../images/action.svg"
case LogEntry.LoggingSourceEvents:
return "../images/event.svg"
case LogEntry.LoggingSourceRules:
return "../images/magic.svg"
}
}
}
ColumnLayout {
RowLayout {
Label {
text: {
switch (model.source) {
case LogEntry.LoggingSourceStates:
// return entryDelegate.stateType.displayName
case LogEntry.LoggingSourceEvents:
return entryDelegate.eventType.displayName
case LogEntry.LoggingSourceActions:
return entryDelegate.actionType.displayName
}
}
Layout.fillWidth: true
elide: Text.ElideRight
}
Label {
text: Qt.formatDateTime(model.timestamp,"dd.MM.yy hh:mm:ss")
elide: Text.ElideRight
font.pixelSize: app.smallFont
enabled: false
}
}
RowLayout {
Loader {
id: valueLoader
Layout.fillWidth: true
sourceComponent: {
switch (model.source) {
case LogEntry.LoggingSourceStates:
switch (entryDelegate.stateType.type.toLowerCase()) {
case "bool":
return boolComponent;
case "color":
return colorComponent
default:
if (entryDelegate.stateType.unit == Types.UnitUnixTime) {
return dateTimeComponent
}
return labelComponent
}
case LogEntry.LoggingSourceActions:
break;
case LogEntry.LoggingSourceEvents:
break;
}
return labelComponent
}
Binding { target: valueLoader.item; property: "value"; value: model.value }
Binding {
target: entryDelegate.stateType && valueLoader.item.hasOwnProperty("unitString") ? valueLoader.item : null;
property: "unitString"
value: entryDelegate.stateType ? entryDelegate.stateType.unitString : ""
}
}
}
}
}
}
}
Component {
id: labelComponent
Label {
property var value
property string unitString
text: value + " " + unitString
font.pixelSize: app.smallFont
elide: Text.ElideRight
}
}
Component {
id: dateTimeComponent
Label {
property var value
text: Qt.formatDateTime(new Date(value * 1000), Qt.DefaultLocaleShortDate)
}
}
Component {
id: boolComponent
Item {
id: boolLed
property var value
Led {
implicitHeight: app.smallFont
on: boolLed.value === "true"
}
}
}
Component {
id: colorComponent
Item {
property var value
implicitHeight: app.smallFont
Rectangle {
height: parent.height
width: height * 2
color: parent.value
// radius: width / 2
border.color: app.foregroundColor
border.width: 1
}
}
}
}