summaryrefslogtreecommitdiff
path: root/plugin/src/Caelestia/filesystemmodel.hpp
blob: 8584e8769cfcdf203c21d441cd166bb8d0642417 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#pragma once

#include <QObject>
#include <qqmlintegration.h>
#include <QAbstractListModel>
#include <QFileSystemWatcher>
#include <QFileInfo>
#include <QDir>

class FileSystemEntry : public QObject {
    Q_OBJECT
    QML_ELEMENT;
    QML_UNCREATABLE("FileSystemEntry instances can only be retrieved from a FileSystemModel");

    Q_PROPERTY(QString path READ path CONSTANT);
    Q_PROPERTY(QString relativePath READ relativePath CONSTANT);
    Q_PROPERTY(QString name READ name CONSTANT);
    Q_PROPERTY(QString parentDir READ parentDir CONSTANT);
    Q_PROPERTY(qint64 size READ size 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) {}

    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(); };
    qint64 size() const { return m_fileInfo.size(); };

private:
    const QFileInfo m_fileInfo;

    const QString m_path;
    const QString m_relativePath;
};

class FileSystemModel : public QAbstractListModel {
    Q_OBJECT;
    QML_ELEMENT;

    Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged);
    Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged);
    Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged);

    Q_PROPERTY(QList<FileSystemEntry*> files READ files NOTIFY filesChanged);

public:
    enum Roles {
        FilePathRole = Qt::UserRole + 1,
        RelativeFilePathRole,
        FileNameRole,
        ParentDirRole,
        FileSizeRole
    };

    enum Filter {
        NoFilter,
        ImagesOnly
    };
    Q_ENUM(Filter)

    explicit FileSystemModel(QObject* parent = nullptr)
        : QAbstractListModel(parent), m_recursive(true), m_filter(NoFilter) {
            connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &FileSystemModel::watchDirIfRecursive);
            connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &FileSystemModel::updateFiles);
        }

    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

    QString path() const;
    void setPath(const QString& path);

    bool recursive() const;
    void setRecursive(bool recursive);

    Filter filter() const;
    void setFilter(Filter filter);

    QList<FileSystemEntry*> files() const;

signals:
    void pathChanged();
    void recursiveChanged();
    void filterChanged();
    void filesChanged();

private:
    QDir m_dir;
    QFileSystemWatcher m_watcher;
    QList<FileSystemEntry*> m_files;

    QString m_path;
    bool m_recursive;
    Filter m_filter;

    void watchDirIfRecursive(const QString& path);
    void update();
    void updateWatcher();
    void updateFiles();
};