From d940e705648114c8878c14ecb3d84cfdeb13fe54 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 24 Sep 2019 00:31:16 -0700 Subject: [PATCH] Adding a proper SortFilterModel --- .../cache/cash/ResourceCacheInspector.qml | 221 +++++++----------- .../utilities/cache/cash/SortFilterModel.qml | 118 ++++++++++ 2 files changed, 205 insertions(+), 134 deletions(-) create mode 100644 scripts/developer/utilities/cache/cash/SortFilterModel.qml diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index 71dc2f7d24..badc6e6754 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -59,7 +59,7 @@ Item { } Timer { - interval: 1000; running: true; repeat: true + interval: 2000; running: true; repeat: true onTriggered: pullFreshValues() } @@ -70,7 +70,65 @@ Item { needFreshList = false } } - + + property alias resourceItemsModel: visualModel.model + property var currentItemsList: new Array(); + + function packItemEntry(item, index) { + var entry = { "index": index, "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)) + } + } + + function updateItemList(newItemList) { + resetItemList(newItemList) + } + property var itemFields: ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] @@ -81,15 +139,6 @@ Item { anchors.left: parent.left anchors.right: parent.right - - /*Prop.PropButton { - anchors.left: parent.left - id: refresh - text: "Refresh" - onClicked: { - resetItemListFromCache() - } - }*/ Item { anchors.left: parent.left anchors.right: parent.right @@ -104,7 +153,7 @@ Item { property: "numTotal" integral: true readOnly: true - onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() } + onSourceValueVarChanged: { updateItemListFromCache() } } Prop.PropScalar { id: cachedCount @@ -115,7 +164,7 @@ Item { property: "numCached" integral: true readOnly: true - onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() } + onSourceValueVarChanged: { updateItemListFromCache() } } } @@ -128,6 +177,7 @@ Item { anchors.left: parent.left id: orderSelector model: itemFields + currentIndex: 1 property var selectedIndex: currentIndex property var isSchemeVisible: (currentIndex == 2) @@ -136,12 +186,19 @@ Item { property var isURLVisible: (currentIndex == 5) } - /* Prop.PropCheckBox { + Prop.PropCheckBox { anchors.left: orderSelector.right id: listQRC - checked: true + checked: false text: "list qrc" - }*/ + } + + TextField { + anchors.left: listQRC.right + id: nameFilter + placeholderText: qsTr("Search by name...") + Layout.fillWidth: true + } } } @@ -212,139 +269,35 @@ Item { } } - // ['index', 'name', 'scheme', 'host', 'pathDir', 'url'] - DelegateModel { + SortFilterModel { id: visualModel - model: ListModel {} - property var filterQRC: function(item) { return item.scheme == "qrc" } - property var lessThan: [ + property int sortOrder: orderSelector.selectedIndex + + 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 sortOrder: orderSelector.selectedIndex - onSortOrderChanged: items.setGroups(0, items.count, "unsorted") - - property bool listQRCChecked: listQRC.checked - onListQRCCheckedChanged: items.setGroups(0, items.count, "unsorted") - - function insertPosition(lessThan, item) { - var lower = 0 - var upper = items.count - while (lower < upper) { - var middle = Math.floor(lower + (upper - lower) / 2) - var result = lessThan(item.model, items.get(middle).model); - if (result) { - upper = middle - } else { - lower = middle + 1 - } - } - return lower - } - - function sort(lessThan) { - while (unsortedItems.count > 0) { - var item = unsortedItems.get(0) - // var doHide = (!listQRCChecked && filterQRC(item.model)) - - var index = insertPosition(lessThan, item) - - item.groups = "items" - // if (doHide) { - // item.inItems = false; - // } else { - // item.inItems = true; - items.move(item.itemsIndex, index) - // } - } - } - - items.includeByDefault: false - groups: - DelegateModelGroup { - id: unsortedItems - name: "unsorted" - - includeByDefault: true - onChanged: { - if (visualModel.sortOrder == visualModel.lessThan.length) - setGroups(0, count, "items") - else - visualModel.sort(visualModel.lessThan[visualModel.sortOrder]) - } - } + property int listQRCChecked: listQRC.checked + property int textFilter: nameFilter.text + property var acceptItemArray: [ + function(item) { return item.scheme != "qrc" }, + // function(item) { return true } + function(item) { return (item.name.search(textFilter) >= 0) } + ] + acceptItem: acceptItemArray[0 + listQRCChecked] delegate: resouceItemDelegate } - property alias resourceItemsModel: visualModel.model - property var currentItemsList: new Array(); - - function packItemEntry(item, index) { - var entry = { "index": index, "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)) - } - } - - function updateItemList(newItemList) { - resetItemList(newItemList) - } - - - ListView { anchors.top: header.bottom diff --git a/scripts/developer/utilities/cache/cash/SortFilterModel.qml b/scripts/developer/utilities/cache/cash/SortFilterModel.qml new file mode 100644 index 0000000000..a4a9c3f6a3 --- /dev/null +++ b/scripts/developer/utilities/cache/cash/SortFilterModel.qml @@ -0,0 +1,118 @@ +import QtQuick 2.9 +import QtQml.Models 2.3 + +DelegateModel { + id: delegateModel + + property var lessThan: function(left, right) { return true; } + property var acceptItem: function(item) { return true; } +/* + function insertPosition(lessThan, item) { + var lower = 0 + var upper = items.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThan(item.model, items.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 + } + } + return lower + } + + function sort(lessThan) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + + var index = insertPosition(lessThan, item) + + item.groups = "items" + items.move(item.itemsIndex, index) + } + } +*/ + function insertPosition(lessThanFunctor, item) { + var lower = 0 + var upper = visibleItems.count + while (lower < upper) { + var middle = Math.floor(lower + (upper - lower) / 2) + var result = lessThanFunctor(item.model, visibleItems.get(middle).model); + if (result) { + upper = middle + } else { + lower = middle + 1 + } + } + return lower + } + + function sort(lessThanFunctor, acceptItemFunctor) { + while (unsortedItems.count > 0) { + var item = unsortedItems.get(0) + + if (acceptItemFunctor(item.model)) { + var index = insertPosition(lessThanFunctor, item) + + item.groups = ["items","visible"] + visibleItems.move(item.visibleIndex, index) + } else { + item.groups = ["items"] + } + } + } + + function update() { + if (items.count > 0) { + items.setGroups(0, items.count, ["items","unsorted"]); + } + + sort(lessThan, acceptItem) + /* + // Step 1: Filter items + var visible = []; + for (var i = 0; i < items.count; ++i) { + var item = items.get(i); + if (filterAcceptsItem(item.model)) { + visible.push(item); + } + } + + // Step 2: Sort the list of visible items + visible.sort(function(a, b) { + return lessThan(a.model, b.model) ? -1 : 1; + }); + + // Step 3: Add all items to the visible group: + for (i = 0; i < visible.length; ++i) { + item = visible[i]; + item.inVisible = true; + if (item.visibleIndex !== i) { + visibleItems.move(item.visibleIndex, i, 1); + } + } + */ + } + + items.onChanged: update() + onLessThanChanged: update() + onAcceptItemChanged: update() + + groups: [ + DelegateModelGroup { + id: visibleItems + + name: "visible" + includeByDefault: false + }, + DelegateModelGroup { + id: unsortedItems + + name: "unsorted" + includeByDefault: false + } + ] + + filterOnGroup: "visible" +} \ No newline at end of file