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