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