Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickfolderlistmodel.cpp
Go to the documentation of this file.
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
6#include "fileinfothread_p.h"
7#include "fileproperty_p.h"
8#include <QtCore/qloggingcategory.h>
9#include <qqmlcontext.h>
10#include <qqmlfile.h>
11
13
14Q_LOGGING_CATEGORY(lcFolderListModel, "qt.labs.folderlistmodel")
15
17{
18 Q_DECLARE_PUBLIC(QQuickFolderListModel)
19
20public:
22
27 QList<FileProperty> data;
28 QHash<int, QByteArray> roleNames;
30 QStringList nameFilters = { QLatin1String("*") };
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
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
57{
59 qRegisterMetaType<QList<FileProperty> >("QList<FileProperty>");
60 qRegisterMetaType<QQuickFolderListModel::Status>("QQuickFolderListModel::Status");
61 q->connect(&fileInfoThread, SIGNAL(directoryChanged(QString,QList<FileProperty>)),
62 q, SLOT(_q_directoryChanged(QString,QList<FileProperty>)));
63 q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString,QList<FileProperty>,int,int)),
64 q, SLOT(_q_directoryUpdated(QString,QList<FileProperty>,int,int)));
65 q->connect(&fileInfoThread, SIGNAL(sortFinished(QList<FileProperty>)),
66 q, SLOT(_q_sortFinished(QList<FileProperty>)));
69 q->connect(q, SIGNAL(rowCountChanged()), q, SIGNAL(countChanged()));
70}
71
72
74{
76
77 QDir::SortFlags flags;
78
79 switch (sortField) {
82 break;
85 break;
88 break;
91 break;
94 break;
95 }
96
97 emit q->layoutAboutToBeChanged();
98
99 if (sortReversed)
103
105}
106
108{
109 qCDebug(lcFolderListModel) << "_q_directoryChanged called with directory" << directory;
112
113 data = list;
114 q->endResetModel();
115 qCDebug(lcFolderListModel) << "- endResetModel called";
116 emit q->rowCountChanged();
117 emit q->folderChanged();
118}
119
120
121void QQuickFolderListModelPrivate::_q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex)
122{
125
126 QModelIndex parent;
127 if (data.size() == list.size()) {
128 QModelIndex modelIndexFrom = q->createIndex(fromIndex, 0);
129 QModelIndex modelIndexTo = q->createIndex(toIndex, 0);
130 data = list;
131 emit q->dataChanged(modelIndexFrom, 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, 0, 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, 0, data.size() - 1);
146 q->endInsertRows();
147 }
148 emit q->rowCountChanged();
149 }
150}
151
153{
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, 0, 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, 0, list.size()-1);
168 data = list;
169 q->endInsertRows();
170 qCDebug(lcFolderListModel) << "- ... inserted sorted rows";
171}
172
174{
176
177 if (status != s) {
178 status = s;
179 emit q->statusChanged();
180 }
181}
182
184{
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(fullPath);
191}
192
210
308{
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
326
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(index.row()).fileName();
339 break;
340 case FilePathRole:
341 rv = d->data.at(index.row()).filePath();
342 break;
343 case FileBaseNameRole:
344 rv = d->data.at(index.row()).baseName();
345 break;
346 case FileSuffixRole:
347 rv = d->data.at(index.row()).suffix();
348 break;
349 case FileSizeRole:
350 rv = d->data.at(index.row()).size();
351 break;
353 rv = d->data.at(index.row()).lastModified();
354 break;
355 case FileLastReadRole:
356 rv = d->data.at(index.row()).lastRead();
357 break;
358 case FileIsDirRole:
359 rv = d->data.at(index.row()).isDir();
360 break;
361 case FileUrlRole:
362 case FileURLRole:
363 rv = QUrl::fromLocalFile(d->data.at(index.row()).filePath());
364 break;
365 default:
366 break;
367 }
368 return rv;
369}
370
371QHash<int, QByteArray> QQuickFolderListModel::roleNames() const
372{
373 Q_D(const QQuickFolderListModel);
374 return d->roleNames;
375}
376
385{
386 Q_D(const QQuickFolderListModel);
388 return d->data.size();
389}
390
392{
393 return createIndex(row, 0);
394}
395
408{
409 Q_D(const QQuickFolderListModel);
410 return d->currentDir;
411}
412
414{
416
417 if (folder == d->currentDir)
418 return;
419
421
422 qCDebug(lcFolderListModel) << "about to emit beginResetModel since our folder was set to" << folder;
424
425 //Remove the old path for the file system watcher
426 if (!d->currentDir.isEmpty())
427 d->fileInfoThread.removePath(d->currentDir.path());
428
429 d->currentDir = folder;
430
431 QFileInfo info(resolvedPath);
432 if (!info.exists() || !info.isDir()) {
433 d->data.clear();
436 if (d->status != QQuickFolderListModel::Null) {
439 }
440 return;
441 }
442
443 d->fileInfoThread.setPath(resolvedPath);
444}
445
446
455{
456 Q_D(const QQuickFolderListModel);
457 return d->rootDir;
458}
459
461{
463
464 if (path.isEmpty())
465 return;
466
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
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(QLatin1Char('/'));
497 if (pos <= 0)
498 return QUrl();
499 localFile = path.left(pos);
500 }
501 return QUrl::fromLocalFile(localFile);
502}
503
521{
522 Q_D(const QQuickFolderListModel);
523 return d->nameFilters;
524}
525
527{
529 if (d->nameFilters == filters)
530 return;
531 d->fileInfoThread.setNameFilters(filters);
532 d->nameFilters = filters;
533}
534
538
540{
542 QString localPath = QQmlFile::urlToLocalFileOrQrc(d->currentDir);
543 if (localPath.isEmpty() || !QDir(localPath).exists())
545 d->fileInfoThread.start(QThread::LowPriority);
546}
547
563{
564 Q_D(const QQuickFolderListModel);
565 return d->sortField;
566}
567
569{
571 if (field != d->sortField) {
572 d->sortField = field;
573 d->updateSorting();
574 }
575}
576
578{
579 Q_D(const QQuickFolderListModel);
580 return d->roleNames.key(roleName.toLatin1(), -1);
581}
582
591{
592 Q_D(const QQuickFolderListModel);
593 return d->sortReversed;
594}
595
597{
599
600 if (rev != d->sortReversed) {
601 d->sortReversed = rev;
602 d->updateSorting();
603 }
604}
605
613{
614 if (index != -1) {
615 QModelIndex idx = createIndex(index, 0);
616 if (idx.isValid()) {
618 if (var.isValid())
619 return var.toBool();
620 }
621 }
622 return false;
623}
624
637{
638 Q_D(const QQuickFolderListModel);
639 return d->showFiles;
640}
641
643{
645
646 d->fileInfoThread.setShowFiles(on);
647 d->showFiles = on;
648}
649
663{
664 Q_D(const QQuickFolderListModel);
665 return d->showDirs;
666}
667
669{
671
672 d->fileInfoThread.setShowDirs(on);
673 d->showDirs = on;
674}
675
686{
687 Q_D(const QQuickFolderListModel);
688 return d->showDirsFirst;
689}
690
692{
694
695 d->fileInfoThread.setShowDirsFirst(on);
696 d->showDirsFirst = on;
697}
698
699
711{
712 Q_D(const QQuickFolderListModel);
713 return d->showDotAndDotDot;
714}
715
717{
719
720 if (on != d->showDotAndDotDot) {
721 d->fileInfoThread.setShowDotAndDotDot(on);
722 d->showDotAndDotDot = on;
723 }
724}
725
726
737{
738 Q_D(const QQuickFolderListModel);
739 return d->showHidden;
740}
741
743{
745
746 if (on != d->showHidden) {
747 d->fileInfoThread.setShowHidden(on);
748 d->showHidden = on;
749 }
750}
751
763{
764 Q_D(const QQuickFolderListModel);
765 return d->showOnlyReadable;
766}
767
769{
771
772 if (on != d->showOnlyReadable) {
773 d->fileInfoThread.setShowOnlyReadable(on);
774 d->showOnlyReadable = on;
775 }
776}
777
788{
789 Q_D(const QQuickFolderListModel);
790 return d->caseSensitive;
791}
792
794{
796
797 if (on != d->caseSensitive) {
798 d->fileInfoThread.setCaseSensitive(on);
799 d->caseSensitive = on;
800 }
801}
802
838{
839 Q_D(const QQuickFolderListModel);
840 return d->status;
841}
842
851{
852 Q_D(const QQuickFolderListModel);
853 return d->sortCaseSensitive;
854}
855
857{
859
860 if (on != d->sortCaseSensitive) {
861 d->sortCaseSensitive = on;
862 d->updateSorting();
863 }
864}
865
886{
887 int role = roleFromString(property);
888 if (role >= 0 && idx >= 0)
889 return data(index(idx, 0), role);
890 else
891 return QVariant();
892}
893
902{
903 Q_D(const QQuickFolderListModel);
904 FileProperty toFind(QFileInfo(file.toLocalFile()));
905 return d->data.indexOf(toFind);
906}
907
910
911#include "moc_qquickfolderlistmodel_p.cpp"
void setSortFlags(QDir::SortFlags flags)
void endResetModel()
Completes a model reset operation.
void beginResetModel()
Begins a model reset operation.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
\inmodule QtCore
Definition qdir.h:20
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2398
@ Size
Definition qdir.h:52
@ IgnoreCase
Definition qdir.h:58
@ Unsorted
Definition qdir.h:53
@ Time
Definition qdir.h:51
@ Name
Definition qdir.h:50
@ Type
Definition qdir.h:61
@ Reversed
Definition qdir.h:57
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2054
qsizetype size() const noexcept
Definition qlist.h:397
\inmodule QtCore
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
\inmodule QtCore
Definition qobject.h:103
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
static QString resolvePath(const QUrl &path)
void _q_sortFinished(const QList< FileProperty > &list)
QQuickFolderListModelPrivate(QQuickFolderListModel *q)
QHash< int, QByteArray > roleNames
QQuickFolderListModel::SortField sortField
void _q_directoryChanged(const QString &directory, const QList< FileProperty > &list)
void _q_statusChanged(QQuickFolderListModel::Status s)
void _q_directoryUpdated(const QString &directory, const QList< FileProperty > &list, int fromIndex, int toIndex)
QQuickFolderListModel::Status status
void setFolder(const QUrl &folder)
Q_INVOKABLE QVariant get(int idx, const QString &property) const
\qmlmethod var FolderListModel::get(int index, string property)
void setShowDirs(bool showDirs)
void setShowDirsFirst(bool showDirsFirst)
QHash< int, QByteArray > roleNames() const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Returns the index of the data in row and column with parent.
void setNameFilters(const QStringList &filters)
void rowCountChanged() const
Q_INVOKABLE int indexOf(const QUrl &file) const
\qmlmethod int FolderListModel::indexOf(url file)
void setSortField(SortField field)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
Q_INVOKABLE bool isFolder(int index) const
[prop funcs]
void setShowFiles(bool showFiles)
QQuickFolderListModel(QObject *parent=nullptr)
[class props]
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.
void setRootFolder(const QUrl &path)
void classBegin() override
[parserstatus]
int rowCount(const QModelIndex &parent=QModelIndex()) const override
\qmlproperty int FolderListModel::count \readonly
int roleFromString(const QString &roleName) const
[parserstatus]
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
@ LowPriority
Definition qthread.h:44
\inmodule QtCore
Definition qurl.h:94
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3368
\inmodule QtCore
Definition qvariant.h:65
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:714
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
#define this
Definition dialogs.cpp:9
void statusChanged(QQmlComponent::Status status)
[1]
Definition qlogging.cpp:11
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLuint index
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLbitfield flags
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLenum GLenum GLsizei void * row
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
#define emit
#define Q_UNUSED(x)
static uint toIndex(ExecutionEngine *e, const Value &v)
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
QFile file
[0]
QString dir
[11]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QHostInfo info
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18