#pragma once #include #include #include #include #include #include #include #include namespace caelestia { 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(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); [[nodiscard]] QString path() const; [[nodiscard]] QString relativePath() const; [[nodiscard]] QString name() const; [[nodiscard]] QString parentDir() const; [[nodiscard]] QString suffix() const; [[nodiscard]] qint64 size() const; [[nodiscard]] bool isDir() const; [[nodiscard]] bool isImage() const; [[nodiscard]] QString mimeType() const; private: const QFileInfo m_fileInfo; const QString m_path; const QString m_relativePath; mutable bool m_isImage; mutable bool m_isImageInitialised; mutable QString m_mimeType; mutable bool m_mimeTypeInitialised; }; 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(bool watchChanges READ watchChanges WRITE setWatchChanges NOTIFY watchChangesChanged) Q_PROPERTY(bool showHidden READ showHidden WRITE setShowHidden NOTIFY showHiddenChanged) Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY filterChanged) Q_PROPERTY(QList entries READ entries NOTIFY entriesChanged) public: enum Filter { NoFilter, Images, Files, Dirs }; Q_ENUM(Filter) explicit FileSystemModel(QObject* parent = nullptr); int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QHash roleNames() const override; [[nodiscard]] QString path() const; void setPath(const QString& path); [[nodiscard]] bool recursive() const; void setRecursive(bool recursive); [[nodiscard]] bool watchChanges() const; void setWatchChanges(bool watchChanges); [[nodiscard]] bool showHidden() const; void setShowHidden(bool showHidden); [[nodiscard]] Filter filter() const; void setFilter(Filter filter); [[nodiscard]] QList entries() const; signals: void pathChanged(); void recursiveChanged(); void watchChangesChanged(); void showHiddenChanged(); void filterChanged(); void entriesChanged(); void added(const FileSystemEntry* entry); void removed(const QString& path); private: QDir m_dir; QFileSystemWatcher m_watcher; QList m_entries; QHash, QSet>>> m_futures; QString m_path; bool m_recursive; bool m_watchChanges; bool m_showHidden; Filter m_filter; void watchDirIfRecursive(const QString& path); void update(); void updateWatcher(); void updateEntries(); void updateEntriesForDir(const QString& dir); void applyChanges(const QSet& removedPaths, const QSet& addedPaths); [[nodiscard]] static bool compareEntries(const FileSystemEntry* a, const FileSystemEntry* b); }; } // namespace caelestia