From 1768dacac3dcba29a6a5ce71a289cae156f93560 Mon Sep 17 00:00:00 2001 From: Spyridon Siarapis Date: Sun, 22 Mar 2026 09:03:50 +0100 Subject: [PATCH] fix(NFilePicker): Added ability to use both Control and Shift with both having different functionality --- Widgets/NFilePicker.qml | 109 +++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/Widgets/NFilePicker.qml b/Widgets/NFilePicker.qml index 2a0503e6d..84395c1d7 100644 --- a/Widgets/NFilePicker.qml +++ b/Widgets/NFilePicker.qml @@ -168,6 +168,55 @@ Popup { } } + // Function when an item is clicked, either a folder or a file since both have the same functionality, reduces repetitive code + function itemClicked(modifiers, path) { + var list = currentSelection.slice(); + const index = list.indexOf(path); + if (root.allowMultiSelection && (modifiers & Qt.ShiftModifier) && list.length > 0) { + if (index > -1) { + list.splice(index, 1); + currentSelection = list; + } else { + var i = 0; + var toggle = false; + const firstItemPath = list[0]; + while (i < filteredModel.count) { + const itemPath = filteredModel.get(i).filePath; + + // This should be called twice, when we get to the item selected and when we get to the starting item. + if (itemPath === firstItemPath || itemPath === path) { + toggle = !toggle; + } + + // Add all files between the starting item and the item selected. + if (toggle) { + if (!list.includes(itemPath)) { + list.push(itemPath); + } + } + + i++; + } + + // Add the path selected as well since it's skipped in the while loop + if (!list.includes(path)) { + list.push(path); + } + currentSelection = list; + } + } else if (root.allowMultiSelection && (modifiers & Qt.ControlModifier)) { + if (index > -1) { + list.splice(index, 1); + currentSelection = list; + } else { + list.push(path); + currentSelection = list; + } + } else { + currentSelection = [path]; + } + } + ColumnLayout { anchors.fill: parent spacing: Style.marginM @@ -579,39 +628,13 @@ Popup { if (model.fileIsDir) { // In folder mode, single click selects the folder if (root.selectionMode === "folders") { - if (root.allowMultiSelection && (mouse.modifiers & Qt.ShiftModifier)) { - // Deep copy otherwise the isSelected might not get updated. - var list = JSON.parse(JSON.stringify(filePickerPanel.currentSelection)); - const index = list.indexOf(model.filePath); - if (index > -1) { - list.splice(index, 1); - filePickerPanel.currentSelection = list; - } else { - list.push(model.filePath); - filePickerPanel.currentSelection = list; - } - } else { - filePickerPanel.currentSelection = [model.filePath]; - } + filePickerPanel.itemClicked(mouse.modifiers, model.filePath); } // In file mode, single click on folder does nothing (must double-click to enter) } else { // Single click on file selects it (only in file mode) if (root.selectionMode === "files") { - if (root.allowMultiSelection && (mouse.modifiers & Qt.ShiftModifier)) { - // Deep copy otherwise the isSelected might not get updated. - var list = JSON.parse(JSON.stringify(filePickerPanel.currentSelection)); - const index = list.indexOf(model.filePath); - if (index > -1) { - list.splice(index, 1); - filePickerPanel.currentSelection = list; - } else { - list.push(model.filePath); - filePickerPanel.currentSelection = list; - } - } else { - filePickerPanel.currentSelection = [model.filePath]; - } + filePickerPanel.itemClicked(mouse.modifiers, model.filePath); } } } @@ -704,39 +727,13 @@ Popup { if (model.fileIsDir) { // In folder mode, single click selects the folder if (root.selectionMode === "folders") { - // Deep copy otherwise the isSelected might not get updated. - if (root.allowMultiSelection && (mouse.modifiers & Qt.ShiftModifier)) { - var list = JSON.parse(JSON.stringify(filePickerPanel.currentSelection)); - const index = list.indexOf(model.filePath); - if (index > -1) { - list.splice(index, 1); - filePickerPanel.currentSelection = list; - } else { - list.push(model.filePath); - filePickerPanel.currentSelection = list; - } - } else { - filePickerPanel.currentSelection = [model.filePath]; - } + filePickerPanel.itemClicked(mouse.modifiers, model.filePath); } // In file mode, single click on folder does nothing (must double-click to enter) } else { // Single click on file selects it (only in file mode) if (root.selectionMode === "files") { - if (root.allowMultiSelection && (mouse.modifiers & Qt.ShiftModifier)) { - // Deep copy otherwise the isSelected might not get updated. - var list = JSON.parse(JSON.stringify(filePickerPanel.currentSelection)); - const index = list.indexOf(model.filePath); - if (index > -1) { - list.splice(index, 1); - filePickerPanel.currentSelection = list; - } else { - list.push(model.filePath); - filePickerPanel.currentSelection = list; - } - } else { - filePickerPanel.currentSelection = [model.filePath]; - } + filePickerPanel.itemClicked(mouse.modifiers, model.filePath); } } }