status-desktop/monitoring/MonitorEntryPoint.qml

410 lines
14 KiB
QML
Raw Normal View History

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import Monitoring 1.0
import Qt.labs.settings 1.0
import AppLayouts.Wallet.stores 1.0 as WalletStores
Component {
ColumnLayout {
spacing: 0
Settings {
property alias tabIndex: tabBar.currentIndex
property alias modelObjectName: objectNameTextFiled.text
}
TabBar {
id: tabBar
Layout.fillWidth: true
Layout.bottomMargin: 10
TabButton {
text: "Context properties inspection"
}
TabButton {
text: "Models inspection"
}
currentIndex: swipeView.currentIndex
}
StackLayout {
id: swipeView
currentIndex: tabBar.currentIndex
//anchors.fill: parent
Layout.fillWidth: true
Layout.fillHeight: true
SplitView {
id: root
ColumnLayout {
SplitView.fillHeight: true
SplitView.preferredWidth: 450
spacing: 5
Label {
Layout.fillWidth: true
Layout.margins: 5
text: "Context properties:"
font.bold: true
}
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 5
model: Monitor.contexPropertiesModel
clip: true
spacing: 5
delegate: Item {
implicitWidth: delegateRow.implicitWidth
implicitHeight: delegateRow.implicitHeight
readonly property var contextPropertyValue:
MonitorUtils.contextPropertyBindingHelper(name, this).value
Row {
id: delegateRow
Label {
text: name
}
Label {
text: ` [${MonitorUtils.typeName(contextPropertyValue)}]`
color: "darkgreen"
}
Label {
text: ` (${MonitorUtils.valueToString(contextPropertyValue)})`
color: "darkred"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
inspectionStackView.clear()
headerModel.clear()
const props = {
name: name,
objectForInspection: contextPropertyValue
}
inspectionStackView.push(inspectionList, props)
headerModel.append({ name })
}
}
}
}
}
Component {
id: modelInspectionComponent
ModelInspectionPane {}
}
Component {
id: inspectionList
ListView {
property var objectForInspection
property string name
ScrollBar.vertical: ScrollBar {}
onObjectForInspectionChanged: {
inspectionModel.clear()
if (!objectForInspection)
return
const items = []
for (const property in objectForInspection) {
const type = typeof objectForInspection[property]
if (type === "function") {
items.push({
name: property,
category: "functions",
isModel: false,
type: type
})
} else {
const value = objectForInspection[property]
const detailedType = MonitorUtils.typeName(value)
const isModel = Monitor.isModel(value)
items.push({
name: property,
type: detailedType,
category: isModel? "models" : "properties",
isModel: isModel
})
}
}
items.sort((a, b) => {
const nameA = a.category
const nameB = b.category
if (nameA === nameB)
return 0
if (nameA === "models")
return -1
if (nameB === "models")
return 1
if (nameA < nameB)
return -1
if (nameA > nameB)
return 1
})
inspectionModel.append(items)
}
anchors.fill: parent
spacing: 5
clip: true
model: ListModel {
id: inspectionModel
}
delegate: Item {
implicitWidth: delegateRow.implicitWidth
implicitHeight: delegateRow.implicitHeight
Row {
id: delegateRow
readonly property var object: objectForInspection[name]
Label {
text: name
}
Loader {
active: type !== "function"
sourceComponent: Label {
text: ` [${type}]`
color: "darkgreen"
}
}
Loader {
active: type !== "function"
sourceComponent: Label {
text: ` (${MonitorUtils.valueToString(delegateRow.object)})`
color: "darkred"
}
}
Loader {
active: isModel
sourceComponent: Label {
text: `, ${delegateRow.object.rowCount()} items`
color: "darkred"
font.bold: true
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if (isModel) {
const props = {
name: name,
model: objectForInspection[name]
}
inspectionStackView.push(modelInspectionComponent,
props, StackView.Immediate)
headerModel.append({ name })
} else if (type !== "function") {
const props = {
name: name,
objectForInspection: objectForInspection[name]
}
inspectionStackView.push(inspectionList, props, StackView.Immediate)
headerModel.append({ name })
}
}
}
}
section.property: "category"
section.delegate: Pane {
leftPadding: 0
Label {
text: section
font.bold: true
}
}
}
}
Pane {
SplitView.fillHeight: true
SplitView.minimumWidth: 100
ColumnLayout {
anchors.fill: parent
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: false
RoundButton {
text: "⬅️"
visible: headerRepeater.count > 1
onClicked: {
inspectionStackView.pop(StackView.Immediate)
headerModel.remove(headerModel.count - 1)
}
}
Repeater {
id: headerRepeater
model: ListModel {
id: headerModel
}
delegate: TextInput {
readonly property bool last: headerRepeater.count - 1 === index
text: model.name + (last ? "" : " -> ")
font.pixelSize: 20
font.bold: true
selectByMouse: true
readOnly: true
}
}
}
MenuSeparator {
visible: headerRepeater.count
Layout.fillWidth: true
}
StackView {
id: inspectionStackView
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
}
Pane {
ColumnLayout {
anchors.fill: parent
RowLayout {
Layout.fillHeight: false
Layout.fillWidth: true
Label {
text: "Model's object name:"
}
TextField {
id: objectNameTextFiled
Layout.fillWidth: true
selectByMouse: true
onAccepted: searchButton.clicked()
}
Button {
id: searchButton
text: "Search"
onClicked: {
const roots = [
applicationWindow,
WalletStores.RootStore
]
let obj = null
for (let root of roots) {
obj = Monitor.findChild(root, objectNameTextFiled.text)
if (obj)
break
}
if (!obj) {
objLabel.objStr = "Model not found"
rolesModelContent.model = null
return
}
if (!Monitor.isModel(obj)) {
objLabel.objStr = "Found object is not a model"
rolesModelContent.model = null
return
}
objLabel.objStr = obj.toString()
rolesModelContent.model = obj
}
}
}
Label {
id: objLabel
property string objStr
Layout.fillWidth: true
visible: objStr !== ""
text: "Object: " + objStr
}
ModelInspectionPane {
id: rolesModelContent
showControls: false
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
}
}
}