| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
1 |
#include "fsdirmodel.h" |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
2 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
3 |
#include <QFile> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
4 |
#include <QFileIconProvider> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
5 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
6 |
#include <algorithm> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
7 |
#include <filesystem> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
8 |
#include <vector> |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
9 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
10 |
namespace fs = std::filesystem; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
11 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
12 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
13 |
// Static helpers |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
14 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
15 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
16 |
QList<FsDirModel::Node *> FsDirModel::listSubdirs(Node *parentNode) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
17 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
18 |
QList<Node *> result; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
19 |
try { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
20 |
std::vector<std::pair<std::string, std::string>> entries; // {nativePath, filename} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
21 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
22 |
for (const fs::directory_entry &entry : |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
23 |
fs::directory_iterator(parentNode->nativePath.toStdString(), |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
24 |
fs::directory_options::skip_permission_denied)) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
25 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
26 |
std::error_code ec; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
27 |
const std::string fname = entry.path().filename().native(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
28 |
if (fname.empty() || fname[0] == '.') |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
29 |
continue; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
30 |
if (!entry.is_directory(ec)) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
31 |
continue; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
32 |
entries.push_back({entry.path().native(), fname}); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
33 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
34 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
35 |
std::sort(entries.begin(), entries.end(), |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
36 |
[](const auto &a, const auto &b) { return a.second < b.second; }); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
37 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
38 |
result.reserve(static_cast<qsizetype>(entries.size())); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
39 |
for (const auto &[npath, fname] : entries) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
40 |
auto *child = new Node; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
41 |
child->nativePath = QByteArray::fromStdString(npath); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
42 |
child->displayName = QString::fromLocal8Bit(fname.c_str(), |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
43 |
static_cast<qsizetype>(fname.size())); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
44 |
child->parent = parentNode; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
45 |
result.append(child); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
46 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
47 |
} catch (const fs::filesystem_error &) {} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
48 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
49 |
return result; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
50 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
51 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
52 |
void FsDirModel::destroyChildren(Node *node) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
53 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
54 |
for (Node *child : node->children) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
55 |
destroyChildren(child); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
56 |
delete child; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
57 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
58 |
node->children.clear(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
59 |
node->populated = false; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
60 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
61 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
62 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
63 |
// Construction / destruction |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
64 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
65 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
66 |
FsDirModel::FsDirModel(QObject *parent) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
67 |
: QAbstractItemModel(parent) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
68 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
69 |
m_virtualRoot.populated = true; // virtual root is always "populated" |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
70 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
71 |
QFileIconProvider iconProvider; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
72 |
m_folderIcon = iconProvider.icon(QFileIconProvider::Folder); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
73 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
74 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
75 |
FsDirModel::~FsDirModel() |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
76 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
77 |
destroyChildren(&m_virtualRoot); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
78 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
79 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
80 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
81 |
// Public API |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
82 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
83 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
84 |
void FsDirModel::setRootPath(const QString &path) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
85 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
86 |
setRootPath(QFile::encodeName(path)); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
87 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
88 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
89 |
void FsDirModel::setRootPath(const QByteArray &nativePath) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
90 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
91 |
beginResetModel(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
92 |
destroyChildren(&m_virtualRoot); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
93 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
94 |
if (!nativePath.isEmpty()) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
95 |
auto *node = new Node; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
96 |
node->nativePath = nativePath; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
97 |
// Display name = last path component (empty for "/", use "/" in that case) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
98 |
std::string fname = fs::path(nativePath.toStdString()).filename().native(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
99 |
node->displayName = fname.empty() |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
100 |
? QFile::decodeName(nativePath) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
101 |
: QString::fromLocal8Bit(fname.c_str(), static_cast<qsizetype>(fname.size())); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
102 |
node->parent = &m_virtualRoot; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
103 |
m_virtualRoot.children.append(node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
104 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
105 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
106 |
endResetModel(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
107 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
108 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
109 |
QModelIndex FsDirModel::rootIndex() const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
110 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
111 |
if (m_virtualRoot.children.isEmpty()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
112 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
113 |
return createIndex(0, 0, m_virtualRoot.children.first()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
114 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
115 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
116 |
QByteArray FsDirModel::filePath(const QModelIndex &index) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
117 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
118 |
if (!index.isValid()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
119 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
120 |
return nodeForIndex(index)->nativePath; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
121 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
122 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
123 |
QModelIndex FsDirModel::indexForPath(const QByteArray &nativePath) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
124 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
125 |
if (nativePath.isEmpty() || m_virtualRoot.children.isEmpty()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
126 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
127 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
128 |
const fs::path target(nativePath.toStdString()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
129 |
const fs::path root(m_virtualRoot.children.first()->nativePath.toStdString()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
130 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
131 |
// Collect the ancestry chain from root down to target |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
132 |
std::vector<fs::path> chain; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
133 |
fs::path cur = target; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
134 |
while (cur != root) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
135 |
chain.push_back(cur); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
136 |
fs::path up = cur.parent_path(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
137 |
if (up == cur) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
138 |
return {}; // reached filesystem root without finding model root |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
139 |
cur = up; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
140 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
141 |
// chain is [target, …, root_child]; reverse so we walk root→target |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
142 |
std::reverse(chain.begin(), chain.end()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
143 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
144 |
// Start at the root path node |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
145 |
Node *node = m_virtualRoot.children.first(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
146 |
QModelIndex idx = createIndex(0, 0, node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
147 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
148 |
for (const fs::path &step : chain) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
149 |
// Ensure this node's children are loaded |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
150 |
if (!node->populated) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
151 |
QList<Node *> children = listSubdirs(node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
152 |
if (!children.isEmpty()) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
153 |
beginInsertRows(idx, 0, children.size() - 1); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
154 |
node->children = children; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
155 |
node->populated = true; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
156 |
endInsertRows(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
157 |
} else { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
158 |
node->populated = true; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
159 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
160 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
161 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
162 |
// Find the child whose nativePath matches step |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
163 |
const std::string stepStr = step.native(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
164 |
bool found = false; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
165 |
for (int i = 0; i < node->children.size(); ++i) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
166 |
if (node->children[i]->nativePath.toStdString() == stepStr) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
167 |
node = node->children[i]; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
168 |
idx = createIndex(i, 0, node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
169 |
found = true; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
170 |
break; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
171 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
172 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
173 |
if (!found) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
174 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
175 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
176 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
177 |
return idx; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
178 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
179 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
180 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
181 |
// QAbstractItemModel interface |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
182 |
// --------------------------------------------------------------------------- |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
183 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
184 |
FsDirModel::Node *FsDirModel::nodeForIndex(const QModelIndex &index) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
185 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
186 |
if (!index.isValid()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
187 |
return const_cast<Node *>(&m_virtualRoot); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
188 |
return static_cast<Node *>(index.internalPointer()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
189 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
190 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
191 |
QModelIndex FsDirModel::indexForNode(Node *node) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
192 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
193 |
if (!node || node == &m_virtualRoot) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
194 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
195 |
Node *parentNode = node->parent; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
196 |
int row = parentNode->children.indexOf(node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
197 |
if (row < 0) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
198 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
199 |
return createIndex(row, 0, node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
200 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
201 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
202 |
QModelIndex FsDirModel::index(int row, int column, const QModelIndex &parent) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
203 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
204 |
if (column != 0) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
205 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
206 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
207 |
Node *parentNode = nodeForIndex(parent); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
208 |
if (row < 0 || row >= parentNode->children.size()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
209 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
210 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
211 |
return createIndex(row, 0, parentNode->children[row]); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
212 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
213 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
214 |
QModelIndex FsDirModel::parent(const QModelIndex &index) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
215 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
216 |
if (!index.isValid()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
217 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
218 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
219 |
Node *node = static_cast<Node *>(index.internalPointer()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
220 |
Node *parentNode = node->parent; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
221 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
222 |
if (!parentNode || parentNode == &m_virtualRoot) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
223 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
224 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
225 |
return indexForNode(parentNode); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
226 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
227 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
228 |
int FsDirModel::rowCount(const QModelIndex &parent) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
229 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
230 |
return nodeForIndex(parent)->children.size(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
231 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
232 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
233 |
int FsDirModel::columnCount(const QModelIndex &) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
234 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
235 |
return 1; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
236 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
237 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
238 |
QVariant FsDirModel::data(const QModelIndex &index, int role) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
239 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
240 |
if (!index.isValid()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
241 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
242 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
243 |
const Node *node = static_cast<const Node *>(index.internalPointer()); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
244 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
245 |
switch (role) { |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
246 |
case Qt::DisplayRole: |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
247 |
return node->displayName; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
248 |
case Qt::DecorationRole: |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
249 |
return m_folderIcon; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
250 |
default: |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
251 |
return {}; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
252 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
253 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
254 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
255 |
bool FsDirModel::hasChildren(const QModelIndex &parent) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
256 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
257 |
const Node *node = nodeForIndex(parent); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
258 |
if (!node->populated) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
259 |
return true; // optimistic: show expand arrow until we actually look |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
260 |
return !node->children.isEmpty(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
261 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
262 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
263 |
bool FsDirModel::canFetchMore(const QModelIndex &parent) const |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
264 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
265 |
return !nodeForIndex(parent)->populated; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
266 |
} |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
267 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
268 |
void FsDirModel::fetchMore(const QModelIndex &parent) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
269 |
{ |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
270 |
Node *node = nodeForIndex(parent); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
271 |
if (node->populated) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
272 |
return; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
273 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
274 |
QList<Node *> children = listSubdirs(node); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
275 |
node->populated = true; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
276 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
277 |
if (children.isEmpty()) |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
278 |
return; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
279 |
|
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
280 |
beginInsertRows(parent, 0, children.size() - 1); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
281 |
node->children = children; |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
282 |
endInsertRows(); |
| 40efdfde |
Poul Sander |
2026-05-19 21:24 |
283 |
} |
|
|
1970-01-01 00:00 |
284 |
|