git repos / SagoImageBrowser

blame: src/fsdirmodel.h

normal view · raw

40efdfde Poul Sander 2026-05-19 21:24 1
#pragma once
40efdfde Poul Sander 2026-05-19 21:24 2
40efdfde Poul Sander 2026-05-19 21:24 3
#include <QAbstractItemModel>
40efdfde Poul Sander 2026-05-19 21:24 4
#include <QByteArray>
40efdfde Poul Sander 2026-05-19 21:24 5
#include <QIcon>
40efdfde Poul Sander 2026-05-19 21:24 6
#include <QList>
40efdfde Poul Sander 2026-05-19 21:24 7
40efdfde Poul Sander 2026-05-19 21:24 8
// A directory-tree model that uses std::filesystem for enumeration so that
40efdfde Poul Sander 2026-05-19 21:24 9
// directory entries with non-UTF-8 filenames (e.g. Latin-1 encoded names on
40efdfde Poul Sander 2026-05-19 21:24 10
// a UTF-8 locale) are listed correctly instead of being silently dropped or
40efdfde Poul Sander 2026-05-19 21:24 11
// mangled by QDir / QFileSystemModel.
40efdfde Poul Sander 2026-05-19 21:24 12
//
40efdfde Poul Sander 2026-05-19 21:24 13
// The model is lazily populated: child directories are enumerated only when
40efdfde Poul Sander 2026-05-19 21:24 14
// the view first expands a node (via canFetchMore / fetchMore).
40efdfde Poul Sander 2026-05-19 21:24 15
class FsDirModel : public QAbstractItemModel
40efdfde Poul Sander 2026-05-19 21:24 16
{
40efdfde Poul Sander 2026-05-19 21:24 17
    Q_OBJECT
40efdfde Poul Sander 2026-05-19 21:24 18
40efdfde Poul Sander 2026-05-19 21:24 19
public:
40efdfde Poul Sander 2026-05-19 21:24 20
    explicit FsDirModel(QObject *parent = nullptr);
40efdfde Poul Sander 2026-05-19 21:24 21
    ~FsDirModel() override;
40efdfde Poul Sander 2026-05-19 21:24 22
40efdfde Poul Sander 2026-05-19 21:24 23
    // Set the directory shown as the tree root.  Call rootIndex() afterwards
40efdfde Poul Sander 2026-05-19 21:24 24
    // and pass the result to QTreeView::setRootIndex() so the root node itself
40efdfde Poul Sander 2026-05-19 21:24 25
    // is hidden and only its children are displayed as top-level items.
40efdfde Poul Sander 2026-05-19 21:24 26
    void setRootPath(const QByteArray &nativePath);
40efdfde Poul Sander 2026-05-19 21:24 27
    void setRootPath(const QString &path);   // convenience: converts via QFile::encodeName
40efdfde Poul Sander 2026-05-19 21:24 28
40efdfde Poul Sander 2026-05-19 21:24 29
    // Model index of the root-path node (the one whose *children* are shown
40efdfde Poul Sander 2026-05-19 21:24 30
    // as top-level items when passed to QTreeView::setRootIndex).
40efdfde Poul Sander 2026-05-19 21:24 31
    QModelIndex rootIndex() const;
40efdfde Poul Sander 2026-05-19 21:24 32
40efdfde Poul Sander 2026-05-19 21:24 33
    // Raw native OS byte path for the node at index.
40efdfde Poul Sander 2026-05-19 21:24 34
    QByteArray filePath(const QModelIndex &index) const;
40efdfde Poul Sander 2026-05-19 21:24 35
40efdfde Poul Sander 2026-05-19 21:24 36
    // Walk the tree to find (and lazily populate) the node for nativePath.
40efdfde Poul Sander 2026-05-19 21:24 37
    // Returns an invalid index if the path is not under the current root.
40efdfde Poul Sander 2026-05-19 21:24 38
    QModelIndex indexForPath(const QByteArray &nativePath);
40efdfde Poul Sander 2026-05-19 21:24 39
40efdfde Poul Sander 2026-05-19 21:24 40
    // QAbstractItemModel interface
40efdfde Poul Sander 2026-05-19 21:24 41
    QModelIndex index(int row, int column,
40efdfde Poul Sander 2026-05-19 21:24 42
                      const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 43
    QModelIndex parent(const QModelIndex &index) const override;
40efdfde Poul Sander 2026-05-19 21:24 44
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 45
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 46
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
40efdfde Poul Sander 2026-05-19 21:24 47
    bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 48
    bool canFetchMore(const QModelIndex &parent) const override;
40efdfde Poul Sander 2026-05-19 21:24 49
    void fetchMore(const QModelIndex &parent) override;
40efdfde Poul Sander 2026-05-19 21:24 50
40efdfde Poul Sander 2026-05-19 21:24 51
private:
40efdfde Poul Sander 2026-05-19 21:24 52
    struct Node {
40efdfde Poul Sander 2026-05-19 21:24 53
        QByteArray  nativePath;
40efdfde Poul Sander 2026-05-19 21:24 54
        QString     displayName;
40efdfde Poul Sander 2026-05-19 21:24 55
        Node       *parent   = nullptr;
40efdfde Poul Sander 2026-05-19 21:24 56
        QList<Node *> children;
40efdfde Poul Sander 2026-05-19 21:24 57
        bool        populated = false;
40efdfde Poul Sander 2026-05-19 21:24 58
    };
40efdfde Poul Sander 2026-05-19 21:24 59
40efdfde Poul Sander 2026-05-19 21:24 60
    // Synchronously populate node->children from the filesystem.
40efdfde Poul Sander 2026-05-19 21:24 61
    // Only call this inside fetchMore (with proper begin/endInsertRows around it).
40efdfde Poul Sander 2026-05-19 21:24 62
    static QList<Node *> listSubdirs(Node *parent);
40efdfde Poul Sander 2026-05-19 21:24 63
40efdfde Poul Sander 2026-05-19 21:24 64
    Node *nodeForIndex(const QModelIndex &index) const;
40efdfde Poul Sander 2026-05-19 21:24 65
    QModelIndex indexForNode(Node *node) const;
40efdfde Poul Sander 2026-05-19 21:24 66
    static void destroyChildren(Node *node);
40efdfde Poul Sander 2026-05-19 21:24 67
40efdfde Poul Sander 2026-05-19 21:24 68
    Node   m_virtualRoot;   // hidden root; always has exactly 0 or 1 child
40efdfde Poul Sander 2026-05-19 21:24 69
    QIcon  m_folderIcon;
40efdfde Poul Sander 2026-05-19 21:24 70
};
1970-01-01 00:00 71