Qt 6.x
The Qt SDK
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
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>)),
63 q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString,QList<FileProperty>,int,int)),
65 q->connect(&fileInfoThread, SIGNAL(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
122{
125
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
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
307{
309 d->roleNames[FileNameRole] = "fileName";
310 d->roleNames[FilePathRole] = "filePath";
311 d->roleNames[FileBaseNameRole] = "fileBaseName";
312 d->roleNames[FileSuffixRole] = "fileSuffix";
313 d->roleNames[FileSizeRole] = "fileSize";
314 d->roleNames[FileLastModifiedRole] = "fileModified";
315 d->roleNames[FileLastReadRole] = "fileAccessed";
316 d->roleNames[FileIsDirRole] = "fileIsDir";
317 d->roleNames[FileUrlRole] = "fileUrl";
318 d->roleNames[FileURLRole] = "fileURL";
319 d->init();
320}
321
323{
324}
325
327{
328 Q_D(const QQuickFolderListModel);
329 QVariant rv;
330
331 if (index.row() >= d->data.size())
332 return rv;
333
334 switch (role)
335 {
336 case FileNameRole:
337 rv = d->data.at(index.row()).fileName();
338 break;
339 case FilePathRole:
340 rv = d->data.at(index.row()).filePath();
341 break;
342 case FileBaseNameRole:
343 rv = d->data.at(index.row()).baseName();
344 break;
345 case FileSuffixRole:
346 rv = d->data.at(index.row()).suffix();
347 break;
348 case FileSizeRole:
349 rv = d->data.at(index.row()).size();
350 break;
352 rv = d->data.at(index.row()).lastModified();
353 break;
354 case FileLastReadRole:
355 rv = d->data.at(index.row()).lastRead();
356 break;
357 case FileIsDirRole:
358 rv = d->data.at(index.row()).isDir();
359 break;
360 case FileUrlRole:
361 case FileURLRole:
362 rv = QUrl::fromLocalFile(d->data.at(index.row()).filePath());
363 break;
364 default:
365 break;
366 }
367 return rv;
368}
369
371{
372 Q_D(const QQuickFolderListModel);
373 return d->roleNames;
374}
375
384{
385 Q_D(const QQuickFolderListModel);
387 return d->data.size();
388}
389
391{
392 return createIndex(row, 0);
393}
394
406{
407 Q_D(const QQuickFolderListModel);
408 return d->currentDir;
409}
410
412{
414
415 if (folder == d->currentDir)
416 return;
417
419
420 qCDebug(lcFolderListModel) << "about to emit beginResetModel since our folder was set to" << folder;
422
423 //Remove the old path for the file system watcher
424 if (!d->currentDir.isEmpty())
425 d->fileInfoThread.removePath(d->currentDir.path());
426
427 d->currentDir = folder;
428
429 QFileInfo info(resolvedPath);
430 if (!info.exists() || !info.isDir()) {
431 d->data.clear();
434 if (d->status != QQuickFolderListModel::Null) {
437 }
438 return;
439 }
440
441 d->fileInfoThread.setPath(resolvedPath);
442}
443
444
453{
454 Q_D(const QQuickFolderListModel);
455 return d->rootDir;
456}
457
459{
461
462 if (path.isEmpty())
463 return;
464
466
467 QFileInfo info(resolvedPath);
468 if (!info.exists() || !info.isDir())
469 return;
470
471 d->fileInfoThread.setRootPath(resolvedPath);
472 d->rootDir = path;
473}
474
475
483{
484 Q_D(const QQuickFolderListModel);
485
486 QString localFile = d->currentDir.toLocalFile();
487 if (!localFile.isEmpty()) {
488 QDir dir(localFile);
489 if (dir.isRoot() || !dir.cdUp())
490 return QUrl();
491 localFile = dir.path();
492 } else {
493 const QString path = d->currentDir.path();
494 const int pos = path.lastIndexOf(QLatin1Char('/'));
495 if (pos <= 0)
496 return QUrl();
497 localFile = path.left(pos);
498 }
499 return QUrl::fromLocalFile(localFile);
500}
501
519{
520 Q_D(const QQuickFolderListModel);
521 return d->nameFilters;
522}
523
525{
527 if (d->nameFilters == filters)
528 return;
529 d->fileInfoThread.setNameFilters(filters);
530 d->nameFilters = filters;
531}
532
534{
535}
536
538{
540 QString localPath = QQmlFile::urlToLocalFileOrQrc(d->currentDir);
541 if (localPath.isEmpty() || !QDir(localPath).exists())
543 d->fileInfoThread.start(QThread::LowPriority);
544}
545
561{
562 Q_D(const QQuickFolderListModel);
563 return d->sortField;
564}
565
567{
569 if (field != d->sortField) {
570 d->sortField = field;
571 d->updateSorting();
572 }
573}
574
576{
577 Q_D(const QQuickFolderListModel);
578 return d->roleNames.key(roleName.toLatin1(), -1);
579}
580
589{
590 Q_D(const QQuickFolderListModel);
591 return d->sortReversed;
592}
593
595{
597
598 if (rev != d->sortReversed) {
599 d->sortReversed = rev;
600 d->updateSorting();
601 }
602}
603
611{
612 if (index != -1) {
613 QModelIndex idx = createIndex(index, 0);
614 if (idx.isValid()) {
616 if (var.isValid())
617 return var.toBool();
618 }
619 }
620 return false;
621}
622
635{
636 Q_D(const QQuickFolderListModel);
637 return d->showFiles;
638}
639
641{
643
644 d->fileInfoThread.setShowFiles(on);
645 d->showFiles = on;
646}
647
661{
662 Q_D(const QQuickFolderListModel);
663 return d->showDirs;
664}
665
667{
669
670 d->fileInfoThread.setShowDirs(on);
671 d->showDirs = on;
672}
673
684{
685 Q_D(const QQuickFolderListModel);
686 return d->showDirsFirst;
687}
688
690{
692
693 d->fileInfoThread.setShowDirsFirst(on);
694 d->showDirsFirst = on;
695}
696
697
709{
710 Q_D(const QQuickFolderListModel);
711 return d->showDotAndDotDot;
712}
713
715{
717
718 if (on != d->showDotAndDotDot) {
719 d->fileInfoThread.setShowDotAndDotDot(on);
720 d->showDotAndDotDot = on;
721 }
722}
723
724
735{
736 Q_D(const QQuickFolderListModel);
737 return d->showHidden;
738}
739
741{
743
744 if (on != d->showHidden) {
745 d->fileInfoThread.setShowHidden(on);
746 d->showHidden = on;
747 }
748}
749
761{
762 Q_D(const QQuickFolderListModel);
763 return d->showOnlyReadable;
764}
765
767{
769
770 if (on != d->showOnlyReadable) {
771 d->fileInfoThread.setShowOnlyReadable(on);
772 d->showOnlyReadable = on;
773 }
774}
775
786{
787 Q_D(const QQuickFolderListModel);
788 return d->caseSensitive;
789}
790
792{
794
795 if (on != d->caseSensitive) {
796 d->fileInfoThread.setCaseSensitive(on);
797 d->caseSensitive = on;
798 }
799}
800
836{
837 Q_D(const QQuickFolderListModel);
838 return d->status;
839}
840
849{
850 Q_D(const QQuickFolderListModel);
851 return d->sortCaseSensitive;
852}
853
855{
857
858 if (on != d->sortCaseSensitive) {
859 d->sortCaseSensitive = on;
860 d->updateSorting();
861 }
862}
863
884{
885 int role = roleFromString(property);
886 if (role >= 0 && idx >= 0)
887 return data(index(idx, 0), role);
888 else
889 return QVariant();
890}
891
900{
901 Q_D(const QQuickFolderListModel);
902 FileProperty toFind(QFileInfo(file.toLocalFile()));
903 return d->data.indexOf(toFind);
904}
905
908
909#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:311
\inmodule QtCore
Definition qdir.h:19
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2395
@ Size
Definition qdir.h:51
@ IgnoreCase
Definition qdir.h:57
@ Unsorted
Definition qdir.h:52
@ Time
Definition qdir.h:50
@ Name
Definition qdir.h:49
@ Type
Definition qdir.h:60
@ Reversed
Definition qdir.h:56
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2051
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
bool exists() const
Returns true if the file exists; otherwise returns false.
\inmodule QtCore
Definition qhash.h:818
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
\inmodule QtCore
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
\inmodule QtCore
Definition qobject.h:90
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to QFile.
Definition qqmlfile.cpp:643
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:127
QByteArray toLatin1() const &
Definition qstring.h:559
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
@ LowPriority
Definition qthread.h:45
\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:3354
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1983
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2465
\inmodule QtCore
Definition qvariant.h:64
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
#define this
Definition dialogs.cpp:9
void statusChanged(QDeclarativeComponent::Status status)
[1]
Definition qlogging.cpp:9
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLuint index
[2]
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLenum GLenum GLsizei void * row
GLdouble s
[6]
Definition qopenglext.h:235
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]
QFileInfo info(fileName)
[8]
QString dir
[11]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
\inmodule QtCore \reentrant
Definition qchar.h:17
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent