internal: use FileSystemModel for FileDialog

This commit is contained in:
2 * r + 2 * t 2025-09-02 18:40:31 +10:00
parent dccdcd417f
commit e70cb285ac
6 changed files with 44 additions and 46 deletions

View file

@ -79,7 +79,7 @@ Item {
anchors.rightMargin: Appearance.padding.larger - Appearance.padding.small
anchors.bottomMargin: Appearance.padding.normal - Appearance.padding.small
text: qsTr(`"%1" selected`).arg(root.currentItem?.fileName)
text: qsTr(`"%1" selected`).arg(root.currentItem?.modelData.name)
}
}

View file

@ -52,7 +52,7 @@ StyledRect {
disabled: !root.dialog.selectionValid
function onClicked(): void {
root.dialog.accepted(root.folder.currentItem.filePath);
root.dialog.accepted(root.folder.currentItem.modelData.path);
}
}

View file

@ -36,8 +36,8 @@ LazyLoader {
property list<string> filters: loader.filters
readonly property bool selectionValid: {
const item = folderContents.currentItem;
return item && !item.fileIsDir && (filters.includes("*") || filters.includes(item.fileSuffix));
const file = folderContents.currentItem?.modelData;
return file && !file.isDir && (filters.includes("*") || filters.includes(file.suffix));
}
function accepted(path: string): void {

View file

@ -6,13 +6,12 @@ import "../images"
import qs.services
import qs.config
import qs.utils
import Caelestia
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Controls
import Qt.labs.folderlistmodel
Item {
id: root
@ -86,37 +85,30 @@ Item {
Keys.onReturnPressed: {
if (root.dialog.selectionValid)
root.dialog.accepted(currentItem.filePath);
root.dialog.accepted(currentItem.modelData.path);
}
Keys.onEnterPressed: {
if (root.dialog.selectionValid)
root.dialog.accepted(currentItem.filePath);
root.dialog.accepted(currentItem.modelData.path);
}
ScrollBar.vertical: StyledScrollBar {}
model: FolderListModel {
showDirsFirst: true
folder: {
let url = "file://";
model: FileSystemModel {
path: {
if (root.dialog.cwd[0] === "Home")
url += `${Paths.strip(Paths.home)}/${root.dialog.cwd.slice(1).join("/")}`;
return `${Paths.strip(Paths.home)}/${root.dialog.cwd.slice(1).join("/")}`;
else
url += root.dialog.cwd.join("/");
return url;
return root.dialog.cwd.join("/");
}
onFolderChanged: view.currentIndex = -1
onPathChanged: view.currentIndex = -1
}
delegate: StyledRect {
id: item
required property int index
required property string fileName
required property string filePath
required property url fileUrl
required property string fileSuffix
required property bool fileIsDir
required property FileSystemEntry modelData
readonly property real nonAnimHeight: icon.implicitHeight + name.anchors.topMargin + name.implicitHeight + Appearance.padding.normal * 2
@ -130,10 +122,10 @@ Item {
StateLayer {
onDoubleClicked: {
if (item.fileIsDir)
root.dialog.cwd.push(item.fileName);
if (item.modelData.isDir)
root.dialog.cwd.push(item.modelData.name);
else if (root.dialog.selectionValid)
root.dialog.accepted(item.filePath);
root.dialog.accepted(item.modelData.path);
}
function onClicked(): void {
@ -150,31 +142,18 @@ Item {
implicitSize: Sizes.itemWidth - Appearance.padding.normal * 2
source: {
if (!item.fileIsDir)
return Quickshell.iconPath("application-x-zerosize");
if (item.modelData.isImage)
return Qt.resolvedUrl(item.modelData.path);
const name = item.fileName;
if (!item.modelData.isDir)
return Quickshell.iconPath(item.modelData.mimeType.replace("/", "-"), "application-x-zerosize");
const name = item.modelData.name;
if (root.dialog.cwd.length === 1 && ["Desktop", "Documents", "Downloads", "Music", "Pictures", "Public", "Templates", "Videos"].includes(name))
return Quickshell.iconPath(`folder-${name.toLowerCase()}`);
return Quickshell.iconPath("inode-directory");
}
onStatusChanged: {
if (status === Image.Error)
source = Quickshell.iconPath("error");
}
Process {
running: !item.fileIsDir
command: ["file", "--mime", "-b", item.filePath]
stdout: StdioCollector {
onStreamFinished: {
const mime = text.split(";")[0].replace("/", "-");
icon.source = Images.validImageTypes.some(t => mime === `image-${t}`) ? item.fileUrl : Quickshell.iconPath(mime, "image-missing");
}
}
}
}
StyledText {
@ -187,7 +166,7 @@ Item {
anchors.margins: Appearance.padding.normal
horizontalAlignment: Text.AlignHCenter
text: item.fileName
text: item.modelData.name
elide: item.GridView.isCurrentItem ? Text.ElideNone : Text.ElideRight
wrapMode: item.GridView.isCurrentItem ? Text.WrapAtWordBoundaryOrAnywhere : Text.NoWrap
}

View file

@ -6,6 +6,7 @@
#include <QFileSystemWatcher>
#include <QFuture>
#include <QImageReader>
#include <QMimeDatabase>
#include <QObject>
#include <qqmlintegration.h>
@ -18,22 +19,27 @@ class FileSystemEntry : public QObject {
Q_PROPERTY(QString relativePath READ relativePath CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString parentDir READ parentDir CONSTANT)
Q_PROPERTY(QString suffix READ suffix CONSTANT)
Q_PROPERTY(qint64 size READ size CONSTANT)
Q_PROPERTY(bool isDir READ isDir CONSTANT)
Q_PROPERTY(bool isImage READ isImage CONSTANT)
Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
public:
explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr)
: QObject(parent)
, m_fileInfo(QFileInfo(path))
, m_path(path)
, m_relativePath(relativePath) {}
, m_relativePath(relativePath)
, m_isImageInitialised(false)
, m_mimeTypeInitialised(false) {}
QString path() const { return m_path; };
QString relativePath() const { return m_relativePath; };
QString name() const { return m_fileInfo.fileName(); };
QString parentDir() const { return m_fileInfo.absolutePath(); };
QString suffix() const { return m_fileInfo.completeSuffix(); };
qint64 size() const { return m_fileInfo.size(); };
bool isDir() const { return m_fileInfo.isDir(); };
@ -46,6 +52,15 @@ public:
return m_isImage;
}
QString mimeType() {
if (!m_mimeTypeInitialised) {
const QMimeDatabase db;
m_mimeType = db.mimeTypeForFile(m_path).name();
m_mimeTypeInitialised = true;
}
return m_mimeType;
}
private:
const QFileInfo m_fileInfo;
@ -54,6 +69,9 @@ private:
bool m_isImage;
bool m_isImageInitialised;
QString m_mimeType;
bool m_mimeTypeInitialised;
};
class FileSystemModel : public QAbstractListModel {
@ -79,7 +97,7 @@ public:
explicit FileSystemModel(QObject* parent = nullptr)
: QAbstractListModel(parent)
, m_recursive(true)
, m_recursive(false)
, m_watchChanges(true)
, m_showHidden(false)
, m_filter(NoFilter) {

View file

@ -73,6 +73,7 @@ Searcher {
FileSystemModel {
id: wallpapers
recursive: true
path: Paths.expandTilde(Paths.wallsdir)
filter: FileSystemModel.Images
}