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

source code of qtdeclarative/src/labs/folderlistmodel/qquickfolderlistmodel.cpp