git repos / SagoImageBrowser

blame: src/fsdirmodel.h

normal view · raw

14cf904f Poul Sander 2026-06-22 18:18 1
/*
14cf904f Poul Sander 2026-06-22 18:18 2
MIT License
14cf904f Poul Sander 2026-06-22 18:18 3
14cf904f Poul Sander 2026-06-22 18:18 4
Copyright (c) 2026 Poul Sander
14cf904f Poul Sander 2026-06-22 18:18 5
14cf904f Poul Sander 2026-06-22 18:18 6
Permission is hereby granted, free of charge, to any person obtaining a copy
14cf904f Poul Sander 2026-06-22 18:18 7
of this software and associated documentation files (the "Software"), to deal
14cf904f Poul Sander 2026-06-22 18:18 8
in the Software without restriction, including without limitation the rights
14cf904f Poul Sander 2026-06-22 18:18 9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14cf904f Poul Sander 2026-06-22 18:18 10
copies of the Software, and to permit persons to whom the Software is
14cf904f Poul Sander 2026-06-22 18:18 11
furnished to do so, subject to the following conditions:
14cf904f Poul Sander 2026-06-22 18:18 12
14cf904f Poul Sander 2026-06-22 18:18 13
The above copyright notice and this permission notice shall be included in all
14cf904f Poul Sander 2026-06-22 18:18 14
copies or substantial portions of the Software.
14cf904f Poul Sander 2026-06-22 18:18 15
14cf904f Poul Sander 2026-06-22 18:18 16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14cf904f Poul Sander 2026-06-22 18:18 17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14cf904f Poul Sander 2026-06-22 18:18 18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14cf904f Poul Sander 2026-06-22 18:18 19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14cf904f Poul Sander 2026-06-22 18:18 20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14cf904f Poul Sander 2026-06-22 18:18 21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
14cf904f Poul Sander 2026-06-22 18:18 22
SOFTWARE.
14cf904f Poul Sander 2026-06-22 18:18 23
14cf904f Poul Sander 2026-06-22 18:18 24
*/
14cf904f Poul Sander 2026-06-22 18:18 25
40efdfde Poul Sander 2026-05-19 21:24 26
#pragma once
40efdfde Poul Sander 2026-05-19 21:24 27
40efdfde Poul Sander 2026-05-19 21:24 28
#include <QAbstractItemModel>
40efdfde Poul Sander 2026-05-19 21:24 29
#include <QByteArray>
40efdfde Poul Sander 2026-05-19 21:24 30
#include <QIcon>
40efdfde Poul Sander 2026-05-19 21:24 31
#include <QList>
40efdfde Poul Sander 2026-05-19 21:24 32
40efdfde Poul Sander 2026-05-19 21:24 33
// A directory-tree model that uses std::filesystem for enumeration so that
40efdfde Poul Sander 2026-05-19 21:24 34
// directory entries with non-UTF-8 filenames (e.g. Latin-1 encoded names on
40efdfde Poul Sander 2026-05-19 21:24 35
// a UTF-8 locale) are listed correctly instead of being silently dropped or
40efdfde Poul Sander 2026-05-19 21:24 36
// mangled by QDir / QFileSystemModel.
40efdfde Poul Sander 2026-05-19 21:24 37
//
40efdfde Poul Sander 2026-05-19 21:24 38
// The model is lazily populated: child directories are enumerated only when
40efdfde Poul Sander 2026-05-19 21:24 39
// the view first expands a node (via canFetchMore / fetchMore).
40efdfde Poul Sander 2026-05-19 21:24 40
class FsDirModel : public QAbstractItemModel
40efdfde Poul Sander 2026-05-19 21:24 41
{
40efdfde Poul Sander 2026-05-19 21:24 42
    Q_OBJECT
40efdfde Poul Sander 2026-05-19 21:24 43
40efdfde Poul Sander 2026-05-19 21:24 44
public:
40efdfde Poul Sander 2026-05-19 21:24 45
    explicit FsDirModel(QObject *parent = nullptr);
40efdfde Poul Sander 2026-05-19 21:24 46
    ~FsDirModel() override;
40efdfde Poul Sander 2026-05-19 21:24 47
40efdfde Poul Sander 2026-05-19 21:24 48
    // Set the directory shown as the tree root.  Call rootIndex() afterwards
40efdfde Poul Sander 2026-05-19 21:24 49
    // and pass the result to QTreeView::setRootIndex() so the root node itself
40efdfde Poul Sander 2026-05-19 21:24 50
    // is hidden and only its children are displayed as top-level items.
40efdfde Poul Sander 2026-05-19 21:24 51
    void setRootPath(const QByteArray &nativePath);
40efdfde Poul Sander 2026-05-19 21:24 52
    void setRootPath(const QString &path);   // convenience: converts via QFile::encodeName
40efdfde Poul Sander 2026-05-19 21:24 53
40efdfde Poul Sander 2026-05-19 21:24 54
    // Model index of the root-path node (the one whose *children* are shown
40efdfde Poul Sander 2026-05-19 21:24 55
    // as top-level items when passed to QTreeView::setRootIndex).
40efdfde Poul Sander 2026-05-19 21:24 56
    QModelIndex rootIndex() const;
40efdfde Poul Sander 2026-05-19 21:24 57
40efdfde Poul Sander 2026-05-19 21:24 58
    // Raw native OS byte path for the node at index.
40efdfde Poul Sander 2026-05-19 21:24 59
    QByteArray filePath(const QModelIndex &index) const;
40efdfde Poul Sander 2026-05-19 21:24 60
40efdfde Poul Sander 2026-05-19 21:24 61
    // Walk the tree to find (and lazily populate) the node for nativePath.
40efdfde Poul Sander 2026-05-19 21:24 62
    // Returns an invalid index if the path is not under the current root.
40efdfde Poul Sander 2026-05-19 21:24 63
    QModelIndex indexForPath(const QByteArray &nativePath);
40efdfde Poul Sander 2026-05-19 21:24 64
40efdfde Poul Sander 2026-05-19 21:24 65
    // QAbstractItemModel interface
40efdfde Poul Sander 2026-05-19 21:24 66
    QModelIndex index(int row, int column,
40efdfde Poul Sander 2026-05-19 21:24 67
                      const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 68
    QModelIndex parent(const QModelIndex &index) const override;
40efdfde Poul Sander 2026-05-19 21:24 69
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 70
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 71
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
40efdfde Poul Sander 2026-05-19 21:24 72
    bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
40efdfde Poul Sander 2026-05-19 21:24 73
    bool canFetchMore(const QModelIndex &parent) const override;
40efdfde Poul Sander 2026-05-19 21:24 74
    void fetchMore(const QModelIndex &parent) override;
40efdfde Poul Sander 2026-05-19 21:24 75
40efdfde Poul Sander 2026-05-19 21:24 76
private:
40efdfde Poul Sander 2026-05-19 21:24 77
    struct Node {
40efdfde Poul Sander 2026-05-19 21:24 78
        QByteArray  nativePath;
40efdfde Poul Sander 2026-05-19 21:24 79
        QString     displayName;
40efdfde Poul Sander 2026-05-19 21:24 80
        Node       *parent   = nullptr;
40efdfde Poul Sander 2026-05-19 21:24 81
        QList<Node *> children;
40efdfde Poul Sander 2026-05-19 21:24 82
        bool        populated = false;
40efdfde Poul Sander 2026-05-19 21:24 83
    };
40efdfde Poul Sander 2026-05-19 21:24 84
40efdfde Poul Sander 2026-05-19 21:24 85
    // Synchronously populate node->children from the filesystem.
40efdfde Poul Sander 2026-05-19 21:24 86
    // Only call this inside fetchMore (with proper begin/endInsertRows around it).
40efdfde Poul Sander 2026-05-19 21:24 87
    static QList<Node *> listSubdirs(Node *parent);
40efdfde Poul Sander 2026-05-19 21:24 88
40efdfde Poul Sander 2026-05-19 21:24 89
    Node *nodeForIndex(const QModelIndex &index) const;
40efdfde Poul Sander 2026-05-19 21:24 90
    QModelIndex indexForNode(Node *node) const;
40efdfde Poul Sander 2026-05-19 21:24 91
    static void destroyChildren(Node *node);
40efdfde Poul Sander 2026-05-19 21:24 92
40efdfde Poul Sander 2026-05-19 21:24 93
    Node   m_virtualRoot;   // hidden root; always has exactly 0 or 1 child
40efdfde Poul Sander 2026-05-19 21:24 94
    QIcon  m_folderIcon;
40efdfde Poul Sander 2026-05-19 21:24 95
};
1970-01-01 00:00 96