internal: use FileSystemModel for FileDialog
This commit is contained in:
parent
dccdcd417f
commit
e70cb285ac
6 changed files with 44 additions and 46 deletions
|
|
@ -79,7 +79,7 @@ Item {
|
||||||
anchors.rightMargin: Appearance.padding.larger - Appearance.padding.small
|
anchors.rightMargin: Appearance.padding.larger - Appearance.padding.small
|
||||||
anchors.bottomMargin: Appearance.padding.normal - 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ StyledRect {
|
||||||
disabled: !root.dialog.selectionValid
|
disabled: !root.dialog.selectionValid
|
||||||
|
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
root.dialog.accepted(root.folder.currentItem.filePath);
|
root.dialog.accepted(root.folder.currentItem.modelData.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ LazyLoader {
|
||||||
property list<string> filters: loader.filters
|
property list<string> filters: loader.filters
|
||||||
|
|
||||||
readonly property bool selectionValid: {
|
readonly property bool selectionValid: {
|
||||||
const item = folderContents.currentItem;
|
const file = folderContents.currentItem?.modelData;
|
||||||
return item && !item.fileIsDir && (filters.includes("*") || filters.includes(item.fileSuffix));
|
return file && !file.isDir && (filters.includes("*") || filters.includes(file.suffix));
|
||||||
}
|
}
|
||||||
|
|
||||||
function accepted(path: string): void {
|
function accepted(path: string): void {
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,12 @@ import "../images"
|
||||||
import qs.services
|
import qs.services
|
||||||
import qs.config
|
import qs.config
|
||||||
import qs.utils
|
import qs.utils
|
||||||
|
import Caelestia
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Qt.labs.folderlistmodel
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -86,37 +85,30 @@ Item {
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
if (root.dialog.selectionValid)
|
if (root.dialog.selectionValid)
|
||||||
root.dialog.accepted(currentItem.filePath);
|
root.dialog.accepted(currentItem.modelData.path);
|
||||||
}
|
}
|
||||||
Keys.onEnterPressed: {
|
Keys.onEnterPressed: {
|
||||||
if (root.dialog.selectionValid)
|
if (root.dialog.selectionValid)
|
||||||
root.dialog.accepted(currentItem.filePath);
|
root.dialog.accepted(currentItem.modelData.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollBar.vertical: StyledScrollBar {}
|
ScrollBar.vertical: StyledScrollBar {}
|
||||||
|
|
||||||
model: FolderListModel {
|
model: FileSystemModel {
|
||||||
showDirsFirst: true
|
path: {
|
||||||
folder: {
|
|
||||||
let url = "file://";
|
|
||||||
if (root.dialog.cwd[0] === "Home")
|
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
|
else
|
||||||
url += root.dialog.cwd.join("/");
|
return root.dialog.cwd.join("/");
|
||||||
return url;
|
|
||||||
}
|
}
|
||||||
onFolderChanged: view.currentIndex = -1
|
onPathChanged: view.currentIndex = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: StyledRect {
|
delegate: StyledRect {
|
||||||
id: item
|
id: item
|
||||||
|
|
||||||
required property int index
|
required property int index
|
||||||
required property string fileName
|
required property FileSystemEntry modelData
|
||||||
required property string filePath
|
|
||||||
required property url fileUrl
|
|
||||||
required property string fileSuffix
|
|
||||||
required property bool fileIsDir
|
|
||||||
|
|
||||||
readonly property real nonAnimHeight: icon.implicitHeight + name.anchors.topMargin + name.implicitHeight + Appearance.padding.normal * 2
|
readonly property real nonAnimHeight: icon.implicitHeight + name.anchors.topMargin + name.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
|
|
@ -130,10 +122,10 @@ Item {
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
onDoubleClicked: {
|
onDoubleClicked: {
|
||||||
if (item.fileIsDir)
|
if (item.modelData.isDir)
|
||||||
root.dialog.cwd.push(item.fileName);
|
root.dialog.cwd.push(item.modelData.name);
|
||||||
else if (root.dialog.selectionValid)
|
else if (root.dialog.selectionValid)
|
||||||
root.dialog.accepted(item.filePath);
|
root.dialog.accepted(item.modelData.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
|
|
@ -150,31 +142,18 @@ Item {
|
||||||
|
|
||||||
implicitSize: Sizes.itemWidth - Appearance.padding.normal * 2
|
implicitSize: Sizes.itemWidth - Appearance.padding.normal * 2
|
||||||
source: {
|
source: {
|
||||||
if (!item.fileIsDir)
|
if (item.modelData.isImage)
|
||||||
return Quickshell.iconPath("application-x-zerosize");
|
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))
|
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(`folder-${name.toLowerCase()}`);
|
||||||
|
|
||||||
return Quickshell.iconPath("inode-directory");
|
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 {
|
StyledText {
|
||||||
|
|
@ -187,7 +166,7 @@ Item {
|
||||||
anchors.margins: Appearance.padding.normal
|
anchors.margins: Appearance.padding.normal
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
text: item.fileName
|
text: item.modelData.name
|
||||||
elide: item.GridView.isCurrentItem ? Text.ElideNone : Text.ElideRight
|
elide: item.GridView.isCurrentItem ? Text.ElideNone : Text.ElideRight
|
||||||
wrapMode: item.GridView.isCurrentItem ? Text.WrapAtWordBoundaryOrAnywhere : Text.NoWrap
|
wrapMode: item.GridView.isCurrentItem ? Text.WrapAtWordBoundaryOrAnywhere : Text.NoWrap
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
#include <QMimeDatabase>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
|
|
||||||
|
|
@ -18,22 +19,27 @@ class FileSystemEntry : public QObject {
|
||||||
Q_PROPERTY(QString relativePath READ relativePath CONSTANT)
|
Q_PROPERTY(QString relativePath READ relativePath CONSTANT)
|
||||||
Q_PROPERTY(QString name READ name CONSTANT)
|
Q_PROPERTY(QString name READ name CONSTANT)
|
||||||
Q_PROPERTY(QString parentDir READ parentDir CONSTANT)
|
Q_PROPERTY(QString parentDir READ parentDir CONSTANT)
|
||||||
|
Q_PROPERTY(QString suffix READ suffix CONSTANT)
|
||||||
Q_PROPERTY(qint64 size READ size CONSTANT)
|
Q_PROPERTY(qint64 size READ size CONSTANT)
|
||||||
Q_PROPERTY(bool isDir READ isDir CONSTANT)
|
Q_PROPERTY(bool isDir READ isDir CONSTANT)
|
||||||
Q_PROPERTY(bool isImage READ isImage CONSTANT)
|
Q_PROPERTY(bool isImage READ isImage CONSTANT)
|
||||||
|
Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr)
|
explicit FileSystemEntry(const QString& path, const QString& relativePath, QObject* parent = nullptr)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_fileInfo(QFileInfo(path))
|
, m_fileInfo(QFileInfo(path))
|
||||||
, m_path(path)
|
, m_path(path)
|
||||||
, m_relativePath(relativePath) {}
|
, m_relativePath(relativePath)
|
||||||
|
, m_isImageInitialised(false)
|
||||||
|
, m_mimeTypeInitialised(false) {}
|
||||||
|
|
||||||
QString path() const { return m_path; };
|
QString path() const { return m_path; };
|
||||||
QString relativePath() const { return m_relativePath; };
|
QString relativePath() const { return m_relativePath; };
|
||||||
|
|
||||||
QString name() const { return m_fileInfo.fileName(); };
|
QString name() const { return m_fileInfo.fileName(); };
|
||||||
QString parentDir() const { return m_fileInfo.absolutePath(); };
|
QString parentDir() const { return m_fileInfo.absolutePath(); };
|
||||||
|
QString suffix() const { return m_fileInfo.completeSuffix(); };
|
||||||
qint64 size() const { return m_fileInfo.size(); };
|
qint64 size() const { return m_fileInfo.size(); };
|
||||||
bool isDir() const { return m_fileInfo.isDir(); };
|
bool isDir() const { return m_fileInfo.isDir(); };
|
||||||
|
|
||||||
|
|
@ -46,6 +52,15 @@ public:
|
||||||
return m_isImage;
|
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:
|
private:
|
||||||
const QFileInfo m_fileInfo;
|
const QFileInfo m_fileInfo;
|
||||||
|
|
||||||
|
|
@ -54,6 +69,9 @@ private:
|
||||||
|
|
||||||
bool m_isImage;
|
bool m_isImage;
|
||||||
bool m_isImageInitialised;
|
bool m_isImageInitialised;
|
||||||
|
|
||||||
|
QString m_mimeType;
|
||||||
|
bool m_mimeTypeInitialised;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileSystemModel : public QAbstractListModel {
|
class FileSystemModel : public QAbstractListModel {
|
||||||
|
|
@ -79,7 +97,7 @@ public:
|
||||||
|
|
||||||
explicit FileSystemModel(QObject* parent = nullptr)
|
explicit FileSystemModel(QObject* parent = nullptr)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
, m_recursive(true)
|
, m_recursive(false)
|
||||||
, m_watchChanges(true)
|
, m_watchChanges(true)
|
||||||
, m_showHidden(false)
|
, m_showHidden(false)
|
||||||
, m_filter(NoFilter) {
|
, m_filter(NoFilter) {
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ Searcher {
|
||||||
FileSystemModel {
|
FileSystemModel {
|
||||||
id: wallpapers
|
id: wallpapers
|
||||||
|
|
||||||
|
recursive: true
|
||||||
path: Paths.expandTilde(Paths.wallsdir)
|
path: Paths.expandTilde(Paths.wallsdir)
|
||||||
filter: FileSystemModel.Images
|
filter: FileSystemModel.Images
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue