367 lines · 12.3 KB · Text
RawDownload
////  ResourceCacheInspector.qml////  Created by Sam Gateau on 2019-09-17//  Copyright 2019 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html//import QtQuick 2.12import QtQuick.Controls 2.5import QtQuick.Layouts 1.3import QtQml.Models 2.12 import "../../lib/skit/qml" as Skitimport "../../lib/prop" as Prop Item {    id: root;    Prop.Global { id: global }     anchors.fill: parent.fill    property var cache: {}    property string cacheResourceName: ""      function fromScript(message) {        switch (message.method) {        case "resetItemList":            resetItemListFromCache()            break;        }    }     function requestResourceDetails(resourceURL) {        sendToScript({method: "inspectResource", params: {url: resourceURL, semantic: cacheResourceName}});     }     Component.onCompleted: {        resetItemListFromCache();    }     function fetchItemsList() {        var theList;        if (cache !== undefined) {            theList = cache.getResourceList();        } else {            theList = ["ResourceCacheInspector.cache is undefined"];        }        var theListString = new Array(theList.length)        for (var i in theList) {            theListString[i] = (theList[i].toString())        }        return theListString;    }     function resetItemListFromCache() {          resetItemList(fetchItemsList())    }     property var needFreshList : false     function updateItemListFromCache() {         needFreshList = true    }      Timer {        interval: 2000; running: true; repeat: true        onTriggered: pullFreshValues()    }     function pullFreshValues() {        if (needFreshList) {            updateItemList(fetchItemsList())            needFreshList = false        }    }        property alias resourceItemsModel: visualModel.model      property var currentItemsList: new Array();      function packItemEntry(item, identifier) {        var entry = { "identifier": identifier, "name": "", "scheme": "", "host": "", "pathDir": "", "url": item}        if (item.length > 0) {            // Detect scheme:            var schemePos = item.search(":")             entry.scheme = item.substring(0, schemePos)            if (schemePos < 0) schemePos = 0            else schemePos += 1             // path pos is probably after schemePos            var pathPos = schemePos                        // try to detect //userinfo@host:port            var token = item.substr(schemePos, 2);            if (token.search("//") == 0) {                pathPos += 2            }            item = item.substring(pathPos, item.length)            // item is now everything after scheme:[//]            var splitted = item.split('/')             // odd ball, the rest of the url has no other'/' ?            // in theory this means it s just the host info ?            // we are assuming that path ALWAYS starts with a slash            entry.host = splitted[0]                        if (splitted.length > 1) {                           entry.name = splitted[splitted.length - 1]                  // if splitted is longer than 2 then there should be a path dir                if (splitted.length > 2) {                      for (var i = 1; i < splitted.length - 1; i++) {                        entry.pathDir += '/' +   splitted[i]                       }                }            }        }        return entry    }      function resetItemList(itemList) {        currentItemsList = []        resourceItemsModel.clear()        for (var i in itemList) {            var item = itemList[i]            currentItemsList.push(item)            resourceItemsModel.append(packItemEntry(item, currentItemsList.length -1))        }        // At the end of it, force an update        visualModel.forceUpdate()       }     function updateItemList(newItemList) {        resetItemList(newItemList)     }     property var itemFields: ['identifier', 'name', 'scheme', 'host', 'pathDir', 'url']      Column {        id: header         anchors.top: parent.top        anchors.left: parent.left        anchors.right: parent.right                Item {            anchors.left: parent.left            anchors.right: parent.right            height: totalCount.height            id: headerTop             Prop.PropButton {                id: refreshButton                anchors.left: parent.left                anchors.verticalCenter: parent.verticalCenter                text: "Refresh"                color: needFreshList ? global.colorOrangeAccent : global.fontColor                 onPressed: { pullFreshValues() }            }             GridLayout {                anchors.left: refreshButton.right                anchors.right: parent.right                id: headerCountLane                columns: 3                 Item {                    Layout.fillWidth: true                    Prop.PropScalar {                        id: itemCount                        label: "Count"                        object: root.cache                        property: "numTotal"                         integral: true                        readOnly: true                    }                }                Item {                    Layout.fillWidth: true                    Prop.PropScalar {                        id: totalCount                        label: "Count"                        object: root.cache                        property: "numTotal"                         integral: true                        readOnly: true                        onSourceValueVarChanged: { updateItemListFromCache() }                    }                }                Item {                    Layout.fillWidth: true                    Prop.PropScalar {                        id: cachedCount                        label: "Cached"                        object: root.cache                        property: "numCached"                         integral: true                        readOnly: true                        onSourceValueVarChanged: { updateItemListFromCache() }                    }                }            }        }        Item {            anchors.left: parent.left            anchors.right: parent.right            height: orderSelector.height                        Prop.PropText {                anchors.left: parent.left                anchors.verticalCenter: parent.verticalCenter                width: 50                id: orderSelectorLabel                text: "Sort by"                horizontalAlignment: Text.AlignHCenter            }              Prop.PropComboBox {                anchors.left: orderSelectorLabel.right                width: 80                id: orderSelector                model: itemFields                currentIndex: 1                                property var isSchemeVisible: (currentIndex == 2 || filterFieldSelector.currentIndex == 2)                property var isHostVisible: (currentIndex == 3 || filterFieldSelector.currentIndex == 3)                property var isPathDirVisible: (currentIndex == 4 || filterFieldSelector.currentIndex == 4)                property var isURLVisible: (currentIndex == 5 || filterFieldSelector.currentIndex == 5)            }             Prop.PropTextField {                anchors.left: orderSelector.right                anchors.right: filterFieldSelector.left                id: nameFilter                placeholderText: qsTr("Filter by " + itemFields[filterFieldSelector.currentIndex] + "...")                Layout.fillWidth: true            }            Prop.PropComboBox {                anchors.right: parent.right                id: filterFieldSelector                model: itemFields                currentIndex: 1                width: 80                opacity: (nameFilter.text.length > 0) ? 1.0 : 0.5            }        }    }     Component {        id: resouceItemDelegate        MouseArea {            id: dragArea            property bool held: false            anchors { left: parent.left; right: parent.right }            height: item.height            onPressed: {held = true}            onReleased: {held = false}            onDoubleClicked: { requestResourceDetails(model.url) }            Rectangle {                id: item                width: parent.width                height: global.slimHeight                color: dragArea.held ? global.colorBackHighlight : (index % 2 ? global.colorBackShadow : global.colorBack)                              Row {                    id: itemRow                    anchors.verticalCenter : parent.verticalCenter                    Prop.PropText {                        id: itemIdentifier                        text: model.identifier                        width: 30                    }                    Prop.PropSplitter {                        visible: orderSelector.isSchemeVisible                        size:8                    }                    Prop.PropLabel {                        visible: orderSelector.isSchemeVisible                        text: model.scheme                        width: 30                    }                    Prop.PropSplitter {                        visible: orderSelector.isHostVisible                        size:8                    }                    Prop.PropLabel {                        visible: orderSelector.isHostVisible                        text: model.host                        width: 150                    }                    Prop.PropSplitter {                        visible: orderSelector.isPathDirVisible                        size:8                    }                    Prop.PropLabel {                        visible: orderSelector.isPathDirVisible                        text: model.pathDir                    }                    Prop.PropSplitter {                        size:8                    }                    Prop.PropLabel {                        visible: !orderSelector.isURLVisible                        text: model.name                    }                    Prop.PropLabel {                        visible: orderSelector.isURLVisible                        text: model.url                    }                }            }                    }    }     Skit.SortFilterModel {        id: visualModel        model: ListModel {}         property int sortOrder: orderSelector.currentIndex         property var lessThanArray: [            function(left, right) { return left.index < right.index },            function(left, right) { return left.name < right.name },            function(left, right) { return left.scheme < right.scheme },            function(left, right) { return left.host < right.host },            function(left, right) { return left.pathDir < right.pathDir },            function(left, right) { return left.url < right.url }        ];        lessThan: lessThanArray[sortOrder]         property int filterField: filterFieldSelector.currentIndex        onFilterFieldChanged: { refreshFilter() }        property var textFilter: nameFilter.text        onTextFilterChanged: { refreshFilter() }                function filterToken(itemWord, token) { return  (itemWord.search(token) > -1) }        property var acceptItemArray: [            function(item) { return true },            function(item) { return filterToken(item.identifier.toString(), textFilter) },            function(item) { return filterToken(item.name, textFilter) },            function(item) { return filterToken(item.scheme, textFilter) },            function(item) { return filterToken(item.host, textFilter) },            function(item) { return filterToken(item.pathDir, textFilter) },            function(item) { return filterToken(item.url, textFilter) }        ]         function refreshFilter() {            //console.log("refreshFilter! token = " + textFilter + " field = " + filterField)            acceptItem = acceptItemArray[(textFilter.length != 0) * + (1 + filterField)]        }         delegate: resouceItemDelegate    }     ListView {        anchors.top: header.bottom         anchors.bottom: parent.bottom        anchors.left: parent.left        anchors.right: parent.right        clip: true            id: listView        model: visualModel    }}