feat(qt): Shift ranges in the library folders settings table

A row or checkbox click toggled one folder. Shift now adds the run over the
rows the filter shows, Ctrl adds one, and the ids stay numbers for the
removal action.

cc
This commit is contained in:
vicrodh committed 2026-09-14 10:31:40 -06:00
1 parent b1791d6223
commit cf3069386b
2 files changed
+47 -6

No files matched your search

@@ -42,10 +42,23 @@ Column {
})
}
function isSelected(id) { return selectedIds.indexOf(id) >= 0 }
function toggleSelected(id) {
const next = selectedIds.slice()
const at = next.indexOf(id)
if (at >= 0) next.splice(at, 1); else next.push(id)
/// A plain or Ctrl click toggles one folder; Shift adds the range from the
/// last plain click over the rows SHOWN (the filter is a view filter) —
/// the rule every multi-select list shares (controls/SelectionModel.qml).
SelectionModel { id: folderSel }
function toggleSelected(id, mods) {
const rows = root.shown()
const current = {}
for (let i = 0; i < selectedIds.length; i++)
current[String(selectedIds[i])] = true
const picked = folderSel.next(current, id, rows,
mods === undefined ? Qt.NoModifier : mods)
// Back to the ids themselves (the removal action takes them as
// numbers), keeping earlier picks the filter currently hides.
const next = selectedIds.filter(function (sid) { return picked[String(sid)] === true })
for (let j = 0; j < rows.length; j++)
if (picked[String(rows[j].id)] === true && next.indexOf(rows[j].id) < 0)
next.push(rows[j].id)
selectedIds = next
}
function scanLabel(ts) {
@@ -118,6 +131,7 @@ Column {
QbzBridge.settingsString("library-remove-folders",
JSON.stringify(root.selectedIds))
root.selectedIds = []
folderSel.anchorId = ""
}
}
}
@@ -279,7 +293,9 @@ Column {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.toggleSelected(folderRow.modelData.id)
onClicked: function (mouse) {
root.toggleSelected(folderRow.modelData.id, mouse.modifiers)
}
}
Row {
@@ -292,7 +308,9 @@ Column {
width: root.kioskHost ? 44 : 20
anchors.verticalCenter: parent.verticalCenter
checked: root.isSelected(folderRow.modelData.id)
onToggled: root.toggleSelected(folderRow.modelData.id)
onToggled: function (mods) {
root.toggleSelected(folderRow.modelData.id, mods)
}
}
// FOLDER: type glyph + name.
Row {
+23
View File
@@ -13,6 +13,7 @@ import "../../crates/qbz-qt/qml/cards"
import "../../crates/qbz-qt/qml/views" as Views
import "../../crates/qbz-qt/qml/views/local" as Local
import "../../crates/qbz-qt/qml/views/myqbz" as MyQbz
import "../../crates/qbz-qt/qml/settings" as Settings
Item {
id: root
@@ -156,6 +157,18 @@ Item {
view: railView
}
// ---- Settings > Local Library folders ---------------------------------------
Settings.LibraryFolderTable {
id: folderTable
x: 0; y: 880
width: 1200
lib: ({ "folders": [1, 2, 3, 4, 5].map(function (n) {
return { "id": n, "displayName": "Music " + n, "path": "/music/" + n,
"isNetwork": false, "enabled": true, "accessible": true,
"status": "active", "lastScan": 0 }
}) })
}
TestCase {
name: "MultiSelect"
when: windowShown
@@ -225,6 +238,7 @@ Item {
QbzLocal.treeCalls = []
railView.opened = []
railView.treeSelectMode = true
folderTable.selectedIds = []
}
// A point of the row with nothing drawn over it but the body: the
@@ -376,6 +390,15 @@ Item {
clickOn(railCheck("/m/b"), 6, 6, Qt.ShiftModifier)
compare(QbzLocal.treeCalls[3], "folder:/m/b")
}
function test_settings_folder_table_shift_range() {
var first = textItem(folderTable, "Music 1")
clickOn(first, 10, first.height / 2)
var fourth = textItem(folderTable, "Music 4")
clickOn(fourth, 10, fourth.height / 2, Qt.ShiftModifier)
compare(folderTable.selectedIds.slice().sort().join(","), "1,2,3,4")
verify(folderTable.isSelected(2), "the numeric ids stay numbers")
}
}
// ---- the selection rule itself ---------------------------------------------