1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | //![code] |
5 | #include "qquickfolderlistmodel_p.h" |
6 | #include "fileinfothread_p.h" |
7 | #include "fileproperty_p.h" |
8 | #include <QtCore/qloggingcategory.h> |
9 | #include <qqmlcontext.h> |
10 | #include <qqmlfile.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | Q_LOGGING_CATEGORY(lcFolderListModel, "qt.labs.folderlistmodel") |
15 | |
16 | class QQuickFolderListModelPrivate |
17 | { |
18 | Q_DECLARE_PUBLIC(QQuickFolderListModel) |
19 | |
20 | public: |
21 | QQuickFolderListModelPrivate(QQuickFolderListModel *q) : q_ptr(q) { } |
22 | |
23 | QQuickFolderListModel *q_ptr; |
24 | QUrl currentDir; |
25 | QUrl rootDir; |
26 | FileInfoThread fileInfoThread; |
27 | QList<FileProperty> data; |
28 | QHash<int, QByteArray> roleNames; |
29 | QQuickFolderListModel::SortField sortField = QQuickFolderListModel::Name; |
30 | QStringList nameFilters = { QLatin1String("*") }; |
31 | QQuickFolderListModel::Status status = QQuickFolderListModel::Null; |
32 | bool sortReversed = false; |
33 | bool showFiles = true; |
34 | bool showDirs = true; |
35 | bool showDirsFirst = false; |
36 | bool showDotAndDotDot = false; |
37 | bool showOnlyReadable = false; |
38 | bool showHidden = false; |
39 | bool caseSensitive = true; |
40 | bool sortCaseSensitive = true; |
41 | bool resettingModel = false; |
42 | |
43 | ~QQuickFolderListModelPrivate() {} |
44 | void init(); |
45 | void updateSorting(); |
46 | |
47 | void finishModelReset(); |
48 | |
49 | // private slots |
50 | void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list); |
51 | void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex); |
52 | void _q_sortFinished(const QList<FileProperty> &list); |
53 | void _q_statusChanged(QQuickFolderListModel::Status s); |
54 | |
55 | static QString resolvePath(const QUrl &path); |
56 | }; |
57 | |
58 | |
59 | void QQuickFolderListModelPrivate::init() |
60 | { |
61 | Q_Q(QQuickFolderListModel); |
62 | qRegisterMetaType<QList<FileProperty> >(typeName: "QList<FileProperty>"); |
63 | qRegisterMetaType<QQuickFolderListModel::Status>(typeName: "QQuickFolderListModel::Status"); |
64 | q->connect(sender: &fileInfoThread, SIGNAL(directoryChanged(QString,QList<FileProperty>)), |
65 | receiver: q, SLOT(_q_directoryChanged(QString,QList<FileProperty>))); |
66 | q->connect(sender: &fileInfoThread, SIGNAL(directoryUpdated(QString,QList<FileProperty>,int,int)), |
67 | receiver: q, SLOT(_q_directoryUpdated(QString,QList<FileProperty>,int,int))); |
68 | q->connect(sender: &fileInfoThread, SIGNAL(sortFinished(QList<FileProperty>)), |
69 | receiver: q, SLOT(_q_sortFinished(QList<FileProperty>))); |
70 | q->connect(sender: &fileInfoThread, SIGNAL(statusChanged(QQuickFolderListModel::Status)), |
71 | receiver: q, SLOT(_q_statusChanged(QQuickFolderListModel::Status))); |
72 | q->connect(sender: q, SIGNAL(rowCountChanged()), receiver: q, SIGNAL(countChanged())); |
73 | } |
74 | |
75 | |
76 | void QQuickFolderListModelPrivate::updateSorting() |
77 | { |
78 | Q_Q(QQuickFolderListModel); |
79 | |
80 | QDir::SortFlags flags; |
81 | |
82 | switch (sortField) { |
83 | case QQuickFolderListModel::Unsorted: |
84 | flags |= QDir::Unsorted; |
85 | break; |
86 | case QQuickFolderListModel::Name: |
87 | flags |= QDir::Name; |
88 | break; |
89 | case QQuickFolderListModel::Time: |
90 | flags |= QDir::Time; |
91 | break; |
92 | case QQuickFolderListModel::Size: |
93 | flags |= QDir::Size; |
94 | break; |
95 | case QQuickFolderListModel::Type: |
96 | flags |= QDir::Type; |
97 | break; |
98 | } |
99 | |
100 | emit q->layoutAboutToBeChanged(); |
101 | |
102 | if (sortReversed) |
103 | flags |= QDir::Reversed; |
104 | if (!sortCaseSensitive) |
105 | flags |= QDir::IgnoreCase; |
106 | |
107 | fileInfoThread.setSortFlags(flags); |
108 | } |
109 | |
110 | void QQuickFolderListModelPrivate::finishModelReset() |
111 | { |
112 | Q_Q(QQuickFolderListModel); |
113 | const bool wasDataEmpty = data.isEmpty(); |
114 | data.clear(); |
115 | qCDebug(lcFolderListModel) << "about to emit endResetModel"; |
116 | q->endResetModel(); |
117 | if (!wasDataEmpty) |
118 | emit q->rowCountChanged(); |
119 | if (status != QQuickFolderListModel::Null) { |
120 | status = QQuickFolderListModel::Null; |
121 | emit q->statusChanged(); |
122 | } |
123 | resettingModel = false; |
124 | } |
125 | |
126 | void QQuickFolderListModelPrivate::_q_directoryChanged(const QString &directory, const QList<FileProperty> &list) |
127 | { |
128 | qCDebug(lcFolderListModel) << "_q_directoryChanged called with directory"<< directory; |
129 | Q_Q(QQuickFolderListModel); |
130 | Q_UNUSED(directory); |
131 | |
132 | data = list; |
133 | q->endResetModel(); |
134 | qCDebug(lcFolderListModel) << "- endResetModel called"; |
135 | emit q->rowCountChanged(); |
136 | emit q->folderChanged(); |
137 | resettingModel = false; |
138 | } |
139 | |
140 | |
141 | void QQuickFolderListModelPrivate::_q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex) |
142 | { |
143 | Q_Q(QQuickFolderListModel); |
144 | Q_UNUSED(directory); |
145 | |
146 | QModelIndex parent; |
147 | if (data.size() == list.size()) { |
148 | QModelIndex modelIndexFrom = q->createIndex(arow: fromIndex, acolumn: 0); |
149 | QModelIndex modelIndexTo = q->createIndex(arow: toIndex, acolumn: 0); |
150 | data = list; |
151 | emit q->dataChanged(topLeft: modelIndexFrom, bottomRight: modelIndexTo); |
152 | } else { |
153 | // File(s) inserted or removed. Since I do not know how many |
154 | // or where, I need to update the whole list from the first item. |
155 | // This is a little pessimistic, but optimizing it would require |
156 | // more information in the signal from FileInfoThread. |
157 | if (data.size() > 0) { |
158 | q->beginRemoveRows(parent, first: 0, last: data.size() - 1); |
159 | q->endRemoveRows(); |
160 | } |
161 | data = list; |
162 | if (list.size() > 0) { |
163 | if (toIndex > list.size() - 1) |
164 | toIndex = list.size() - 1; |
165 | q->beginInsertRows(parent, first: 0, last: data.size() - 1); |
166 | q->endInsertRows(); |
167 | } |
168 | emit q->rowCountChanged(); |
169 | } |
170 | } |
171 | |
172 | void QQuickFolderListModelPrivate::_q_sortFinished(const QList<FileProperty> &list) |
173 | { |
174 | Q_Q(QQuickFolderListModel); |
175 | qCDebug(lcFolderListModel) << "_q_sortFinished called with"<< list.size() << "files"; |
176 | |
177 | QModelIndex parent; |
178 | if (data.size() > 0) { |
179 | qCDebug(lcFolderListModel) << "- removing all existing rows..."; |
180 | q->beginRemoveRows(parent, first: 0, last: data.size()-1); |
181 | data.clear(); |
182 | q->endRemoveRows(); |
183 | qCDebug(lcFolderListModel) << "- ...removed all existing rows"; |
184 | } |
185 | |
186 | qCDebug(lcFolderListModel) << "- inserting sorted rows..."; |
187 | q->beginInsertRows(parent, first: 0, last: list.size()-1); |
188 | data = list; |
189 | q->endInsertRows(); |
190 | qCDebug(lcFolderListModel) << "- ... inserted sorted rows"; |
191 | } |
192 | |
193 | void QQuickFolderListModelPrivate::_q_statusChanged(QQuickFolderListModel::Status s) |
194 | { |
195 | Q_Q(QQuickFolderListModel); |
196 | |
197 | if (status != s) { |
198 | status = s; |
199 | emit q->statusChanged(); |
200 | } |
201 | } |
202 | |
203 | QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path) |
204 | { |
205 | QString localPath = QQmlFile::urlToLocalFileOrQrc(path); |
206 | QUrl localUrl = QUrl(localPath); |
207 | QString fullPath = localUrl.path(); |
208 | if (localUrl.scheme().size()) |
209 | fullPath = localUrl.scheme() + QLatin1Char(':') + fullPath; |
210 | return QDir::cleanPath(path: fullPath); |
211 | } |
212 | |
213 | /*! |
214 | \qmlmodule Qt.labs.folderlistmodel 2.\QtMinorVersion |
215 | \title Qt Labs FolderListModel QML Types |
216 | \ingroup qmlmodules |
217 | \brief The FolderListModel provides a model of the contents of a file system folder. |
218 | |
219 | To use this module, import the module with the following line: |
220 | |
221 | \qml |
222 | import Qt.labs.folderlistmodel |
223 | \endqml |
224 | */ |
225 | |
226 | /*! |
227 | \qmltype FolderListModel |
228 | \inqmlmodule Qt.labs.folderlistmodel |
229 | //! \nativetype QQuickFolderListModel |
230 | \ingroup qtquick-models |
231 | \brief The FolderListModel provides a model of the contents of a file system folder. |
232 | |
233 | FolderListModel provides access to information about the contents of a folder |
234 | in the local file system, exposing a list of files to views and other data components. |
235 | |
236 | \note This type is made available by importing the \c Qt.labs.folderlistmodel module. |
237 | \e{Elements in the Qt.labs module are not guaranteed to remain compatible |
238 | in future versions.} |
239 | |
240 | \note Some features in FolderListModel depend on \l QFileSystemWatcher. If \l QFileSystemWatcher |
241 | is disabled, the folder set using \c setFolder is not watched for changes, which results in |
242 | signals typically emitted on directory changes (like directoryUpdated or directoryChanged) not |
243 | being emitted without manually calling \c setFolder again. For more information, see |
244 | \l{Qt Configure Options}. |
245 | |
246 | \qml |
247 | import Qt.labs.folderlistmodel |
248 | \endqml |
249 | |
250 | The \l folder property specifies the folder to access. Information about the |
251 | files and directories in the folder is supplied via the model's interface. |
252 | Components access names and paths via the following roles: |
253 | |
254 | \list |
255 | \li \c fileName (\c string) |
256 | \li \c filePath (\c string) |
257 | \li \c fileURL (\c url) (since Qt 5.2; deprecated since Qt 5.15) |
258 | \li \c fileUrl (\c url) (since Qt 5.15) |
259 | \li \c fileBaseName (\c string) |
260 | \li \c fileSuffix (\c string) |
261 | \li \c fileSize (\c qlonglong) |
262 | \li \c fileModified (\c date) |
263 | \li \c fileAccessed (\c date) |
264 | \li \c fileIsDir (\c bool) |
265 | \endlist |
266 | |
267 | Additionally a file entry can be differentiated from a folder entry via the |
268 | isFolder() method. |
269 | |
270 | \section1 Filtering |
271 | |
272 | Various properties can be set to filter the number of files and directories |
273 | exposed by the model. |
274 | |
275 | The \l nameFilters property can be set to contain a list of wildcard filters |
276 | that are applied to names of files and directories, causing only those that |
277 | match the filters to be exposed. |
278 | |
279 | Directories can be included or excluded using the \l showDirs property, |
280 | navigation directories can also be excluded by setting the \l showDotAndDotDot |
281 | property to false, hidden files can be included or excluded using the |
282 | \l showHidden property. |
283 | |
284 | It is sometimes useful to limit the files and directories exposed to those |
285 | that the user can access. The \l showOnlyReadable property can be set to |
286 | enable this feature. |
287 | |
288 | \section1 Example Usage |
289 | |
290 | The following example shows a FolderListModel being used to provide a list |
291 | of QML files in a \l ListView: |
292 | |
293 | \qml |
294 | import QtQuick |
295 | import Qt.labs.folderlistmodel |
296 | |
297 | ListView { |
298 | width: 200; height: 400 |
299 | |
300 | FolderListModel { |
301 | id: folderModel |
302 | nameFilters: ["*.qml"] |
303 | } |
304 | |
305 | Component { |
306 | id: fileDelegate |
307 | required property string fileName |
308 | Text { text: fileName } |
309 | } |
310 | |
311 | model: folderModel |
312 | delegate: fileDelegate |
313 | } |
314 | \endqml |
315 | |
316 | \section1 Path Separators |
317 | |
318 | Qt uses "/" as a universal directory separator in the same way that "/" is |
319 | used as a path separator in URLs. If you always use "/" as a directory |
320 | separator, Qt will translate your paths to conform to the underlying |
321 | operating system. |
322 | |
323 | \sa {QML Data Models} |
324 | */ |
325 | |
326 | QQuickFolderListModel::QQuickFolderListModel(QObject *parent) |
327 | : QAbstractListModel(parent), d_ptr(new QQuickFolderListModelPrivate(this)) |
328 | { |
329 | Q_D(QQuickFolderListModel); |
330 | d->roleNames[FileNameRole] = "fileName"; |
331 | d->roleNames[FilePathRole] = "filePath"; |
332 | d->roleNames[FileBaseNameRole] = "fileBaseName"; |
333 | d->roleNames[FileSuffixRole] = "fileSuffix"; |
334 | d->roleNames[FileSizeRole] = "fileSize"; |
335 | d->roleNames[FileLastModifiedRole] = "fileModified"; |
336 | d->roleNames[FileLastReadRole] = "fileAccessed"; |
337 | d->roleNames[FileIsDirRole] = "fileIsDir"; |
338 | d->roleNames[FileUrlRole] = "fileUrl"; |
339 | d->roleNames[FileURLRole] = "fileURL"; |
340 | d->init(); |
341 | } |
342 | |
343 | QQuickFolderListModel::~QQuickFolderListModel() |
344 | { |
345 | } |
346 | |
347 | QVariant QQuickFolderListModel::data(const QModelIndex &index, int role) const |
348 | { |
349 | Q_D(const QQuickFolderListModel); |
350 | QVariant rv; |
351 | |
352 | if (index.row() >= d->data.size()) |
353 | return rv; |
354 | |
355 | switch (role) |
356 | { |
357 | case FileNameRole: |
358 | rv = d->data.at(i: index.row()).fileName(); |
359 | break; |
360 | case FilePathRole: |
361 | rv = d->data.at(i: index.row()).filePath(); |
362 | break; |
363 | case FileBaseNameRole: |
364 | rv = d->data.at(i: index.row()).baseName(); |
365 | break; |
366 | case FileSuffixRole: |
367 | rv = d->data.at(i: index.row()).suffix(); |
368 | break; |
369 | case FileSizeRole: |
370 | rv = d->data.at(i: index.row()).size(); |
371 | break; |
372 | case FileLastModifiedRole: |
373 | rv = d->data.at(i: index.row()).lastModified(); |
374 | break; |
375 | case FileLastReadRole: |
376 | rv = d->data.at(i: index.row()).lastRead(); |
377 | break; |
378 | case FileIsDirRole: |
379 | rv = d->data.at(i: index.row()).isDir(); |
380 | break; |
381 | case FileUrlRole: |
382 | case FileURLRole: |
383 | rv = QUrl::fromLocalFile(localfile: d->data.at(i: index.row()).filePath()); |
384 | break; |
385 | default: |
386 | break; |
387 | } |
388 | return rv; |
389 | } |
390 | |
391 | QHash<int, QByteArray> QQuickFolderListModel::roleNames() const |
392 | { |
393 | Q_D(const QQuickFolderListModel); |
394 | return d->roleNames; |
395 | } |
396 | |
397 | /*! |
398 | \qmlproperty int FolderListModel::count |
399 | \readonly |
400 | |
401 | Returns the number of items in the current folder that match the |
402 | filter criteria. |
403 | */ |
404 | int QQuickFolderListModel::rowCount(const QModelIndex &parent) const |
405 | { |
406 | Q_D(const QQuickFolderListModel); |
407 | Q_UNUSED(parent); |
408 | return d->data.size(); |
409 | } |
410 | |
411 | QModelIndex QQuickFolderListModel::index(int row, int , const QModelIndex &) const |
412 | { |
413 | return createIndex(arow: row, acolumn: 0); |
414 | } |
415 | |
416 | /*! |
417 | \qmlproperty url FolderListModel::folder |
418 | |
419 | The \a folder property holds a URL for the folder that the model |
420 | currently provides. |
421 | |
422 | The value must be a \c file: or \c qrc: URL, or a relative URL. |
423 | |
424 | The default value is the application's working directory at the time |
425 | when the FolderListModel is first initialized. |
426 | */ |
427 | QUrl QQuickFolderListModel::folder() const |
428 | { |
429 | Q_D(const QQuickFolderListModel); |
430 | return d->currentDir; |
431 | } |
432 | |
433 | void QQuickFolderListModel::setFolder(const QUrl &folder) |
434 | { |
435 | Q_D(QQuickFolderListModel); |
436 | |
437 | if (folder == d->currentDir) |
438 | return; |
439 | |
440 | // It's possible for the folder to be set twice in quick succession, |
441 | // in which case we could still be waiting for FileInfoThread to finish |
442 | // getting the list of files from the previously set folder. We should |
443 | // at least ensure that the begin/end model reset routine is followed |
444 | // in the correct order, and not e.g. call beginResetModel twice. |
445 | if (d->resettingModel) |
446 | d->finishModelReset(); |
447 | |
448 | d->resettingModel = true; |
449 | |
450 | QString resolvedPath = QQuickFolderListModelPrivate::resolvePath(path: folder); |
451 | |
452 | qCDebug(lcFolderListModel) << "about to emit beginResetModel since our folder was set to"<< folder; |
453 | beginResetModel(); |
454 | |
455 | //Remove the old path for the file system watcher |
456 | if (!d->currentDir.isEmpty()) |
457 | d->fileInfoThread.removePath(path: d->currentDir.path()); |
458 | |
459 | d->currentDir = folder; |
460 | |
461 | QFileInfo info(resolvedPath); |
462 | if (!info.exists() || !info.isDir()) { |
463 | d->finishModelReset(); |
464 | return; |
465 | } |
466 | |
467 | d->fileInfoThread.setPath(resolvedPath); |
468 | } |
469 | |
470 | |
471 | /*! |
472 | \qmlproperty url FolderListModel::rootFolder |
473 | |
474 | When this property is set, the given folder will |
475 | be treated as the root in the file system, so that |
476 | you can only traverse subfolders within it. |
477 | */ |
478 | QUrl QQuickFolderListModel::rootFolder() const |
479 | { |
480 | Q_D(const QQuickFolderListModel); |
481 | return d->rootDir; |
482 | } |
483 | |
484 | void QQuickFolderListModel::setRootFolder(const QUrl &path) |
485 | { |
486 | Q_D(QQuickFolderListModel); |
487 | |
488 | if (path.isEmpty()) |
489 | return; |
490 | |
491 | QString resolvedPath = QQuickFolderListModelPrivate::resolvePath(path); |
492 | |
493 | QFileInfo info(resolvedPath); |
494 | if (!info.exists() || !info.isDir()) |
495 | return; |
496 | |
497 | d->fileInfoThread.setRootPath(resolvedPath); |
498 | d->rootDir = path; |
499 | } |
500 | |
501 | |
502 | /*! |
503 | \qmlproperty url FolderListModel::parentFolder |
504 | \readonly |
505 | |
506 | Returns the URL of the parent of the current \l folder. |
507 | */ |
508 | QUrl QQuickFolderListModel::parentFolder() const |
509 | { |
510 | Q_D(const QQuickFolderListModel); |
511 | |
512 | QString localFile = d->currentDir.toLocalFile(); |
513 | if (!localFile.isEmpty()) { |
514 | QDir dir(localFile); |
515 | if (dir.isRoot() || !dir.cdUp()) |
516 | return QUrl(); |
517 | localFile = dir.path(); |
518 | } else { |
519 | const QString path = d->currentDir.path(); |
520 | const int pos = path.lastIndexOf(c: QLatin1Char('/')); |
521 | if (pos <= 0) |
522 | return QUrl(); |
523 | localFile = path.left(n: pos); |
524 | } |
525 | return QUrl::fromLocalFile(localfile: localFile); |
526 | } |
527 | |
528 | /*! |
529 | \qmlproperty list<string> FolderListModel::nameFilters |
530 | |
531 | The \a nameFilters property contains a list of file name filters. |
532 | The filters may include the ? and * wildcards. |
533 | |
534 | The example below filters on PNG and JPEG files: |
535 | |
536 | \qml |
537 | FolderListModel { |
538 | nameFilters: [ "*.png", "*.jpg" ] |
539 | } |
540 | \endqml |
541 | |
542 | \note Directories are not excluded by filters. |
543 | */ |
544 | QStringList QQuickFolderListModel::nameFilters() const |
545 | { |
546 | Q_D(const QQuickFolderListModel); |
547 | return d->nameFilters; |
548 | } |
549 | |
550 | void QQuickFolderListModel::setNameFilters(const QStringList &filters) |
551 | { |
552 | Q_D(QQuickFolderListModel); |
553 | if (d->nameFilters == filters) |
554 | return; |
555 | d->fileInfoThread.setNameFilters(filters); |
556 | d->nameFilters = filters; |
557 | } |
558 | |
559 | void QQuickFolderListModel::classBegin() |
560 | { |
561 | } |
562 | |
563 | void QQuickFolderListModel::componentComplete() |
564 | { |
565 | Q_D(QQuickFolderListModel); |
566 | QString localPath = QQmlFile::urlToLocalFileOrQrc(d->currentDir); |
567 | if (localPath.isEmpty() || !QDir(localPath).exists()) |
568 | setFolder(QUrl::fromLocalFile(localfile: QDir::currentPath())); |
569 | d->fileInfoThread.start(QThread::LowPriority); |
570 | } |
571 | |
572 | /*! |
573 | \qmlproperty enumeration FolderListModel::sortField |
574 | |
575 | The \a sortField property contains the field to use for sorting. |
576 | \c sortField may be one of: |
577 | |
578 | \value FolderListModel.Unsorted no sorting is applied |
579 | \value FolderListModel.Name sort by filename (default) |
580 | \value FolderListModel.Time sort by time modified |
581 | \value FolderListModel.Size sort by file size |
582 | \value FolderListModel.Type sort by file type/extension |
583 | |
584 | \sa sortReversed |
585 | */ |
586 | QQuickFolderListModel::SortField QQuickFolderListModel::sortField() const |
587 | { |
588 | Q_D(const QQuickFolderListModel); |
589 | return d->sortField; |
590 | } |
591 | |
592 | void QQuickFolderListModel::setSortField(SortField field) |
593 | { |
594 | Q_D(QQuickFolderListModel); |
595 | if (field != d->sortField) { |
596 | d->sortField = field; |
597 | d->updateSorting(); |
598 | } |
599 | } |
600 | |
601 | int QQuickFolderListModel::roleFromString(const QString &roleName) const |
602 | { |
603 | Q_D(const QQuickFolderListModel); |
604 | return d->roleNames.key(value: roleName.toLatin1(), defaultKey: -1); |
605 | } |
606 | |
607 | /*! |
608 | \qmlproperty bool FolderListModel::sortReversed |
609 | |
610 | If set to true, reverses the sort order. The default is false. |
611 | |
612 | \sa sortField |
613 | */ |
614 | bool QQuickFolderListModel::sortReversed() const |
615 | { |
616 | Q_D(const QQuickFolderListModel); |
617 | return d->sortReversed; |
618 | } |
619 | |
620 | void QQuickFolderListModel::setSortReversed(bool rev) |
621 | { |
622 | Q_D(QQuickFolderListModel); |
623 | |
624 | if (rev != d->sortReversed) { |
625 | d->sortReversed = rev; |
626 | d->updateSorting(); |
627 | } |
628 | } |
629 | |
630 | /*! |
631 | \qmlmethod bool FolderListModel::isFolder(int index) |
632 | |
633 | Returns true if the entry \a index is a folder; otherwise |
634 | returns false. |
635 | */ |
636 | bool QQuickFolderListModel::isFolder(int index) const |
637 | { |
638 | if (index != -1) { |
639 | QModelIndex idx = createIndex(arow: index, acolumn: 0); |
640 | if (idx.isValid()) { |
641 | QVariant var = data(index: idx, role: FileIsDirRole); |
642 | if (var.isValid()) |
643 | return var.toBool(); |
644 | } |
645 | } |
646 | return false; |
647 | } |
648 | |
649 | /*! |
650 | \qmlproperty bool FolderListModel::showFiles |
651 | \since 5.2 |
652 | |
653 | If true, files are included in the model; otherwise only directories |
654 | are included. |
655 | |
656 | By default, this property is true. |
657 | |
658 | \sa showDirs |
659 | */ |
660 | bool QQuickFolderListModel::showFiles() const |
661 | { |
662 | Q_D(const QQuickFolderListModel); |
663 | return d->showFiles; |
664 | } |
665 | |
666 | void QQuickFolderListModel::setShowFiles(bool on) |
667 | { |
668 | Q_D(QQuickFolderListModel); |
669 | |
670 | d->fileInfoThread.setShowFiles(on); |
671 | d->showFiles = on; |
672 | } |
673 | |
674 | /*! |
675 | \qmlproperty bool FolderListModel::showDirs |
676 | |
677 | If true, directories are included in the model; otherwise only files |
678 | are included. |
679 | |
680 | By default, this property is true. |
681 | |
682 | Note that the nameFilters are not applied to directories. |
683 | |
684 | \sa showDotAndDotDot |
685 | */ |
686 | bool QQuickFolderListModel::showDirs() const |
687 | { |
688 | Q_D(const QQuickFolderListModel); |
689 | return d->showDirs; |
690 | } |
691 | |
692 | void QQuickFolderListModel::setShowDirs(bool on) |
693 | { |
694 | Q_D(QQuickFolderListModel); |
695 | |
696 | d->fileInfoThread.setShowDirs(on); |
697 | d->showDirs = on; |
698 | } |
699 | |
700 | /*! |
701 | \qmlproperty bool FolderListModel::showDirsFirst |
702 | |
703 | If true, if directories are included in the model they will |
704 | always be shown first, then the files. |
705 | |
706 | By default, this property is false. |
707 | |
708 | */ |
709 | bool QQuickFolderListModel::showDirsFirst() const |
710 | { |
711 | Q_D(const QQuickFolderListModel); |
712 | return d->showDirsFirst; |
713 | } |
714 | |
715 | void QQuickFolderListModel::setShowDirsFirst(bool on) |
716 | { |
717 | Q_D(QQuickFolderListModel); |
718 | |
719 | d->fileInfoThread.setShowDirsFirst(on); |
720 | d->showDirsFirst = on; |
721 | } |
722 | |
723 | |
724 | /*! |
725 | \qmlproperty bool FolderListModel::showDotAndDotDot |
726 | |
727 | If true, the "." and ".." directories are included in the model; otherwise |
728 | they are excluded. |
729 | |
730 | By default, this property is false. |
731 | |
732 | \sa showDirs |
733 | */ |
734 | bool QQuickFolderListModel::showDotAndDotDot() const |
735 | { |
736 | Q_D(const QQuickFolderListModel); |
737 | return d->showDotAndDotDot; |
738 | } |
739 | |
740 | void QQuickFolderListModel::setShowDotAndDotDot(bool on) |
741 | { |
742 | Q_D(QQuickFolderListModel); |
743 | |
744 | if (on != d->showDotAndDotDot) { |
745 | d->fileInfoThread.setShowDotAndDotDot(on); |
746 | d->showDotAndDotDot = on; |
747 | } |
748 | } |
749 | |
750 | |
751 | /*! |
752 | \qmlproperty bool FolderListModel::showHidden |
753 | \since 5.2 |
754 | |
755 | If true, hidden files and directories are included in the model; otherwise |
756 | they are excluded. |
757 | |
758 | By default, this property is false. |
759 | */ |
760 | bool QQuickFolderListModel::showHidden() const |
761 | { |
762 | Q_D(const QQuickFolderListModel); |
763 | return d->showHidden; |
764 | } |
765 | |
766 | void QQuickFolderListModel::setShowHidden(bool on) |
767 | { |
768 | Q_D(QQuickFolderListModel); |
769 | |
770 | if (on != d->showHidden) { |
771 | d->fileInfoThread.setShowHidden(on); |
772 | d->showHidden = on; |
773 | } |
774 | } |
775 | |
776 | /*! |
777 | \qmlproperty bool FolderListModel::showOnlyReadable |
778 | |
779 | If true, only readable files and directories are shown; otherwise all files |
780 | and directories are shown. |
781 | |
782 | By default, this property is false. |
783 | |
784 | \sa showDirs |
785 | */ |
786 | bool QQuickFolderListModel::showOnlyReadable() const |
787 | { |
788 | Q_D(const QQuickFolderListModel); |
789 | return d->showOnlyReadable; |
790 | } |
791 | |
792 | void QQuickFolderListModel::setShowOnlyReadable(bool on) |
793 | { |
794 | Q_D(QQuickFolderListModel); |
795 | |
796 | if (on != d->showOnlyReadable) { |
797 | d->fileInfoThread.setShowOnlyReadable(on); |
798 | d->showOnlyReadable = on; |
799 | } |
800 | } |
801 | |
802 | /*! |
803 | * \qmlproperty bool FolderListModel::caseSensitive |
804 | * \since 5.7 |
805 | * |
806 | * Use case sensitive pattern matching. |
807 | * |
808 | * By default, this property is true. |
809 | * |
810 | */ |
811 | bool QQuickFolderListModel::caseSensitive() const |
812 | { |
813 | Q_D(const QQuickFolderListModel); |
814 | return d->caseSensitive; |
815 | } |
816 | |
817 | void QQuickFolderListModel::setCaseSensitive(bool on) |
818 | { |
819 | Q_D(QQuickFolderListModel); |
820 | |
821 | if (on != d->caseSensitive) { |
822 | d->fileInfoThread.setCaseSensitive(on); |
823 | d->caseSensitive = on; |
824 | } |
825 | } |
826 | |
827 | /*! |
828 | \qmlproperty enumeration FolderListModel::status |
829 | \since 5.11 |
830 | \readonly |
831 | |
832 | This property holds the status of folder reading. It can be one of: |
833 | |
834 | \value FolderListModel.Null no \a folder has been set |
835 | \value FolderListModel.Ready the folder has been loaded |
836 | \value FolderListModel.Loading the folder is currently being loaded |
837 | |
838 | Use this status to provide an update or respond to the status change in some way. |
839 | For example, you could: |
840 | |
841 | \list |
842 | \li Trigger a state change: |
843 | \qml |
844 | State { name: 'loaded'; when: folderModel.status == FolderListModel.Ready } |
845 | \endqml |
846 | |
847 | \li Implement an \c onStatusChanged signal handler: |
848 | \qml |
849 | FolderListModel { |
850 | id: folderModel |
851 | onStatusChanged: if (folderModel.status == FolderListModel.Ready) console.log('Loaded') |
852 | } |
853 | \endqml |
854 | |
855 | \li Bind to the status value: |
856 | \qml |
857 | Text { text: folderModel.status == FolderListModel.Ready ? 'Loaded' : 'Not loaded' } |
858 | \endqml |
859 | \endlist |
860 | */ |
861 | QQuickFolderListModel::Status QQuickFolderListModel::status() const |
862 | { |
863 | Q_D(const QQuickFolderListModel); |
864 | return d->status; |
865 | } |
866 | |
867 | /*! |
868 | \qmlproperty bool FolderListModel::sortCaseSensitive |
869 | \since 5.12 |
870 | |
871 | If set to \c true, the sort is case sensitive. This property is \c true by default. |
872 | */ |
873 | |
874 | bool QQuickFolderListModel::sortCaseSensitive() const |
875 | { |
876 | Q_D(const QQuickFolderListModel); |
877 | return d->sortCaseSensitive; |
878 | } |
879 | |
880 | void QQuickFolderListModel::setSortCaseSensitive(bool on) |
881 | { |
882 | Q_D(QQuickFolderListModel); |
883 | |
884 | if (on != d->sortCaseSensitive) { |
885 | d->sortCaseSensitive = on; |
886 | d->updateSorting(); |
887 | } |
888 | } |
889 | |
890 | /*! |
891 | \qmlmethod var FolderListModel::get(int index, string property) |
892 | |
893 | Returns the folder \a property for the given \a index. The following properties |
894 | are available: |
895 | |
896 | \list |
897 | \li \c fileName (\c string) |
898 | \li \c filePath (\c string) |
899 | \li \c fileURL (\c url) (since Qt 5.2; deprecated since Qt 5.15) |
900 | \li \c fileUrl (\c url) (since Qt 5.15) |
901 | \li \c fileBaseName (\c string) |
902 | \li \c fileSuffix (\c string) |
903 | \li \c fileSize (\c qlonglong) |
904 | \li \c fileModified (\c date) |
905 | \li \c fileAccessed (\c date) |
906 | \li \c fileIsDir (\c bool) |
907 | \endlist |
908 | */ |
909 | QVariant QQuickFolderListModel::get(int idx, const QString &property) const |
910 | { |
911 | int role = roleFromString(roleName: property); |
912 | if (role >= 0 && idx >= 0) |
913 | return data(index: index(row: idx, 0), role); |
914 | else |
915 | return QVariant(); |
916 | } |
917 | |
918 | /*! |
919 | \qmlmethod int FolderListModel::indexOf(url file) |
920 | \since 5.6 |
921 | |
922 | Returns the index of the given \a file URL if the model contains it, |
923 | or -1 if not. |
924 | */ |
925 | int QQuickFolderListModel::indexOf(const QUrl &file) const |
926 | { |
927 | Q_D(const QQuickFolderListModel); |
928 | FileProperty toFind(QFileInfo(file.toLocalFile())); |
929 | return d->data.indexOf(t: toFind); |
930 | } |
931 | |
932 | //![code] |
933 | QT_END_NAMESPACE |
934 | |
935 | #include "moc_qquickfolderlistmodel_p.cpp" |
936 |
Definitions
- lcFolderListModel
- QQuickFolderListModelPrivate
- QQuickFolderListModelPrivate
- ~QQuickFolderListModelPrivate
- init
- updateSorting
- finishModelReset
- _q_directoryChanged
- _q_directoryUpdated
- _q_sortFinished
- _q_statusChanged
- resolvePath
- QQuickFolderListModel
- ~QQuickFolderListModel
- data
- roleNames
- rowCount
- index
- folder
- setFolder
- rootFolder
- setRootFolder
- parentFolder
- nameFilters
- setNameFilters
- classBegin
- componentComplete
- sortField
- setSortField
- roleFromString
- sortReversed
- setSortReversed
- isFolder
- showFiles
- setShowFiles
- showDirs
- setShowDirs
- showDirsFirst
- setShowDirsFirst
- showDotAndDotDot
- setShowDotAndDotDot
- showHidden
- setShowHidden
- showOnlyReadable
- setShowOnlyReadable
- caseSensitive
- setCaseSensitive
- status
- sortCaseSensitive
- setSortCaseSensitive
- get
Learn to use CMake with our Intro Training
Find out more