[ui] more flexible filtering mechanism + filter with viewIds

This commit is contained in:
Loïc Vital 2022-11-04 18:12:30 +01:00
parent 047b6fb589
commit e24310d1a1
3 changed files with 41 additions and 48 deletions

View file

@ -109,9 +109,6 @@ Panel {
SearchBar {
id: searchBar
width: 100
onTextChanged: {
sortedModel.updateFilter("path", text);
}
}
MaterialToolButton {
@ -207,35 +204,33 @@ Panel {
id: sortedModel
model: m.viewpoints
sortRole: "path.basename"
property var filterRoleType: ""
filterRole: _reconstruction.sfmReport ? filterRoleType : ""
filterValue: false
function updateFilter(role, value) {
grid.updateSelectedViewFromGrid = false
sortedModel.filterRoleType = role
sortedModel.filterValue = value
grid.updateCurrentIndexFromSelectionViewId()
grid.updateSelectedViewFromGrid = true
grid.makeCurrentItemVisible()
}
filters: [
[
{role: "path", value: searchBar.text},
{role: "viewId.asString", value: searchBar.text}
],
{role: "viewId.isReconstructed", value: reconstructionFilter}
]
property var reconstructionFilter: undefined
// override modelData to return basename of viewpoint's path for sorting
function modelData(item, roleName_) {
var roleNameAndCmd = roleName_.split(".")
var roleName = roleName_
var cmd = ""
var roleNameAndCmd = roleName_.split(".");
var roleName = roleName_;
var cmd = "";
if(roleNameAndCmd.length >= 2)
{
roleName = roleNameAndCmd[0]
cmd = roleNameAndCmd[1]
roleName = roleNameAndCmd[0];
cmd = roleNameAndCmd[1];
}
if(cmd == "isReconstructed")
return _reconstruction.isReconstructed(item.model.object)
var value = item.model.object.childAttribute(roleName).value
return _reconstruction.isReconstructed(item.model.object);
var value = item.model.object.childAttribute(roleName).value;
if(cmd == "basename")
return Filepath.basename(value)
return Filepath.basename(value);
if (cmd == "asString")
return value.toString();
return value
}
@ -592,9 +587,9 @@ Panel {
onCheckedChanged:{
if(checked) {
sortedModel.updateFilter("", true)
estimatedCamerasFilterButton.checked = false
nonEstimatedCamerasFilterButton.checked = false
sortedModel.reconstructionFilter = undefined;
estimatedCamerasFilterButton.checked = false;
nonEstimatedCamerasFilterButton.checked = false;
intrinsicsFilterButton.checked = false;
}
}
@ -614,9 +609,9 @@ Panel {
onCheckedChanged:{
if(checked) {
sortedModel.updateFilter("viewId.isReconstructed", true)
inputImagesFilterButton.checked = false
nonEstimatedCamerasFilterButton.checked = false
sortedModel.reconstructionFilter = true;
inputImagesFilterButton.checked = false;
nonEstimatedCamerasFilterButton.checked = false;
intrinsicsFilterButton.checked = false;
}
}
@ -643,9 +638,9 @@ Panel {
onCheckedChanged:{
if(checked) {
sortedModel.updateFilter("viewId.isReconstructed", false)
inputImagesFilterButton.checked = false
estimatedCamerasFilterButton.checked = false
sortedModel.reconstructionFilter = false;
inputImagesFilterButton.checked = false;
estimatedCamerasFilterButton.checked = false;
intrinsicsFilterButton.checked = false;
}
}

View file

@ -19,13 +19,11 @@ DelegateModel {
property string sortRole: "" /// the role to use for sorting
property int sortOrder: Qt.AscendingOrder /// the sorting order
property string filterRole: "" /// the role to use for filtering
property variant filterValue /// the value to use as filter
property var filters: []
onSortRoleChanged: invalidateSort()
onSortOrderChanged: invalidateSort()
onFilterRoleChanged: invalidateFilter()
onFilterValueChanged: invalidateFilter()
onFiltersChanged: invalidateFilters()
// display "filtered" group
filterOnGroup: "filtered"
@ -50,7 +48,7 @@ DelegateModel {
sort()
}
// perform filter invalidation in both cases
invalidateFilter()
invalidateFilters()
}
},
// Group for storing filtered items
@ -85,6 +83,9 @@ DelegateModel {
* TODO: add case sensitivity / whole word options for Strings
*/
function respectFilter(value, filter) {
if (filter === undefined) {
return true;
}
switch(value.constructor.name)
{
case "String":
@ -94,6 +95,11 @@ DelegateModel {
}
}
function respectFilters(item) {
let cond = (filter => respectFilter(modelData(item, filter.role), filter.value));
return filters.every(x => Array.isArray(x) ? x.some(cond) : cond(x));
}
/// Reverse sort order (toggle between Qt.AscendingOrder / Qt.DescendingOrder)
function reverseSortOrder() {
sortOrder = sortOrder == Qt.AscendingOrder ? Qt.DescendingOrder : Qt.AscendingOrder
@ -113,18 +119,11 @@ DelegateModel {
}
/// Invalidate filtering
function invalidateFilter() {
// no filtering, add everything to the filtered group
if(!filterRole)
{
items.addGroups(0, items.count, "filtered")
return
}
function invalidateFilters() {
for(var i=0; i < items.count; ++i)
{
// if the property value contains filterText, add it to the filtered group
if(respectFilter(modelData(items.get(i), filterRole), filterValue))
if(respectFilters(items.get(i)))
{
items.addGroups(items.get(i), 1, "filtered")
}

View file

@ -188,8 +188,7 @@ FloatingPane {
id: sortedMetadataModel
model: metadataModel
sortRole: "raw"
filterRole: "raw"
filterValue: searchBar.text
filters: [{role: "raw", value: searchBar.text}]
delegate: RowLayout {
width: parent.width
Label {