QDirListing: add flags to handle entries filtering
By extending IteratorFlag so that it replaces both QDir::Filter and QDirIterator::IteratorFlag enums, but with better defaults (based on how QDir/Iterator is used in 15-20 years worth of code in Qt and KDE). Make the QDirListing(QDir ~~) ctor private, also change it to use QDirIterator::IteratatorFlags; it will be used to port existing code. If QDir is ported to use QDirListing::IteratorFlags, instead of QDir::Filters, a public QDirListing(QDir) constructor can then be added. Fixes: QTBUG-125504 Task-number: QTBUG-125859 Change-Id: Ide4ff8279f554029ac30d0579b0e8373ed4337f7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit e583c3d5163a5512abac85e32359652e28a053f7) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
0cbf579ca1
commit
7c663d04d7
@ -314,9 +314,9 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
|
|||||||
const QStringList sourceFilesFilter = sourceFilesForImplicitRulesFilter();
|
const QStringList sourceFilesFilter = sourceFilesForImplicitRulesFilter();
|
||||||
QStringList fixifiedSourceDirs = fileFixify(QList<QString>(source_directories.constBegin(), source_directories.constEnd()), FileFixifyAbsolute);
|
QStringList fixifiedSourceDirs = fileFixify(QList<QString>(source_directories.constBegin(), source_directories.constEnd()), FileFixifyAbsolute);
|
||||||
fixifiedSourceDirs.removeDuplicates();
|
fixifiedSourceDirs.removeDuplicates();
|
||||||
constexpr auto filters = QDir::Files | QDir::NoDotAndDotDot;
|
using F = QDirListing::IteratorFlag;
|
||||||
for (const QString &sourceDir : std::as_const(fixifiedSourceDirs)) {
|
for (const QString &sourceDir : std::as_const(fixifiedSourceDirs)) {
|
||||||
for (const auto &dirEntry : QDirListing(sourceDir, sourceFilesFilter, filters)) {
|
for (const auto &dirEntry : QDirListing(sourceDir, sourceFilesFilter, F::FilesOnly)) {
|
||||||
QString &duplicate = fileNames[dirEntry.completeBaseName()];
|
QString &duplicate = fileNames[dirEntry.completeBaseName()];
|
||||||
if (duplicate.isNull()) {
|
if (duplicate.isNull()) {
|
||||||
duplicate = dirEntry.filePath();
|
duplicate = dirEntry.filePath();
|
||||||
|
@ -1293,9 +1293,8 @@ void VcprojGenerator::initDeploymentTool()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int pathSize = searchPath.size();
|
int pathSize = searchPath.size();
|
||||||
constexpr auto filters = QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks;
|
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
QDirListing dirList(searchPath, QStringList{nameFilter}, filters, F::Recursive);
|
QDirListing dirList(searchPath, QStringList{nameFilter}, F::FilesOnly | F::Recursive);
|
||||||
// foreach dirIterator-entry in d
|
// foreach dirIterator-entry in d
|
||||||
for (const auto &dirEntry : dirList) {
|
for (const auto &dirEntry : dirList) {
|
||||||
const QString absoluteItemPath = Option::fixPathToTargetOS(dirEntry.absolutePath());
|
const QString absoluteItemPath = Option::fixPathToTargetOS(dirEntry.absolutePath());
|
||||||
|
@ -35,7 +35,8 @@ for (const auto &dirEntry : dirList) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
//! [2]
|
//! [2]
|
||||||
QDirListing audioFileIt(u"/home/johndoe/"_s, {"*.mp3", "*.wav"}, QDir::Files);
|
QDirListing audioFileIt(u"/home/johndoe/"_s, QStringList{u"*.mp3"_s, u"*.wav"_s},
|
||||||
|
QDirListing::IteratorFlag::FilesOnly);
|
||||||
//! [2]
|
//! [2]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +590,21 @@ bool QAbstractFileEngine::isRelativePath() const
|
|||||||
\sa setFileName()
|
\sa setFileName()
|
||||||
*/
|
*/
|
||||||
QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
|
QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
#ifdef QT_BOOTSTRAPPED
|
||||||
|
Q_UNUSED(filters);
|
||||||
|
Q_UNUSED(filterNames);
|
||||||
|
Q_UNREACHABLE_RETURN(ret);
|
||||||
|
#else
|
||||||
|
for (const auto &dirEntry : QDirListing(fileName(), filterNames, filters.toInt()))
|
||||||
|
ret.emplace_back(dirEntry.fileName());
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QAbstractFileEngine::entryList(QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames) const
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
#ifdef QT_BOOTSTRAPPED
|
#ifdef QT_BOOTSTRAPPED
|
||||||
@ -902,6 +917,15 @@ QAbstractFileEngineIterator::QAbstractFileEngineIterator(const QString &path, QD
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractFileEngineIterator::QAbstractFileEngineIterator(const QString &path,
|
||||||
|
QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &nameFilters)
|
||||||
|
: m_listingFilters(filters),
|
||||||
|
m_nameFilters(nameFilters),
|
||||||
|
m_path(appendSlashIfNeeded(path))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Destroys the QAbstractFileEngineIterator.
|
Destroys the QAbstractFileEngineIterator.
|
||||||
|
|
||||||
@ -1017,6 +1041,16 @@ QAbstractFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractFileEngine::IteratorUniquePtr
|
||||||
|
QAbstractFileEngine::beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames)
|
||||||
|
{
|
||||||
|
Q_UNUSED(path);
|
||||||
|
Q_UNUSED(filters);
|
||||||
|
Q_UNUSED(filterNames);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Reads a number of characters from the file into \a data. At most
|
Reads a number of characters from the file into \a data. At most
|
||||||
\a maxlen characters will be read.
|
\a maxlen characters will be read.
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <QtCore/private/qglobal_p.h>
|
#include <QtCore/private/qglobal_p.h>
|
||||||
#include "QtCore/qfile.h"
|
#include "QtCore/qfile.h"
|
||||||
#include "QtCore/qdir.h"
|
#include "QtCore/qdir.h"
|
||||||
|
#include "QtCore/qdirlisting.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -106,6 +107,8 @@ public:
|
|||||||
virtual bool caseSensitive() const;
|
virtual bool caseSensitive() const;
|
||||||
virtual bool isRelativePath() const;
|
virtual bool isRelativePath() const;
|
||||||
virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
|
virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
|
||||||
|
virtual QStringList entryList(QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames) const;
|
||||||
virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const;
|
virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const;
|
||||||
virtual bool setPermissions(uint perms);
|
virtual bool setPermissions(uint perms);
|
||||||
virtual QByteArray id() const;
|
virtual QByteArray id() const;
|
||||||
@ -128,6 +131,10 @@ public:
|
|||||||
beginEntryList(const QString &path, QDir::Filters filters, const QStringList &filterNames);
|
beginEntryList(const QString &path, QDir::Filters filters, const QStringList &filterNames);
|
||||||
virtual IteratorUniquePtr endEntryList() { return {}; }
|
virtual IteratorUniquePtr endEntryList() { return {}; }
|
||||||
|
|
||||||
|
virtual IteratorUniquePtr
|
||||||
|
beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames);
|
||||||
|
|
||||||
virtual qint64 read(char *data, qint64 maxlen);
|
virtual qint64 read(char *data, qint64 maxlen);
|
||||||
virtual qint64 readLine(char *data, qint64 maxlen);
|
virtual qint64 readLine(char *data, qint64 maxlen);
|
||||||
virtual qint64 write(const char *data, qint64 len);
|
virtual qint64 write(const char *data, qint64 len);
|
||||||
@ -203,6 +210,8 @@ class Q_CORE_EXPORT QAbstractFileEngineIterator
|
|||||||
public:
|
public:
|
||||||
QAbstractFileEngineIterator(const QString &path, QDir::Filters filters,
|
QAbstractFileEngineIterator(const QString &path, QDir::Filters filters,
|
||||||
const QStringList &nameFilters);
|
const QStringList &nameFilters);
|
||||||
|
QAbstractFileEngineIterator(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &nameFilters);
|
||||||
virtual ~QAbstractFileEngineIterator();
|
virtual ~QAbstractFileEngineIterator();
|
||||||
|
|
||||||
virtual bool advance() = 0;
|
virtual bool advance() = 0;
|
||||||
@ -225,6 +234,7 @@ private:
|
|||||||
friend class QDirListingPrivate;
|
friend class QDirListingPrivate;
|
||||||
|
|
||||||
QDir::Filters m_filters;
|
QDir::Filters m_filters;
|
||||||
|
QDirListing::IteratorFlags m_listingFilters;
|
||||||
QStringList m_nameFilters;
|
QStringList m_nameFilters;
|
||||||
QString m_path;
|
QString m_path;
|
||||||
};
|
};
|
||||||
|
@ -347,8 +347,10 @@ inline void QDirPrivate::initFileLists(const QDir &dir) const
|
|||||||
QMutexLocker locker(&fileCache.mutex);
|
QMutexLocker locker(&fileCache.mutex);
|
||||||
if (!fileCache.fileListsInitialized) {
|
if (!fileCache.fileListsInitialized) {
|
||||||
QFileInfoList l;
|
QFileInfoList l;
|
||||||
for (const auto &dirEntry : QDirListing(dir))
|
for (const auto &dirEntry : QDirListing(dir.path(), dir.nameFilters(),
|
||||||
|
dir.filter().toInt())) {
|
||||||
l.emplace_back(dirEntry.fileInfo());
|
l.emplace_back(dirEntry.fileInfo());
|
||||||
|
}
|
||||||
|
|
||||||
sortFileList(sort, l, &fileCache.files, &fileCache.fileInfos);
|
sortFileList(sort, l, &fileCache.files, &fileCache.fileInfos);
|
||||||
fileCache.fileListsInitialized = true;
|
fileCache.fileListsInitialized = true;
|
||||||
@ -1427,7 +1429,7 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDirListing dirList(d->dirEntry.filePath(), nameFilters, filters);
|
QDirListing dirList(d->dirEntry.filePath(), nameFilters, filters.toInt());
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
if (needsSorting) {
|
if (needsSorting) {
|
||||||
QFileInfoList l;
|
QFileInfoList l;
|
||||||
@ -1473,7 +1475,7 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter
|
|||||||
}
|
}
|
||||||
|
|
||||||
QFileInfoList l;
|
QFileInfoList l;
|
||||||
for (const auto &dirEntry : QDirListing(d->dirEntry.filePath(), nameFilters, filters))
|
for (const auto &dirEntry : QDirListing(d->dirEntry.filePath(), nameFilters, filters.toInt()))
|
||||||
l.emplace_back(dirEntry.fileInfo());
|
l.emplace_back(dirEntry.fileInfo());
|
||||||
QFileInfoList ret;
|
QFileInfoList ret;
|
||||||
d->sortFileList(sort, l, nullptr, &ret);
|
d->sortFileList(sort, l, nullptr, &ret);
|
||||||
@ -1645,8 +1647,7 @@ bool QDir::removeRecursively()
|
|||||||
bool success = true;
|
bool success = true;
|
||||||
const QString dirPath = path();
|
const QString dirPath = path();
|
||||||
// not empty -- we must empty it first
|
// not empty -- we must empty it first
|
||||||
constexpr auto dirFilters = QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot;
|
for (const auto &dirEntry : QDirListing(dirPath, QDirListing::IteratorFlag::IncludeHidden)) {
|
||||||
for (const auto &dirEntry : QDirListing(dirPath, dirFilters)) {
|
|
||||||
const QString &filePath = dirEntry.filePath();
|
const QString &filePath = dirEntry.filePath();
|
||||||
bool ok;
|
bool ok;
|
||||||
if (dirEntry.isDir() && !dirEntry.isSymLink()) {
|
if (dirEntry.isDir() && !dirEntry.isSymLink()) {
|
||||||
@ -1969,7 +1970,7 @@ bool QDir::exists(const QString &name) const
|
|||||||
bool QDir::isEmpty(Filters filters) const
|
bool QDir::isEmpty(Filters filters) const
|
||||||
{
|
{
|
||||||
Q_D(const QDir);
|
Q_D(const QDir);
|
||||||
QDirListing dirList(d->dirEntry.filePath(), d->nameFilters, filters);
|
QDirListing dirList(d->dirEntry.filePath(), d->nameFilters, filters.toInt());
|
||||||
return dirList.cbegin() == dirList.cend();
|
return dirList.cbegin() == dirList.cend();
|
||||||
}
|
}
|
||||||
#endif // !QT_BOOTSTRAPPED
|
#endif // !QT_BOOTSTRAPPED
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <QtCore/qcompare.h>
|
#include <QtCore/qcompare.h>
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
|
#include <QtCore/qdirlisting.h>
|
||||||
#include <QtCore/qfile.h>
|
#include <QtCore/qfile.h>
|
||||||
#include <QtCore/qfileinfo.h>
|
#include <QtCore/qfileinfo.h>
|
||||||
#include <QtCore/qstringlist.h>
|
#include <QtCore/qstringlist.h>
|
||||||
@ -244,6 +245,7 @@ private:
|
|||||||
Q_DECLARE_EQUALITY_COMPARABLE(QDir)
|
Q_DECLARE_EQUALITY_COMPARABLE(QDir)
|
||||||
friend class QDirIterator;
|
friend class QDirIterator;
|
||||||
friend class QDirListing;
|
friend class QDirListing;
|
||||||
|
friend class QDirListingPrivate;
|
||||||
// Q_DECLARE_PRIVATE equivalent for shared data pointers
|
// Q_DECLARE_PRIVATE equivalent for shared data pointers
|
||||||
QDirPrivate *d_func();
|
QDirPrivate *d_func();
|
||||||
const QDirPrivate *d_func() const { return d_ptr.constData(); }
|
const QDirPrivate *d_func() const { return d_ptr.constData(); }
|
||||||
|
@ -86,44 +86,12 @@ using namespace Qt::StringLiterals;
|
|||||||
|
|
||||||
class QDirIteratorPrivate
|
class QDirIteratorPrivate
|
||||||
{
|
{
|
||||||
static QDirListing::IteratorFlags toDirListingFlags(QDirIterator::IteratorFlags flags)
|
|
||||||
{
|
|
||||||
using F = QDirListing::IteratorFlag;
|
|
||||||
QDirListing::IteratorFlags listerFlags;
|
|
||||||
|
|
||||||
if (flags & QDirIterator::NoIteratorFlags)
|
|
||||||
listerFlags.setFlag(F::NoFlag);
|
|
||||||
if (flags & QDirIterator::FollowSymlinks)
|
|
||||||
listerFlags.setFlag(F::FollowSymlinks);
|
|
||||||
if (flags & QDirIterator::Subdirectories)
|
|
||||||
listerFlags.setFlag(F::Recursive);
|
|
||||||
|
|
||||||
return listerFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QDirIteratorPrivate(const QDir &dir, QDirIterator::IteratorFlags flags)
|
QDirIteratorPrivate(const QString &path, const QStringList &nameFilters = {},
|
||||||
: lister(dir, toDirListingFlags(flags))
|
QDir::Filters filters = QDir::NoFilter,
|
||||||
{
|
QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags)
|
||||||
init();
|
: lister(path, nameFilters, filters.toInt(), flags.toInt())
|
||||||
}
|
{ init(); }
|
||||||
QDirIteratorPrivate(const QString &path, QDirIterator::IteratorFlags flags)
|
|
||||||
: lister(path, toDirListingFlags(flags))
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
QDirIteratorPrivate(const QString &path, QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags)
|
|
||||||
: lister(path, filters, toDirListingFlags(flags))
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters,
|
|
||||||
QDirIterator::IteratorFlags flags)
|
|
||||||
: lister(path, nameFilters, filters, toDirListingFlags(flags))
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
@ -162,7 +130,7 @@ public:
|
|||||||
\sa hasNext(), next(), IteratorFlags
|
\sa hasNext(), next(), IteratorFlags
|
||||||
*/
|
*/
|
||||||
QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
|
QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
|
||||||
: d(new QDirIteratorPrivate(dir, flags))
|
: d(new QDirIteratorPrivate(dir.path(), dir.nameFilters(), dir.filter(), flags))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +148,7 @@ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
|
|||||||
\sa hasNext(), next(), IteratorFlags
|
\sa hasNext(), next(), IteratorFlags
|
||||||
*/
|
*/
|
||||||
QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags)
|
QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags)
|
||||||
: d(new QDirIteratorPrivate(path, filters, flags))
|
: d(new QDirIteratorPrivate(path, {}, filters, flags))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +165,7 @@ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorF
|
|||||||
\sa hasNext(), next(), IteratorFlags
|
\sa hasNext(), next(), IteratorFlags
|
||||||
*/
|
*/
|
||||||
QDirIterator::QDirIterator(const QString &path, IteratorFlags flags)
|
QDirIterator::QDirIterator(const QString &path, IteratorFlags flags)
|
||||||
: d(new QDirIteratorPrivate(path, flags))
|
: d(new QDirIteratorPrivate(path, {}, QDir::NoFilter, flags))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
directory contents recursively, and following symbolic links. Unlike
|
directory contents recursively, and following symbolic links. Unlike
|
||||||
QDir::entryList(), QDirListing does not support sorting.
|
QDir::entryList(), QDirListing does not support sorting.
|
||||||
|
|
||||||
The QDirListing constructor takes a QDir or a directory path as
|
The QDirListing constructor takes a directory path string as
|
||||||
argument. Here's how to iterate over all entries recursively:
|
argument. Here's how to iterate over all entries recursively:
|
||||||
|
|
||||||
\snippet code/src_corelib_io_qdirlisting.cpp 0
|
\snippet code/src_corelib_io_qdirlisting.cpp 0
|
||||||
@ -45,24 +45,73 @@
|
|||||||
|
|
||||||
/*! \enum QDirListing::IteratorFlag
|
/*! \enum QDirListing::IteratorFlag
|
||||||
|
|
||||||
This enum class describes flags can be used to configure the behavior of
|
This enum class describes flags that can be used to configure the behavior
|
||||||
QDirListing. These flags can be bitwise OR'ed together.
|
of QDirListing. Values from this enumerator can be bitwise OR'ed together.
|
||||||
|
|
||||||
\value NoFlag The default value, representing no flags. The iterator
|
\value Default
|
||||||
will return entries for the assigned path.
|
List all files, directories and symbolic links, including broken
|
||||||
|
symlinks (where the target doesn't exist).
|
||||||
|
Hidden files and directories and the special entries \c{.} and \c{..}
|
||||||
|
aren't listed by default.
|
||||||
|
|
||||||
\value FollowSymlinks When combined with Recursive, this flag enables
|
\value ExcludeFiles
|
||||||
iterating through all subdirectories of the assigned path, following
|
Don't list regular files. When combined with ResolveSymlinks, symbolic
|
||||||
all symbolic links. Symbolic link loops (e.g., link => . or link =>
|
links to regular files will be excluded too.
|
||||||
..) are automatically detected and ignored.
|
|
||||||
|
|
||||||
\value Recursive List entries inside all subdirectories as well.
|
\value ExcludeDirs
|
||||||
|
Don't list directories. When combined with ResolveSymlinks, symbolic
|
||||||
|
links to directories will be excluded too.
|
||||||
|
|
||||||
|
\value ExcludeSpecial
|
||||||
|
Don't list special system files:
|
||||||
|
\list
|
||||||
|
\li On Unix: an entry that is not a directory, regular file or
|
||||||
|
symbolic link (including broken symlinks). That is, FIFO,
|
||||||
|
socket, character device, or block device.
|
||||||
|
\li On Windows: \c {.lnk}.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\value ResolveSymlinks
|
||||||
|
Filter symbolic links based on the type of the target of the link,
|
||||||
|
rather than the symbolic link itself. With this flag, broken symbolic
|
||||||
|
links (where the target doesn't exist) are excluded. This flag is
|
||||||
|
ignored on operating systems that don't support symbolic links.
|
||||||
|
|
||||||
|
\value FilesOnly
|
||||||
|
Only regular files will be listed. When combined with ResolveSymlinks,
|
||||||
|
symbolic links to files will also be listed.
|
||||||
|
|
||||||
|
\value DirsOnly
|
||||||
|
Only directories will be listed. When combined with ResolveSymlinks,
|
||||||
|
symbolic links to directories will also be listed.
|
||||||
|
|
||||||
|
\value IncludeHidden
|
||||||
|
List hidden entries. When combined with Recursive, the iteration will
|
||||||
|
recurse into hidden sub-directories as well.
|
||||||
|
|
||||||
|
\value IncludeDotAndDotDot
|
||||||
|
List the \c {.} and \c{..} special entries.
|
||||||
|
|
||||||
|
\value CaseSensitive
|
||||||
|
The file glob patterns in the name filters passed to the QDirListing
|
||||||
|
constructor, will be matched case sensitively (for details, see
|
||||||
|
QDir::setNameFilters()).
|
||||||
|
|
||||||
|
\value Recursive
|
||||||
|
List entries inside all sub-directories as well. When combined with
|
||||||
|
FollowDirSymlinks, symbolic links to directories will be iterated too.
|
||||||
|
|
||||||
|
\value FollowDirSymlinks
|
||||||
|
When combined with Recursive, symbolic links to directories will be
|
||||||
|
iterated too. Symbolic link loops (e.g., link => . or link => ..) are
|
||||||
|
automatically detected and ignored.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qdirlisting.h"
|
#include "qdirlisting.h"
|
||||||
#include "qdirentryinfo_p.h"
|
#include "qdirentryinfo_p.h"
|
||||||
|
|
||||||
#include "qdir_p.h"
|
#include "qdir_p.h"
|
||||||
|
#include "qdiriterator.h"
|
||||||
#include "qabstractfileengine_p.h"
|
#include "qabstractfileengine_p.h"
|
||||||
|
|
||||||
#include <QtCore/qset.h>
|
#include <QtCore/qset.h>
|
||||||
@ -85,6 +134,21 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
|
static QDirListing::IteratorFlags toDirListingFlags(QDirIterator::IteratorFlags flags)
|
||||||
|
{
|
||||||
|
using F = QDirListing::IteratorFlag;
|
||||||
|
QDirListing::IteratorFlags listerFlags;
|
||||||
|
|
||||||
|
if (flags & QDirIterator::NoIteratorFlags)
|
||||||
|
listerFlags.setFlag(F::Default);
|
||||||
|
if (flags & QDirIterator::FollowSymlinks)
|
||||||
|
listerFlags.setFlag(F::FollowDirSymlinks);
|
||||||
|
if (flags & QDirIterator::Subdirectories)
|
||||||
|
listerFlags.setFlag(F::Recursive);
|
||||||
|
|
||||||
|
return listerFlags;
|
||||||
|
}
|
||||||
|
|
||||||
class QDirListingPrivate
|
class QDirListingPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -100,15 +164,32 @@ public:
|
|||||||
bool matchesFilters(QDirEntryInfo &data) const;
|
bool matchesFilters(QDirEntryInfo &data) const;
|
||||||
bool hasIterators() const;
|
bool hasIterators() const;
|
||||||
|
|
||||||
|
bool matchesLegacyFilters(QDirEntryInfo &data) const;
|
||||||
|
void setLegacyFilters(QDir::Filters dirFilters, QDirIterator::IteratorFlags dirIteratorFlags)
|
||||||
|
{
|
||||||
|
useLegacyFilters = true;
|
||||||
|
legacyDirFilters = dirFilters;
|
||||||
|
iteratorFlags = toDirListingFlags(dirIteratorFlags);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<QAbstractFileEngine> engine;
|
std::unique_ptr<QAbstractFileEngine> engine;
|
||||||
QDirEntryInfo initialEntryInfo;
|
QDirEntryInfo initialEntryInfo;
|
||||||
QStringList nameFilters;
|
QStringList nameFilters;
|
||||||
QDir::Filters filters;
|
|
||||||
QDirListing::IteratorFlags iteratorFlags;
|
QDirListing::IteratorFlags iteratorFlags;
|
||||||
QDirEntryInfo currentEntryInfo;
|
QDirEntryInfo currentEntryInfo;
|
||||||
|
|
||||||
|
bool useLegacyFilters = false;
|
||||||
|
QDir::Filters legacyDirFilters;
|
||||||
|
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
QList<QRegularExpression> nameRegExps;
|
QList<QRegularExpression> nameRegExps;
|
||||||
|
bool regexMatchesName(const QString &fileName) const
|
||||||
|
{
|
||||||
|
if (nameRegExps.isEmpty())
|
||||||
|
return true;
|
||||||
|
auto hasMatch = [&fileName](const auto &re) { return re.match(fileName).hasMatch(); };
|
||||||
|
return std::any_of(nameRegExps.cbegin(), nameRegExps.cend(), hasMatch);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using FEngineIteratorPtr = std::unique_ptr<QAbstractFileEngineIterator>;
|
using FEngineIteratorPtr = std::unique_ptr<QAbstractFileEngineIterator>;
|
||||||
@ -127,13 +208,21 @@ void QDirListingPrivate::init(bool resolveEngine = true)
|
|||||||
if (nameFilters.contains("*"_L1))
|
if (nameFilters.contains("*"_L1))
|
||||||
nameFilters.clear();
|
nameFilters.clear();
|
||||||
|
|
||||||
if (filters == QDir::NoFilter)
|
if (useLegacyFilters) {
|
||||||
filters = QDir::AllEntries;
|
if (legacyDirFilters == QDir::NoFilter)
|
||||||
|
legacyDirFilters = QDir::AllEntries;
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
nameRegExps.reserve(nameFilters.size());
|
nameRegExps.reserve(nameFilters.size());
|
||||||
const auto cs = filters.testAnyFlags(QDir::CaseSensitive) ? Qt::CaseSensitive
|
|
||||||
: Qt::CaseInsensitive;
|
const bool isCase = [this] {
|
||||||
|
if (useLegacyFilters)
|
||||||
|
return legacyDirFilters.testAnyFlags(QDir::CaseSensitive);
|
||||||
|
return iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::CaseSensitive);
|
||||||
|
}();
|
||||||
|
|
||||||
|
const auto cs = isCase ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||||
for (const auto &filter : nameFilters)
|
for (const auto &filter : nameFilters)
|
||||||
nameRegExps.emplace_back(QRegularExpression::fromWildcard(filter, cs));
|
nameRegExps.emplace_back(QRegularExpression::fromWildcard(filter, cs));
|
||||||
#endif
|
#endif
|
||||||
@ -171,7 +260,7 @@ void QDirListingPrivate::pushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
||||||
if (iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::FollowSymlinks)) {
|
if (iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::FollowDirSymlinks)) {
|
||||||
// Stop link loops
|
// Stop link loops
|
||||||
if (visitedLinks.hasSeen(entryInfo.canonicalFilePath()))
|
if (visitedLinks.hasSeen(entryInfo.canonicalFilePath()))
|
||||||
return;
|
return;
|
||||||
@ -179,7 +268,7 @@ void QDirListingPrivate::pushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
|
|
||||||
if (engine) {
|
if (engine) {
|
||||||
engine->setFileName(path);
|
engine->setFileName(path);
|
||||||
if (auto it = engine->beginEntryList(path, filters, nameFilters)) {
|
if (auto it = engine->beginEntryList(path, iteratorFlags, nameFilters)) {
|
||||||
fileEngineIterators.emplace_back(std::move(it));
|
fileEngineIterators.emplace_back(std::move(it));
|
||||||
} else {
|
} else {
|
||||||
// No iterator; no entry list.
|
// No iterator; no entry list.
|
||||||
@ -191,7 +280,7 @@ void QDirListingPrivate::pushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
fentry = &entryInfo.fileInfoOpt->d_ptr->fileEntry;
|
fentry = &entryInfo.fileInfoOpt->d_ptr->fileEntry;
|
||||||
else
|
else
|
||||||
fentry = &entryInfo.entry;
|
fentry = &entryInfo.entry;
|
||||||
nativeIterators.emplace_back(std::make_unique<QFileSystemIterator>(*fentry, filters));
|
nativeIterators.emplace_back(std::make_unique<QFileSystemIterator>(*fentry, iteratorFlags));
|
||||||
#else
|
#else
|
||||||
qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
|
qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
|
||||||
#endif
|
#endif
|
||||||
@ -201,6 +290,8 @@ void QDirListingPrivate::pushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
bool QDirListingPrivate::entryMatches(QDirEntryInfo &entryInfo)
|
bool QDirListingPrivate::entryMatches(QDirEntryInfo &entryInfo)
|
||||||
{
|
{
|
||||||
checkAndPushDirectory(entryInfo);
|
checkAndPushDirectory(entryInfo);
|
||||||
|
if (useLegacyFilters)
|
||||||
|
return matchesLegacyFilters(entryInfo);
|
||||||
return matchesFilters(entryInfo);
|
return matchesFilters(entryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +351,11 @@ void QDirListingPrivate::advance()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isDotOrDotDot(QStringView fileName)
|
||||||
|
{
|
||||||
|
return fileName == "."_L1 || fileName == ".."_L1;
|
||||||
|
}
|
||||||
|
|
||||||
void QDirListingPrivate::checkAndPushDirectory(QDirEntryInfo &entryInfo)
|
void QDirListingPrivate::checkAndPushDirectory(QDirEntryInfo &entryInfo)
|
||||||
{
|
{
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
@ -272,16 +368,20 @@ void QDirListingPrivate::checkAndPushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Follow symlinks only when asked
|
// Follow symlinks only when asked
|
||||||
if (!iteratorFlags.testAnyFlags(F::FollowSymlinks) && entryInfo.isSymLink())
|
if (!iteratorFlags.testAnyFlags(F::FollowDirSymlinks) && entryInfo.isSymLink())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Never follow . and ..
|
// Never follow . and ..
|
||||||
const QString &fileName = entryInfo.fileName();
|
if (isDotOrDotDot(entryInfo.fileName()))
|
||||||
if ("."_L1 == fileName || ".."_L1 == fileName)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// No hidden directories unless requested
|
// No hidden directories unless requested
|
||||||
if (!filters.testAnyFlags(QDir::AllDirs | QDir::Hidden) && entryInfo.isHidden())
|
const bool includeHidden = [this]() {
|
||||||
|
if (useLegacyFilters)
|
||||||
|
return legacyDirFilters.testAnyFlags(QDir::AllDirs | QDir::Hidden);
|
||||||
|
return iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::IncludeHidden);
|
||||||
|
}();
|
||||||
|
if (!includeHidden && entryInfo.isHidden())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pushDirectory(entryInfo);
|
pushDirectory(entryInfo);
|
||||||
@ -290,21 +390,21 @@ void QDirListingPrivate::checkAndPushDirectory(QDirEntryInfo &entryInfo)
|
|||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
This functions returns \c true if the current entry matches the filters
|
Works the same as matchesFilters() but for the old QDir::Filters.
|
||||||
(i.e., the current entry will be returned as part of the directory
|
|
||||||
iteration); otherwise, \c false is returned.
|
|
||||||
*/
|
*/
|
||||||
bool QDirListingPrivate::matchesFilters(QDirEntryInfo &entryInfo) const
|
bool QDirListingPrivate::matchesLegacyFilters(QDirEntryInfo &entryInfo) const
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(useLegacyFilters);
|
||||||
|
|
||||||
const QString &fileName = entryInfo.fileName();
|
const QString &fileName = entryInfo.fileName();
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto &filters = legacyDirFilters;
|
||||||
|
|
||||||
// filter . and ..?
|
// filter . and ..?
|
||||||
|
const bool dotOrDotDot = isDotOrDotDot(fileName);
|
||||||
const qsizetype fileNameSize = fileName.size();
|
const qsizetype fileNameSize = fileName.size();
|
||||||
const bool dotOrDotDot = fileName[0] == u'.'
|
|
||||||
&& ((fileNameSize == 1)
|
|
||||||
||(fileNameSize == 2 && fileName[1] == u'.'));
|
|
||||||
if ((filters & QDir::NoDot) && dotOrDotDot && fileNameSize == 1)
|
if ((filters & QDir::NoDot) && dotOrDotDot && fileNameSize == 1)
|
||||||
return false;
|
return false;
|
||||||
if ((filters & QDir::NoDotDot) && dotOrDotDot && fileNameSize == 2)
|
if ((filters & QDir::NoDotDot) && dotOrDotDot && fileNameSize == 2)
|
||||||
@ -313,11 +413,8 @@ bool QDirListingPrivate::matchesFilters(QDirEntryInfo &entryInfo) const
|
|||||||
// name filter
|
// name filter
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
// Pass all entries through name filters, except dirs if AllDirs is set
|
// Pass all entries through name filters, except dirs if AllDirs is set
|
||||||
if (!nameRegExps.isEmpty() && !(filters.testAnyFlags(QDir::AllDirs) && entryInfo.isDir())) {
|
if (!(filters.testAnyFlags(QDir::AllDirs) && entryInfo.isDir())) {
|
||||||
auto regexMatchesName = [&fileName](const auto &re) {
|
if (!regexMatchesName(fileName))
|
||||||
return re.match(fileName).hasMatch();
|
|
||||||
};
|
|
||||||
if (std::none_of(nameRegExps.cbegin(), nameRegExps.cend(), regexMatchesName))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -371,6 +468,59 @@ bool QDirListingPrivate::matchesFilters(QDirEntryInfo &entryInfo) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
This function returns \c true if the current entry matches the filters
|
||||||
|
(i.e., the current entry will be returned as part of the directory
|
||||||
|
iteration); otherwise, \c false is returned.
|
||||||
|
*/
|
||||||
|
bool QDirListingPrivate::matchesFilters(QDirEntryInfo &entryInfo) const
|
||||||
|
{
|
||||||
|
using F = QDirListing::IteratorFlag;
|
||||||
|
|
||||||
|
const QString &fileName = entryInfo.fileName();
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isDotOrDotDot(fileName)) // All done, other checks below don't matter in this case
|
||||||
|
return iteratorFlags.testAnyFlags(F::IncludeDotAndDotDot);
|
||||||
|
|
||||||
|
// name filter
|
||||||
|
#if QT_CONFIG(regularexpression)
|
||||||
|
if (!regexMatchesName(fileName))
|
||||||
|
return false;
|
||||||
|
#endif // QT_CONFIG(regularexpression)
|
||||||
|
|
||||||
|
if (!iteratorFlags.testAnyFlag(F::IncludeHidden) && entryInfo.isHidden())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (entryInfo.isSymLink()) {
|
||||||
|
// With ResolveSymlinks, we look at the type of the link's target,
|
||||||
|
// and exclude broken symlinks (where the target doesn't exist).
|
||||||
|
if (iteratorFlags.testAnyFlag(F::ResolveSymlinks)) {
|
||||||
|
if (!entryInfo.exists())
|
||||||
|
return false;
|
||||||
|
} else if (iteratorFlags.testAnyFlags(F::FilesOnly)
|
||||||
|
|| iteratorFlags.testAnyFlags(F::DirsOnly)) {
|
||||||
|
return false; // symlink is not a file or dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iteratorFlags.testAnyFlag(F::ExcludeSpecial)
|
||||||
|
&& !entryInfo.isFile() && !entryInfo.isDir() && !entryInfo.isSymLink()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iteratorFlags.testAnyFlags(F::ExcludeDirs) && entryInfo.isDir())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (iteratorFlags.testAnyFlags(F::ExcludeFiles) && entryInfo.isFile())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool QDirListingPrivate::hasIterators() const
|
bool QDirListingPrivate::hasIterators() const
|
||||||
{
|
{
|
||||||
if (engine)
|
if (engine)
|
||||||
@ -384,60 +534,12 @@ bool QDirListingPrivate::hasIterators() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a QDirListing that can iterate over \a dir's entries, using
|
Constructs a QDirListing that can iterate over \a path.
|
||||||
\a dir's name filters and the QDir::Filters set in \a dir. You can pass
|
|
||||||
options via \a flags to decide how the directory should be iterated.
|
|
||||||
|
|
||||||
By default, \a flags is NoIteratorFlags, which provides the same behavior
|
You can pass options via \a flags to control how the directory should
|
||||||
as in QDir::entryList().
|
be iterated.
|
||||||
|
|
||||||
The sorting in \a dir is ignored.
|
By default, \a flags is IteratorFlag::Default.
|
||||||
|
|
||||||
\note To list symlinks that point to non existing files, QDir::System
|
|
||||||
must be set in \a dir's QDir::Filters.
|
|
||||||
|
|
||||||
\sa IteratorFlags
|
|
||||||
*/
|
|
||||||
QDirListing::QDirListing(const QDir &dir, IteratorFlags flags)
|
|
||||||
: d(new QDirListingPrivate)
|
|
||||||
{
|
|
||||||
const QDirPrivate *other = dir.d_ptr.constData();
|
|
||||||
d->initialEntryInfo.entry = other->dirEntry;
|
|
||||||
d->nameFilters = other->nameFilters;
|
|
||||||
d->filters = other->filters;
|
|
||||||
d->iteratorFlags = flags;
|
|
||||||
const bool resolveEngine = other->fileEngine ? true : false;
|
|
||||||
d->init(resolveEngine);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Constructs a QDirListing that can iterate over \a path. Entries are
|
|
||||||
filtered according to \a filters. You can pass options via \a flags to
|
|
||||||
decide how the directory should be iterated.
|
|
||||||
|
|
||||||
By default, \a filters is QDir::NoFilter, and \a flags is NoIteratorFlags,
|
|
||||||
which provides the same behavior as in QDir::entryList().
|
|
||||||
|
|
||||||
\note To list symlinks that point to non existing files, QDir::System
|
|
||||||
must be set in \a filters.
|
|
||||||
|
|
||||||
\sa IteratorFlags
|
|
||||||
*/
|
|
||||||
QDirListing::QDirListing(const QString &path, QDir::Filters filters, IteratorFlags flags)
|
|
||||||
: d(new QDirListingPrivate)
|
|
||||||
{
|
|
||||||
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
|
||||||
d->filters = filters;
|
|
||||||
d->iteratorFlags = flags;
|
|
||||||
d->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Constructs a QDirListing that can iterate over \a path. You can pass
|
|
||||||
options via \a flags to decide how the directory should be iterated.
|
|
||||||
|
|
||||||
By default, \a flags is NoIteratorFlags, which provides the same behavior
|
|
||||||
as in QDir::entryList().
|
|
||||||
|
|
||||||
\sa IteratorFlags
|
\sa IteratorFlags
|
||||||
*/
|
*/
|
||||||
@ -445,40 +547,57 @@ QDirListing::QDirListing(const QString &path, IteratorFlags flags)
|
|||||||
: d(new QDirListingPrivate)
|
: d(new QDirListingPrivate)
|
||||||
{
|
{
|
||||||
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
||||||
d->filters = QDir::NoFilter;
|
|
||||||
d->iteratorFlags = flags;
|
d->iteratorFlags = flags;
|
||||||
d->init();
|
d->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Constructs a QDirListing that can iterate over \a path, using \a
|
Constructs a QDirListing that can iterate over \a path.
|
||||||
nameFilters and \a filters. You can pass options via \a flags to decide
|
|
||||||
how the directory should be iterated.
|
|
||||||
|
|
||||||
By default, \a flags is NoIteratorFlags, which provides the same behavior
|
You can pass options via \a flags to control how the directory should
|
||||||
as QDir::entryList().
|
be iterated. By default, \a flags is IteratorFlag::Default.
|
||||||
|
|
||||||
|
The listed entries will be filtered according to the file glob patterns
|
||||||
|
in \a nameFilters (see QDir::setNameFilters() for more details).
|
||||||
|
|
||||||
For example, the following iterator could be used to iterate over audio
|
For example, the following iterator could be used to iterate over audio
|
||||||
files:
|
files:
|
||||||
|
|
||||||
\snippet code/src_corelib_io_qdirlisting.cpp 2
|
\snippet code/src_corelib_io_qdirlisting.cpp 2
|
||||||
|
|
||||||
\note To list symlinks that point to non existing files, QDir::System
|
|
||||||
must be set in \a flags.
|
|
||||||
|
|
||||||
\sa IteratorFlags, QDir::setNameFilters()
|
\sa IteratorFlags, QDir::setNameFilters()
|
||||||
*/
|
*/
|
||||||
QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, QDir::Filters filters,
|
QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, IteratorFlags flags)
|
||||||
IteratorFlags flags)
|
|
||||||
: d(new QDirListingPrivate)
|
: d(new QDirListingPrivate)
|
||||||
{
|
{
|
||||||
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
||||||
d->nameFilters = nameFilters;
|
d->nameFilters = nameFilters;
|
||||||
d->filters = filters;
|
|
||||||
d->iteratorFlags = flags;
|
d->iteratorFlags = flags;
|
||||||
d->init();
|
d->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Only used by classes that still have to use QDir::Filters; for example,
|
||||||
|
QDir, such usage may be deprecated at some point.
|
||||||
|
|
||||||
|
\a qdirFilters is converted to QDir::Filters and \a qdirIteratorFlags is
|
||||||
|
converted to QDirIterator::IteratorFlags (qdirlisting.h can't include
|
||||||
|
qdir.h or qdiriterator.h) and used to control the filtering of the
|
||||||
|
dir entries.
|
||||||
|
*/
|
||||||
|
QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, uint qdirFilters,
|
||||||
|
uint qdirIteratorFlags)
|
||||||
|
: d(new QDirListingPrivate)
|
||||||
|
{
|
||||||
|
d->initialEntryInfo.entry = QFileSystemEntry(path);
|
||||||
|
d->nameFilters = nameFilters;
|
||||||
|
d->setLegacyFilters(QDir::Filters::fromInt(qdirFilters),
|
||||||
|
QDirIterator::IteratorFlags::fromInt(qdirIteratorFlags));
|
||||||
|
d->init();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Move constructor. Moves \a other into this QDirListing.
|
Move constructor. Moves \a other into this QDirListing.
|
||||||
|
|
||||||
@ -497,6 +616,7 @@ QDirListing::QDirListing(QDirListing &&other) = default;
|
|||||||
*/
|
*/
|
||||||
QDirListing &QDirListing::operator=(QDirListing &&other) = default;
|
QDirListing &QDirListing::operator=(QDirListing &&other) = default;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Destroys the QDirListing.
|
Destroys the QDirListing.
|
||||||
*/
|
*/
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
#ifndef QDILISTING_H
|
#ifndef QDILISTING_H
|
||||||
#define QDILISTING_H
|
#define QDILISTING_H
|
||||||
|
|
||||||
#include <QtCore/qdir.h>
|
#include <QtCore/qfiledevice.h>
|
||||||
|
#include <QtCore/qflags.h>
|
||||||
|
#include <QtCore/qtclasshelpermacros.h>
|
||||||
|
#include <QtCore/qtcoreexports.h>
|
||||||
|
#include <QtCore/qdatetime.h>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -13,24 +17,32 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QDirListingPrivate;
|
class QDirListingPrivate;
|
||||||
|
class QFileInfo;
|
||||||
|
class QDir;
|
||||||
|
class QTimeZone;
|
||||||
|
|
||||||
class Q_CORE_EXPORT QDirListing
|
class Q_CORE_EXPORT QDirListing
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class IteratorFlag {
|
enum class IteratorFlag {
|
||||||
NoFlag = 0x0,
|
Default = 0x000000,
|
||||||
FollowSymlinks = 0x1,
|
ExcludeFiles = 0x000004,
|
||||||
Recursive = 0x2
|
ExcludeDirs = 0x000008,
|
||||||
|
ExcludeSpecial = 0x000010,
|
||||||
|
ResolveSymlinks = 0x000020,
|
||||||
|
FilesOnly = ExcludeDirs | ExcludeSpecial,
|
||||||
|
DirsOnly = ExcludeFiles | ExcludeSpecial,
|
||||||
|
IncludeHidden = 0x000040,
|
||||||
|
IncludeDotAndDotDot = 0x000080,
|
||||||
|
CaseSensitive = 0x000100,
|
||||||
|
Recursive = 0x000400,
|
||||||
|
FollowDirSymlinks = 0x000800,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)
|
Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)
|
||||||
|
|
||||||
QDirListing(const QDir &dir, IteratorFlags flags = IteratorFlag::NoFlag);
|
explicit QDirListing(const QString &path, IteratorFlags flags = IteratorFlag::Default);
|
||||||
QDirListing(const QString &path, IteratorFlags flags = IteratorFlag::NoFlag);
|
explicit QDirListing(const QString &path, const QStringList &nameFilters,
|
||||||
QDirListing(const QString &path, QDir::Filters filter,
|
IteratorFlags flags = IteratorFlag::Default);
|
||||||
IteratorFlags flags = IteratorFlag::NoFlag);
|
|
||||||
QDirListing(const QString &path, const QStringList &nameFilters,
|
|
||||||
QDir::Filters filters = QDir::NoFilter,
|
|
||||||
IteratorFlags flags = IteratorFlag::NoFlag);
|
|
||||||
|
|
||||||
QDirListing(QDirListing &&);
|
QDirListing(QDirListing &&);
|
||||||
QDirListing &operator=(QDirListing &&);
|
QDirListing &operator=(QDirListing &&);
|
||||||
@ -65,11 +77,15 @@ public:
|
|||||||
QString absolutePath() const;
|
QString absolutePath() const;
|
||||||
qint64 size() const;
|
qint64 size() const;
|
||||||
|
|
||||||
QDateTime birthTime(const QTimeZone &tz) const { return fileTime(QFile::FileBirthTime, tz); }
|
QDateTime birthTime(const QTimeZone &tz) const
|
||||||
QDateTime metadataChangeTime(const QTimeZone &tz) const { return fileTime(QFile::FileMetadataChangeTime, tz); }
|
{ return fileTime(QFileDevice::FileBirthTime, tz); }
|
||||||
QDateTime lastModified(const QTimeZone &tz) const { return fileTime(QFile::FileModificationTime, tz); }
|
QDateTime metadataChangeTime(const QTimeZone &tz) const
|
||||||
QDateTime lastRead(const QTimeZone &tz) const { return fileTime(QFile::FileAccessTime, tz); }
|
{ return fileTime(QFileDevice::FileMetadataChangeTime, tz); }
|
||||||
QDateTime fileTime(QFile::FileTime type, const QTimeZone &tz) const;
|
QDateTime lastModified(const QTimeZone &tz) const
|
||||||
|
{ return fileTime(QFileDevice::FileModificationTime, tz); }
|
||||||
|
QDateTime lastRead(const QTimeZone &tz) const
|
||||||
|
{ return fileTime(QFileDevice::FileAccessTime, tz); }
|
||||||
|
QDateTime fileTime(QFileDevice::FileTime type, const QTimeZone &tz) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class const_iterator
|
class const_iterator
|
||||||
@ -111,8 +127,19 @@ public:
|
|||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(QDirListing)
|
Q_DISABLE_COPY(QDirListing)
|
||||||
|
|
||||||
|
// Private constructor that is used in deprecated code paths.
|
||||||
|
// `uint` instead of QDir::Filters and QDirIterator::IteratorFlags
|
||||||
|
// because qdir.h can't be included here; qdiriterator.h can't included
|
||||||
|
// either, because it includes qdir.h
|
||||||
|
QDirListing(const QString &path, const QStringList &nameFilters, uint dirFilters,
|
||||||
|
uint qdirIteratorFlags = 0); // QDirIterator::NoIteratorFlags == 0x0
|
||||||
|
|
||||||
std::unique_ptr<QDirListingPrivate> d;
|
std::unique_ptr<QDirListingPrivate> d;
|
||||||
friend class QDir;
|
friend class QDir;
|
||||||
|
friend class QDirPrivate;
|
||||||
|
friend class QDirIteratorPrivate;
|
||||||
|
friend class QAbstractFileEngine;
|
||||||
|
friend class QFileInfoGatherer;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QDirListing::IteratorFlags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QDirListing::IteratorFlags)
|
||||||
|
@ -38,6 +38,7 @@ class QFileSystemIterator
|
|||||||
public:
|
public:
|
||||||
QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters);
|
QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters);
|
||||||
QFileSystemIterator(const QFileSystemEntry &entry);
|
QFileSystemIterator(const QFileSystemEntry &entry);
|
||||||
|
QFileSystemIterator(const QFileSystemEntry &entry, QDirListing::IteratorFlags filters);
|
||||||
~QFileSystemIterator();
|
~QFileSystemIterator();
|
||||||
|
|
||||||
bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData);
|
bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData);
|
||||||
|
@ -32,6 +32,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDirListing::IteratorFlags)
|
||||||
|
: QFileSystemIterator(entry)
|
||||||
|
{}
|
||||||
|
|
||||||
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters)
|
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters)
|
||||||
: QFileSystemIterator(entry)
|
: QFileSystemIterator(entry)
|
||||||
{
|
{
|
||||||
|
@ -42,6 +42,13 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
|
|||||||
onlyDirs = true;
|
onlyDirs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry,
|
||||||
|
QDirListing::IteratorFlags flags)
|
||||||
|
: QFileSystemIterator(entry)
|
||||||
|
{
|
||||||
|
onlyDirs = flags.testAnyFlags(QDirListing::IteratorFlag::DirsOnly);
|
||||||
|
}
|
||||||
|
|
||||||
QFileSystemIterator::~QFileSystemIterator()
|
QFileSystemIterator::~QFileSystemIterator()
|
||||||
{
|
{
|
||||||
if (findFileHandle != INVALID_HANDLE_VALUE)
|
if (findFileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
@ -798,6 +798,12 @@ QFSFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
|
|||||||
return std::make_unique<QFSFileEngineIterator>(path, filters, filterNames);
|
return std::make_unique<QFSFileEngineIterator>(path, filters, filterNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractFileEngine::IteratorUniquePtr
|
||||||
|
QFSFileEngine::beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames)
|
||||||
|
{
|
||||||
|
return std::make_unique<QFSFileEngineIterator>(path, filters, filterNames);
|
||||||
|
}
|
||||||
#endif // QT_NO_FILESYSTEMITERATOR
|
#endif // QT_NO_FILESYSTEMITERATOR
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -16,6 +16,13 @@ QFSFileEngineIterator::QFSFileEngineIterator(const QString &path, QDir::Filters
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFSFileEngineIterator::QFSFileEngineIterator(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames)
|
||||||
|
: QAbstractFileEngineIterator(path, filters, filterNames),
|
||||||
|
nativeIterator(new QFileSystemIterator(QFileSystemEntry(path), filters))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
QFSFileEngineIterator::~QFSFileEngineIterator()
|
QFSFileEngineIterator::~QFSFileEngineIterator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ class QFSFileEngineIterator : public QAbstractFileEngineIterator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QFSFileEngineIterator(const QString &path, QDir::Filters filters, const QStringList &filterNames);
|
QFSFileEngineIterator(const QString &path, QDir::Filters filters, const QStringList &filterNames);
|
||||||
|
QFSFileEngineIterator(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames);
|
||||||
~QFSFileEngineIterator();
|
~QFSFileEngineIterator();
|
||||||
|
|
||||||
bool advance() override;
|
bool advance() override;
|
||||||
|
@ -88,6 +88,8 @@ public:
|
|||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
||||||
const QStringList &filterNames) override;
|
const QStringList &filterNames) override;
|
||||||
|
IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qint64 read(char *data, qint64 maxlen) override;
|
qint64 read(char *data, qint64 maxlen) override;
|
||||||
|
@ -1589,6 +1589,13 @@ QResourceFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
|
|||||||
return std::make_unique<QResourceFileEngineIterator>(path, filters, filterNames);
|
return std::make_unique<QResourceFileEngineIterator>(path, filters, filterNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractFileEngine::IteratorUniquePtr
|
||||||
|
QResourceFileEngine::beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames)
|
||||||
|
{
|
||||||
|
return std::make_unique<QResourceFileEngineIterator>(path, filters, filterNames);
|
||||||
|
}
|
||||||
|
|
||||||
bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
|
bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output)
|
||||||
{
|
{
|
||||||
Q_D(QResourceFileEngine);
|
Q_D(QResourceFileEngine);
|
||||||
|
@ -15,6 +15,14 @@ QResourceFileEngineIterator::QResourceFileEngineIterator(const QString &path, QD
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QResourceFileEngineIterator::QResourceFileEngineIterator(const QString &path,
|
||||||
|
QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames)
|
||||||
|
: QAbstractFileEngineIterator(path, filters, filterNames),
|
||||||
|
index(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
QResourceFileEngineIterator::~QResourceFileEngineIterator()
|
QResourceFileEngineIterator::~QResourceFileEngineIterator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ class QResourceFileEngineIterator : public QAbstractFileEngineIterator
|
|||||||
public:
|
public:
|
||||||
QResourceFileEngineIterator(const QString &path, QDir::Filters filters,
|
QResourceFileEngineIterator(const QString &path, QDir::Filters filters,
|
||||||
const QStringList &filterNames);
|
const QStringList &filterNames);
|
||||||
|
QResourceFileEngineIterator(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames);
|
||||||
~QResourceFileEngineIterator();
|
~QResourceFileEngineIterator();
|
||||||
|
|
||||||
bool advance() override;
|
bool advance() override;
|
||||||
|
@ -51,6 +51,8 @@ public:
|
|||||||
|
|
||||||
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
||||||
const QStringList &filterNames) override;
|
const QStringList &filterNames) override;
|
||||||
|
IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
|
const QStringList &filterNames) override;
|
||||||
|
|
||||||
bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
|
bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
|
||||||
bool supportsExtension(Extension extension) const override;
|
bool supportsExtension(Extension extension) const override;
|
||||||
|
@ -140,9 +140,7 @@ static inline quint64 retrieveDeviceId(const QByteArray &device, quint64 deviceI
|
|||||||
static QDirListing devicesByLabel()
|
static QDirListing devicesByLabel()
|
||||||
{
|
{
|
||||||
static const char pathDiskByLabel[] = "/dev/disk/by-label";
|
static const char pathDiskByLabel[] = "/dev/disk/by-label";
|
||||||
static constexpr auto LabelFileFilter =
|
static constexpr auto LabelFileFilter = QDirListing::IteratorFlag::IncludeHidden;
|
||||||
QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot;
|
|
||||||
|
|
||||||
return QDirListing(QLatin1StringView(pathDiskByLabel), LabelFileFilter);
|
return QDirListing(QLatin1StringView(pathDiskByLabel), LabelFileFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ inline void QFactoryLoaderPrivate::updateSinglePath(const QString &path)
|
|||||||
#elif defined(Q_OS_ANDROID)
|
#elif defined(Q_OS_ANDROID)
|
||||||
QStringList("libplugins_%1_*.so"_L1.arg(suffix)),
|
QStringList("libplugins_%1_*.so"_L1.arg(suffix)),
|
||||||
#endif
|
#endif
|
||||||
QDir::Files);
|
QDirListing::IteratorFlag::FilesOnly);
|
||||||
|
|
||||||
for (const auto &dirEntry : plugins) {
|
for (const auto &dirEntry : plugins) {
|
||||||
const QString &fileName = dirEntry.fileName();
|
const QString &fileName = dirEntry.fileName();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <QtCore/QDataStream>
|
#include <QtCore/QDataStream>
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#include <QtCore/QDirListing>
|
#include <QtCore/QDirListing>
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QCache>
|
#include <QtCore/QCache>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
@ -113,14 +114,16 @@ static QTzTimeZoneHash loadTzTimeZones()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString path = tzif.fileName();
|
QString path = tzif.fileName();
|
||||||
const qsizetype cut = path.lastIndexOf(u'/');
|
const qsizetype cut = path.lastIndexOf(u'/');
|
||||||
Q_ASSERT(cut > 0);
|
Q_ASSERT(cut > 0);
|
||||||
const QDir zoneDir = QDir(path.first(cut));
|
path.truncate(cut + 1);
|
||||||
for (const auto &info : QDirListing(zoneDir, QDirListing::IteratorFlag::Recursive)) {
|
const qsizetype prefixLen = path.size();
|
||||||
|
for (const auto &info : QDirListing(path, QDirListing::IteratorFlag::Recursive)) {
|
||||||
if (!(info.isFile() || info.isSymLink()))
|
if (!(info.isFile() || info.isSymLink()))
|
||||||
continue;
|
continue;
|
||||||
const QString name = zoneDir.relativeFilePath(info.filePath());
|
const QString infoAbsolutePath = info.absoluteFilePath();
|
||||||
|
const QString name = infoAbsolutePath.sliced(prefixLen);
|
||||||
// Two sub-directories containing (more or less) copies of the zoneinfo tree.
|
// Two sub-directories containing (more or less) copies of the zoneinfo tree.
|
||||||
if (info.isDir() ? name == "posix"_L1 || name == "right"_L1
|
if (info.isDir() ? name == "posix"_L1 || name == "right"_L1
|
||||||
: name.startsWith("posix/"_L1) || name.startsWith("right/"_L1)) {
|
: name.startsWith("posix/"_L1) || name.startsWith("right/"_L1)) {
|
||||||
@ -130,7 +133,7 @@ static QTzTimeZoneHash loadTzTimeZones()
|
|||||||
// isTzFile() check; in practice current (2023) zoneinfo/ contains only
|
// isTzFile() check; in practice current (2023) zoneinfo/ contains only
|
||||||
// actual zone files and matches to that filter.
|
// actual zone files and matches to that filter.
|
||||||
const QByteArray id = QFile::encodeName(name);
|
const QByteArray id = QFile::encodeName(name);
|
||||||
if (!zonesHash.contains(id) && isTzFile(zoneDir.absoluteFilePath(name)))
|
if (!zonesHash.contains(id) && isTzFile(infoAbsolutePath))
|
||||||
zonesHash.insert(id, QTzTimeZone());
|
zonesHash.insert(id, QTzTimeZone());
|
||||||
}
|
}
|
||||||
return zonesHash;
|
return zonesHash;
|
||||||
|
@ -419,8 +419,10 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
|
|||||||
|
|
||||||
QStringList allFiles;
|
QStringList allFiles;
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
|
// Use QDirListing::IteratorFlags when QFileSystemModel is
|
||||||
|
// changed to use them too
|
||||||
constexpr auto dirFilters = QDir::AllEntries | QDir::System | QDir::Hidden;
|
constexpr auto dirFilters = QDir::AllEntries | QDir::System | QDir::Hidden;
|
||||||
for (const auto &dirEntry : QDirListing(path, dirFilters)) {
|
for (const auto &dirEntry : QDirListing(path, {}, dirFilters.toInt())) {
|
||||||
if (isInterruptionRequested())
|
if (isInterruptionRequested())
|
||||||
break;
|
break;
|
||||||
fileInfo = dirEntry.fileInfo();
|
fileInfo = dirEntry.fileInfo();
|
||||||
|
@ -473,8 +473,6 @@ qint64 QNetworkDiskCache::expire()
|
|||||||
// close file handle to prevent "in use" error when QFile::remove() is called
|
// close file handle to prevent "in use" error when QFile::remove() is called
|
||||||
d->lastItem.reset();
|
d->lastItem.reset();
|
||||||
|
|
||||||
const QDir::Filters filters = QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot;
|
|
||||||
|
|
||||||
struct CacheItem
|
struct CacheItem
|
||||||
{
|
{
|
||||||
std::chrono::milliseconds msecs;
|
std::chrono::milliseconds msecs;
|
||||||
@ -484,7 +482,7 @@ qint64 QNetworkDiskCache::expire()
|
|||||||
std::vector<CacheItem> cacheItems;
|
std::vector<CacheItem> cacheItems;
|
||||||
qint64 totalSize = 0;
|
qint64 totalSize = 0;
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
for (const auto &dirEntry : QDirListing(cacheDirectory(), filters, F::Recursive)) {
|
for (const auto &dirEntry : QDirListing(cacheDirectory(), F::FilesOnly | F::Recursive)) {
|
||||||
if (!dirEntry.fileName().endsWith(CACHE_POSTFIX))
|
if (!dirEntry.fileName().endsWith(CACHE_POSTFIX))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -681,8 +681,8 @@ QList<QSslCertificate> QSslCertificate::fromPath(const QString &path,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
constexpr auto iterFlags = F::FollowSymlinks | F::Recursive;
|
constexpr auto iterFlags = F::FollowDirSymlinks | F::Recursive | F::FilesOnly;
|
||||||
for (const auto &dirEntry : QDirListing(pathPrefixString, QDir::Files, iterFlags)) {
|
for (const auto &dirEntry : QDirListing(pathPrefixString, iterFlags)) {
|
||||||
QString filePath = dirEntry.filePath();
|
QString filePath = dirEntry.filePath();
|
||||||
if (startIndex > 0)
|
if (startIndex > 0)
|
||||||
filePath.remove(0, startIndex);
|
filePath.remove(0, startIndex);
|
||||||
|
@ -245,7 +245,7 @@ QString AndroidContentFileEngine::fileName(FileName f) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QAbstractFileEngine::IteratorUniquePtr
|
QAbstractFileEngine::IteratorUniquePtr
|
||||||
AndroidContentFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
|
AndroidContentFileEngine::beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
const QStringList &filterNames)
|
const QStringList &filterNames)
|
||||||
{
|
{
|
||||||
return std::make_unique<AndroidContentFileEngineIterator>(path, filters, filterNames);
|
return std::make_unique<AndroidContentFileEngineIterator>(path, filters, filterNames);
|
||||||
@ -265,7 +265,7 @@ AndroidContentFileEngineHandler::create(const QString &fileName) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
AndroidContentFileEngineIterator::AndroidContentFileEngineIterator(
|
AndroidContentFileEngineIterator::AndroidContentFileEngineIterator(
|
||||||
const QString &path, QDir::Filters filters, const QStringList &filterNames)
|
const QString &path, QDirListing::IteratorFlags filters, const QStringList &filterNames)
|
||||||
: QAbstractFileEngineIterator(path, filters, filterNames)
|
: QAbstractFileEngineIterator(path, filters, filterNames)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
QDateTime fileTime(QFile::FileTime time) const override;
|
QDateTime fileTime(QFile::FileTime time) const override;
|
||||||
FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
|
FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
|
||||||
QString fileName(FileName file = DefaultName) const override;
|
QString fileName(FileName file = DefaultName) const override;
|
||||||
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
const QStringList &filterNames) override;
|
const QStringList &filterNames) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -53,7 +53,7 @@ public:
|
|||||||
class AndroidContentFileEngineIterator : public QAbstractFileEngineIterator
|
class AndroidContentFileEngineIterator : public QAbstractFileEngineIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidContentFileEngineIterator(const QString &path, QDir::Filters filters,
|
AndroidContentFileEngineIterator(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
const QStringList &filterNames);
|
const QStringList &filterNames);
|
||||||
~AndroidContentFileEngineIterator();
|
~AndroidContentFileEngineIterator();
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ Q_CONSTINIT QMutex FolderIterator::m_assetsCacheMutex;
|
|||||||
class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
|
class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidAbstractFileEngineIterator(QDir::Filters filters,
|
AndroidAbstractFileEngineIterator(QDirListing::IteratorFlags filters,
|
||||||
const QStringList &nameFilters,
|
const QStringList &nameFilters,
|
||||||
const QString &path)
|
const QString &path)
|
||||||
: QAbstractFileEngineIterator(path, filters, nameFilters)
|
: QAbstractFileEngineIterator(path, filters, nameFilters)
|
||||||
@ -351,8 +351,8 @@ public:
|
|||||||
m_assetsInfoCache.insert(m_fileName, newAssetInfoPtr);
|
m_assetsInfoCache.insert(m_fileName, newAssetInfoPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorUniquePtr
|
IteratorUniquePtr beginEntryList(const QString &, QDirListing::IteratorFlags filters,
|
||||||
beginEntryList(const QString &, QDir::Filters filters, const QStringList &filterNames) override
|
const QStringList &filterNames) override
|
||||||
{
|
{
|
||||||
// AndroidAbstractFileEngineIterator use `m_fileName` as the path
|
// AndroidAbstractFileEngineIterator use `m_fileName` as the path
|
||||||
if (m_assetInfo && m_assetInfo->type == AssetItem::Type::Folder)
|
if (m_assetInfo && m_assetInfo->type == AssetItem::Type::Folder)
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
void setFileName(const QString &file) override;
|
void setFileName(const QString &file) override;
|
||||||
|
|
||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters,
|
IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
const QStringList &filterNames) override;
|
const QStringList &filterNames) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ public:
|
|||||||
QIOSAssetEnumerator *m_enumerator;
|
QIOSAssetEnumerator *m_enumerator;
|
||||||
|
|
||||||
QIOSFileEngineIteratorAssetsLibrary(
|
QIOSFileEngineIteratorAssetsLibrary(
|
||||||
const QString &path, QDir::Filters filters, const QStringList &nameFilters)
|
const QString &path, QDirListing::IteratorFlags filters, const QStringList &nameFilters)
|
||||||
: QAbstractFileEngineIterator(path, filters, nameFilters)
|
: QAbstractFileEngineIterator(path, filters, nameFilters)
|
||||||
, m_enumerator(new QIOSAssetEnumerator([[[ALAssetsLibrary alloc] init] autorelease], ALAssetsGroupAll))
|
, m_enumerator(new QIOSAssetEnumerator([[[ALAssetsLibrary alloc] init] autorelease], ALAssetsGroupAll))
|
||||||
{
|
{
|
||||||
@ -440,7 +440,7 @@ void QIOSFileEngineAssetsLibrary::setFileName(const QString &file)
|
|||||||
|
|
||||||
QAbstractFileEngine::IteratorUniquePtr
|
QAbstractFileEngine::IteratorUniquePtr
|
||||||
QIOSFileEngineAssetsLibrary::beginEntryList(
|
QIOSFileEngineAssetsLibrary::beginEntryList(
|
||||||
const QString &path, QDir::Filters filters, const QStringList &filterNames)
|
const QString &path, QDirListing::IteratorFlags filters, const QStringList &filterNames)
|
||||||
{
|
{
|
||||||
return std::make_unique<QIOSFileEngineIteratorAssetsLibrary>(path, filters, filterNames);
|
return std::make_unique<QIOSFileEngineIteratorAssetsLibrary>(path, filters, filterNames);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,8 @@ void QTlsBackendOpenSSL::ensureCiphersAndCertsLoaded() const
|
|||||||
const QStringList symLinkFilter{
|
const QStringList symLinkFilter{
|
||||||
u"[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"_s};
|
u"[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"_s};
|
||||||
for (const auto &dir : dirs) {
|
for (const auto &dir : dirs) {
|
||||||
QDirListing dirList(QString::fromLatin1(dir), symLinkFilter, QDir::Files);
|
QDirListing dirList(QString::fromLatin1(dir), symLinkFilter,
|
||||||
|
QDirListing::IteratorFlag::FilesOnly);
|
||||||
if (dirList.cbegin() != dirList.cend()) { // Not empty
|
if (dirList.cbegin() != dirList.cend()) { // Not empty
|
||||||
QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
|
QSslSocketPrivate::setRootCertOnDemandLoadingSupported(true);
|
||||||
break;
|
break;
|
||||||
@ -390,11 +391,9 @@ QList<QSslCertificate> systemCaCertificates()
|
|||||||
QStringLiteral("/etc/pki/tls/certs/ca-bundle.crt"), // Fedora, Mandriva
|
QStringLiteral("/etc/pki/tls/certs/ca-bundle.crt"), // Fedora, Mandriva
|
||||||
QStringLiteral("/usr/local/share/certs/ca-root-nss.crt") // FreeBSD's ca_root_nss
|
QStringLiteral("/usr/local/share/certs/ca-root-nss.crt") // FreeBSD's ca_root_nss
|
||||||
};
|
};
|
||||||
QDir currentDir;
|
static const QStringList nameFilters = {u"*.pem"_s, u"*.crt"_s};
|
||||||
currentDir.setNameFilters(QStringList{QStringLiteral("*.pem"), QStringLiteral("*.crt")});
|
|
||||||
for (const auto &directory : directories) {
|
for (const auto &directory : directories) {
|
||||||
currentDir.setPath(QLatin1StringView(directory));
|
for (const auto &dirEntry : QDirListing(directory, nameFilters)) {
|
||||||
for (const auto &dirEntry : QDirListing(currentDir)) {
|
|
||||||
// use canonical path here to not load the same certificate twice if symlinked
|
// use canonical path here to not load the same certificate twice if symlinked
|
||||||
certFiles.insert(dirEntry.canonicalFilePath());
|
certFiles.insert(dirEntry.canonicalFilePath());
|
||||||
}
|
}
|
||||||
|
@ -2870,7 +2870,7 @@ void checkAndWarnGradleLongPaths(const QString &outputDirectory)
|
|||||||
QStringList longFileNames;
|
QStringList longFileNames;
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
for (const auto &dirEntry : QDirListing(outputDirectory, QStringList(u"*.java"_s),
|
for (const auto &dirEntry : QDirListing(outputDirectory, QStringList(u"*.java"_s),
|
||||||
QDir::Files, F::Recursive)) {
|
F::FilesOnly | F::Recursive)) {
|
||||||
if (dirEntry.size() >= MAX_PATH)
|
if (dirEntry.size() >= MAX_PATH)
|
||||||
longFileNames.append(dirEntry.filePath());
|
longFileNames.append(dirEntry.filePath());
|
||||||
}
|
}
|
||||||
|
@ -635,13 +635,13 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
|
|||||||
absFileName.prepend(currentPath);
|
absFileName.prepend(currentPath);
|
||||||
QFileInfo file(absFileName);
|
QFileInfo file(absFileName);
|
||||||
if (file.isDir()) {
|
if (file.isDir()) {
|
||||||
QDir dir(file.filePath());
|
|
||||||
if (!alias.endsWith(slash))
|
if (!alias.endsWith(slash))
|
||||||
alias += slash;
|
alias += slash;
|
||||||
|
|
||||||
QStringList filePaths;
|
QStringList filePaths;
|
||||||
using F = QDirListing::IteratorFlag;
|
using F = QDirListing::IteratorFlag;
|
||||||
for (const auto &entry : QDirListing(dir, F::FollowSymlinks | F::Recursive)) {
|
constexpr auto flags = F::FollowDirSymlinks | F::Recursive;
|
||||||
|
for (const auto &entry : QDirListing(file.filePath(), flags)) {
|
||||||
const QString &fileName = entry.fileName();
|
const QString &fileName = entry.fileName();
|
||||||
if (fileName == "."_L1 || fileName == ".."_L1)
|
if (fileName == "."_L1 || fileName == ".."_L1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -133,8 +133,9 @@ bool QtModuleInfoStore::populate(const QString &modulesDir, const QString &trans
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using F = QDirListing::IteratorFlag;
|
||||||
// Read modules, and assign a bit as ID.
|
// Read modules, and assign a bit as ID.
|
||||||
for (const auto &dirEntry : QDirListing(modulesDir, {u"*.json"_s}, QDir::Files)) {
|
for (const auto &dirEntry : QDirListing(modulesDir, {u"*.json"_s}, F::FilesOnly)) {
|
||||||
QtModule module = moduleFromJsonFile(dirEntry.filePath(), errorString);
|
QtModule module = moduleFromJsonFile(dirEntry.filePath(), errorString);
|
||||||
if (!errorString->isEmpty())
|
if (!errorString->isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -432,7 +432,7 @@ public:
|
|||||||
class Iterator : public QAbstractFileEngineIterator
|
class Iterator : public QAbstractFileEngineIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Iterator(const QString &path, QDir::Filters filters, const QStringList &filterNames)
|
Iterator(const QString &path, QDirListing::IteratorFlags filters, const QStringList &filterNames)
|
||||||
: QAbstractFileEngineIterator(path, filters, filterNames)
|
: QAbstractFileEngineIterator(path, filters, filterNames)
|
||||||
{
|
{
|
||||||
names.append("foo");
|
names.append("foo");
|
||||||
@ -463,8 +463,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorUniquePtr
|
IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters,
|
||||||
beginEntryList(const QString &path, QDir::Filters filters, const QStringList &filterNames) override
|
const QStringList &filterNames) override
|
||||||
{
|
{
|
||||||
return std::make_unique<Iterator>(path, filters, filterNames);
|
return std::make_unique<Iterator>(path, filters, filterNames);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QDirListing::IteratorFlags)
|
Q_DECLARE_METATYPE(QDirListing::IteratorFlags)
|
||||||
Q_DECLARE_METATYPE(QDir::Filters)
|
|
||||||
|
|
||||||
using ItFlag = QDirListing::IteratorFlag;
|
using ItFlag = QDirListing::IteratorFlag;
|
||||||
|
|
||||||
@ -187,183 +186,259 @@ void tst_QDirListing::iterateRelativeDirectory_data()
|
|||||||
{
|
{
|
||||||
QTest::addColumn<QString>("dirName"); // relative from current path or abs
|
QTest::addColumn<QString>("dirName"); // relative from current path or abs
|
||||||
QTest::addColumn<QDirListing::IteratorFlags>("flags");
|
QTest::addColumn<QDirListing::IteratorFlags>("flags");
|
||||||
QTest::addColumn<QDir::Filters>("filters");
|
|
||||||
QTest::addColumn<QStringList>("nameFilters");
|
QTest::addColumn<QStringList>("nameFilters");
|
||||||
QTest::addColumn<QStringList>("entries");
|
QTest::addColumn<QStringList>("entries");
|
||||||
|
|
||||||
QTest::newRow("no flags")
|
const QStringList allSymlinks = {
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags{}
|
#if !defined(Q_NO_SYMLINKS)
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList("*")
|
"entrylist/linktofile.lnk"_L1,
|
||||||
<< QString(
|
"entrylist/brokenlink.lnk"_L1,
|
||||||
"entrylist/.,"
|
# if !defined(Q_NO_SYMLINKS_TO_DIRS)
|
||||||
"entrylist/..,"
|
"entrylist/linktodirectory.lnk"_L1,
|
||||||
"entrylist/file,"
|
# endif
|
||||||
#ifndef Q_NO_SYMLINKS
|
|
||||||
"entrylist/linktofile.lnk,"
|
|
||||||
#endif
|
#endif
|
||||||
"entrylist/directory,"
|
};
|
||||||
#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
|
|
||||||
"entrylist/linktodirectory.lnk,"
|
|
||||||
#endif
|
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("NoDot")
|
const QStringList nonBrokenSymlinks = {
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags{}
|
#if !defined(Q_NO_SYMLINKS)
|
||||||
<< QDir::Filters(QDir::AllEntries | QDir::NoDot) << QStringList("*")
|
"entrylist/linktofile.lnk"_L1,
|
||||||
<< QString(
|
# if !defined(Q_NO_SYMLINKS_TO_DIRS)
|
||||||
"entrylist/..,"
|
"entrylist/linktodirectory.lnk"_L1,
|
||||||
"entrylist/file,"
|
# endif
|
||||||
#ifndef Q_NO_SYMLINKS
|
|
||||||
"entrylist/linktofile.lnk,"
|
|
||||||
#endif
|
#endif
|
||||||
"entrylist/directory,"
|
};
|
||||||
#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
|
|
||||||
"entrylist/linktodirectory.lnk,"
|
|
||||||
#endif
|
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("NoDotDot")
|
using F = QDirListing::IteratorFlag;
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags{}
|
QTest::newRow("Default_Flag")
|
||||||
<< QDir::Filters(QDir::AllEntries | QDir::NoDotDot) << QStringList("*")
|
<< QString("entrylist") << QDirListing::IteratorFlags{F::Default}
|
||||||
<< QString(
|
<< QStringList("*")
|
||||||
"entrylist/.,"
|
<< QStringList{
|
||||||
"entrylist/file,"
|
"entrylist/file"_L1,
|
||||||
#ifndef Q_NO_SYMLINKS
|
"entrylist/directory"_L1,
|
||||||
"entrylist/linktofile.lnk,"
|
"entrylist/writable"_L1,
|
||||||
#endif
|
} + allSymlinks;
|
||||||
"entrylist/directory,"
|
|
||||||
#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
|
|
||||||
"entrylist/linktodirectory.lnk,"
|
|
||||||
#endif
|
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("NoDotAndDotDot")
|
QTest::newRow("IncludeDotAndDotDot")
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags{}
|
<< QString("entrylist")
|
||||||
<< QDir::Filters(QDir::AllEntries | QDir::NoDotAndDotDot) << QStringList("*")
|
<< QDirListing::IteratorFlags{F::IncludeDotAndDotDot}
|
||||||
<< QString(
|
<< QStringList("*")
|
||||||
"entrylist/file,"
|
<< QStringList{
|
||||||
#ifndef Q_NO_SYMLINKS
|
"entrylist/."_L1,
|
||||||
"entrylist/linktofile.lnk,"
|
"entrylist/.."_L1,
|
||||||
#endif
|
"entrylist/file"_L1,
|
||||||
"entrylist/directory,"
|
"entrylist/directory"_L1,
|
||||||
#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
|
"entrylist/writable"_L1,
|
||||||
"entrylist/linktodirectory.lnk,"
|
} + allSymlinks;
|
||||||
#endif
|
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks")
|
QTest::newRow("Recursive-IncludeDotAndDotDot")
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive | ItFlag::FollowSymlinks)
|
<< QString("entrylist")
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList("*")
|
<< QDirListing::IteratorFlags{F::Recursive | F::IncludeDotAndDotDot}
|
||||||
<< QString(
|
<< QStringList("*")
|
||||||
"entrylist/.,"
|
<< QStringList{
|
||||||
"entrylist/..,"
|
"entrylist/."_L1,
|
||||||
"entrylist/directory/.,"
|
"entrylist/.."_L1,
|
||||||
"entrylist/directory/..,"
|
"entrylist/file"_L1,
|
||||||
"entrylist/file,"
|
"entrylist/directory"_L1,
|
||||||
#ifndef Q_NO_SYMLINKS
|
"entrylist/directory/."_L1,
|
||||||
"entrylist/linktofile.lnk,"
|
"entrylist/directory/.."_L1,
|
||||||
#endif
|
"entrylist/directory/dummy"_L1,
|
||||||
"entrylist/directory,"
|
"entrylist/writable"_L1,
|
||||||
"entrylist/directory/dummy,"
|
} + allSymlinks;
|
||||||
#if !defined(Q_NO_SYMLINKS) && !defined(Q_NO_SYMLINKS_TO_DIRS)
|
|
||||||
"entrylist/linktodirectory.lnk,"
|
|
||||||
#endif
|
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("QDir::Subdirectories / QDir::Files")
|
QTest::newRow("Recursive")
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive)
|
<< QString("entrylist")
|
||||||
<< QDir::Filters(QDir::Files) << QStringList("*")
|
<< QDirListing::IteratorFlags(F::Recursive)
|
||||||
<< QString("entrylist/directory/dummy,"
|
<< QStringList("*")
|
||||||
"entrylist/file,"
|
<< QStringList{
|
||||||
#ifndef Q_NO_SYMLINKS
|
"entrylist/file"_L1,
|
||||||
"entrylist/linktofile.lnk,"
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + allSymlinks;
|
||||||
|
|
||||||
|
QTest::newRow("ResolveSymlinks")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags{F::ResolveSymlinks}
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + nonBrokenSymlinks;
|
||||||
|
|
||||||
|
QTest::newRow("Recursive-ResolveSymlinks")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags(F::Recursive | F::ResolveSymlinks)
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + nonBrokenSymlinks;
|
||||||
|
|
||||||
|
QTest::newRow("Recursive-FilesOnly")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags(F::Recursive | F::FilesOnly)
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
};
|
||||||
|
|
||||||
|
QTest::newRow("Recursive-FilesOnly-ResolveSymlinks")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags(F::Recursive | F::FilesOnly | F::ResolveSymlinks)
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
#if !defined(Q_NO_SYMLINKS)
|
||||||
|
"entrylist/linktofile.lnk"_L1,
|
||||||
#endif
|
#endif
|
||||||
"entrylist/writable").split(',');
|
};
|
||||||
|
|
||||||
QTest::newRow("QDir::Subdirectories | QDir::FollowSymlinks / QDir::Files")
|
QTest::newRow("Recursive-DirsOnly")
|
||||||
<< QString("entrylist") << QDirListing::IteratorFlags(ItFlag::Recursive | QDirListing::IteratorFlag::FollowSymlinks)
|
<< QString("entrylist")
|
||||||
<< QDir::Filters(QDir::Files) << QStringList("*")
|
<< QDirListing::IteratorFlags(F::Recursive | F::DirsOnly)
|
||||||
<< QString("entrylist/file,"
|
<< QStringList("*")
|
||||||
#ifndef Q_NO_SYMLINKS
|
<< QStringList{ "entrylist/directory"_L1, };
|
||||||
"entrylist/linktofile.lnk,"
|
|
||||||
|
QTest::newRow("Recursive-DirsOnly-ResolveSymlinks")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags(F::Recursive | F::DirsOnly | F::ResolveSymlinks)
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
#if !defined(Q_NO_SYMLINKS)
|
||||||
|
"entrylist/linktodirectory.lnk"_L1,
|
||||||
#endif
|
#endif
|
||||||
"entrylist/directory/dummy,"
|
};
|
||||||
"entrylist/writable").split(',');
|
|
||||||
|
|
||||||
QTest::newRow("empty, default")
|
QTest::newRow("FollowDirSymlinks")
|
||||||
<< QString("empty") << QDirListing::IteratorFlags{}
|
<< QString("entrylist")
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList("*")
|
<< QDirListing::IteratorFlags{F::FollowDirSymlinks}
|
||||||
<< QString("empty/.,empty/..").split(',');
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + allSymlinks;
|
||||||
|
|
||||||
QTest::newRow("empty, QDir::NoDotAndDotDot")
|
QTest::newRow("FollowDirSymlinks-Recursive")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags{F::FollowDirSymlinks | F::Recursive}
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + allSymlinks;
|
||||||
|
|
||||||
|
QTest::newRow("FollowDirSymlinks-Recursive-ResolveSymlinks")
|
||||||
|
<< QString("entrylist")
|
||||||
|
<< QDirListing::IteratorFlags{F::FollowDirSymlinks | F::Recursive | F::ResolveSymlinks}
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"entrylist/file"_L1,
|
||||||
|
"entrylist/directory"_L1,
|
||||||
|
"entrylist/directory/dummy"_L1,
|
||||||
|
"entrylist/writable"_L1,
|
||||||
|
} + nonBrokenSymlinks;
|
||||||
|
|
||||||
|
QTest::newRow("empty-dir-IncludeDotAndDotDot")
|
||||||
|
<< QString("empty")
|
||||||
|
<< QDirListing::IteratorFlags{F::IncludeDotAndDotDot}
|
||||||
|
<< QStringList("*")
|
||||||
|
<< QStringList{
|
||||||
|
"empty/."_L1,
|
||||||
|
"empty/.."_L1
|
||||||
|
};
|
||||||
|
|
||||||
|
QTest::newRow("empty-dir-Default-Flag")
|
||||||
<< QString("empty") << QDirListing::IteratorFlags{}
|
<< QString("empty") << QDirListing::IteratorFlags{}
|
||||||
<< QDir::Filters(QDir::NoDotAndDotDot) << QStringList("*")
|
<< QStringList("*")
|
||||||
<< QStringList();
|
<< QStringList();
|
||||||
|
|
||||||
|
QTest::newRow("Recursive-nameFilter")
|
||||||
|
<< u"entrylist"_s
|
||||||
|
<< QDirListing::IteratorFlags(F::Recursive)
|
||||||
|
<< QStringList{"dummy"_L1}
|
||||||
|
<< QStringList{"entrylist/directory/dummy"_L1};
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDirListing::iterateRelativeDirectory()
|
void tst_QDirListing::iterateRelativeDirectory()
|
||||||
{
|
{
|
||||||
QFETCH(QString, dirName);
|
QFETCH(QString, dirName);
|
||||||
QFETCH(QDirListing::IteratorFlags, flags);
|
QFETCH(QDirListing::IteratorFlags, flags);
|
||||||
QFETCH(QDir::Filters, filters);
|
|
||||||
QFETCH(QStringList, nameFilters);
|
QFETCH(QStringList, nameFilters);
|
||||||
QFETCH(const QStringList, entries);
|
QFETCH(const QStringList, entries);
|
||||||
|
|
||||||
|
// If canonicalFilePath is empty (e.g. for broken symlinks), use absoluteFilePath()
|
||||||
QStringList list;
|
QStringList list;
|
||||||
for (const auto &dirEntry : QDirListing(dirName, nameFilters, filters, flags)) {
|
for (const auto &dirEntry : QDirListing(dirName, nameFilters, flags)) {
|
||||||
// Using canonical file paths for final comparison
|
QString filePath = dirEntry.canonicalFilePath();
|
||||||
list << dirEntry.fileInfo().canonicalFilePath();
|
list.emplace_back(!filePath.isEmpty()? filePath : dirEntry.absoluteFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The order of items returned by QDirListing is not guaranteed.
|
// The order of items returned by QDirListing is not guaranteed.
|
||||||
list.sort();
|
list.sort();
|
||||||
|
|
||||||
QStringList sortedEntries;
|
QStringList sortedEntries;
|
||||||
for (const QString &item : entries)
|
for (const QString &item : entries) {
|
||||||
sortedEntries.append(QFileInfo(item).canonicalFilePath());
|
QFileInfo fi(item);
|
||||||
|
QString filePath = fi.canonicalFilePath();
|
||||||
|
sortedEntries.emplace_back(!filePath.isEmpty()? filePath : fi.absoluteFilePath());
|
||||||
|
}
|
||||||
sortedEntries.sort();
|
sortedEntries.sort();
|
||||||
|
|
||||||
if (sortedEntries != list) {
|
QCOMPARE_EQ(list, sortedEntries);
|
||||||
qDebug() << "ACTUAL: " << list;
|
|
||||||
qDebug() << "EXPECTED:" << sortedEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
QCOMPARE(list, sortedEntries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDirListing::iterateResource_data()
|
void tst_QDirListing::iterateResource_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QString>("dirName"); // relative from current path or abs
|
QTest::addColumn<QString>("dirName"); // relative from current path or abs
|
||||||
QTest::addColumn<QDirListing::IteratorFlags>("flags");
|
QTest::addColumn<QDirListing::IteratorFlags>("flags");
|
||||||
QTest::addColumn<QDir::Filters>("filters");
|
|
||||||
QTest::addColumn<QStringList>("nameFilters");
|
QTest::addColumn<QStringList>("nameFilters");
|
||||||
QTest::addColumn<QStringList>("entries");
|
QTest::addColumn<QStringList>("entries");
|
||||||
|
|
||||||
QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa") << QDirListing::IteratorFlags{}
|
QTest::newRow("invalid") << QString::fromLatin1(":/testdata/burpaburpa")
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
|
<< QDirListing::IteratorFlags{ItFlag::Default}
|
||||||
<< QStringList();
|
<< QStringList{u"*"_s} << QStringList();
|
||||||
|
|
||||||
QTest::newRow("qrc:/testdata") << u":/testdata/"_s << QDirListing::IteratorFlags{}
|
QTest::newRow("qrc:/testdata") << u":/testdata/"_s << QDirListing::IteratorFlags{}
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
|
<< QStringList(QLatin1String("*"))
|
||||||
<< QString::fromLatin1(":/testdata/entrylist").split(QLatin1String(","));
|
<< QStringList{u":/testdata/entrylist"_s};
|
||||||
QTest::newRow("qrc:/testdata/entrylist") << u":/testdata/entrylist"_s << QDirListing::IteratorFlags{}
|
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
|
QTest::newRow("qrc:/testdata/entrylist")
|
||||||
<< QString::fromLatin1(":/testdata/entrylist/directory,:/testdata/entrylist/file").split(QLatin1String(","));
|
<< u":/testdata/entrylist"_s
|
||||||
QTest::newRow("qrc:/testdata recursive") << u":/testdata"_s
|
<< QDirListing::IteratorFlags{}
|
||||||
<< QDirListing::IteratorFlags(ItFlag::Recursive)
|
<< QStringList(QLatin1String("*"))
|
||||||
<< QDir::Filters(QDir::NoFilter) << QStringList(QLatin1String("*"))
|
<< QStringList{u":/testdata/entrylist/directory"_s,
|
||||||
<< QString::fromLatin1(":/testdata/entrylist,:/testdata/entrylist/directory,:/testdata/entrylist/directory/dummy,:/testdata/entrylist/file").split(QLatin1String(","));
|
u":/testdata/entrylist/file"_s};
|
||||||
|
|
||||||
|
QTest::newRow("qrc:/testdata recursive")
|
||||||
|
<< u":/testdata"_s
|
||||||
|
<< QDirListing::IteratorFlags(ItFlag::Recursive)
|
||||||
|
<< QStringList(QLatin1String("*"))
|
||||||
|
<< QStringList{u":/testdata/entrylist"_s,
|
||||||
|
u":/testdata/entrylist/directory"_s,
|
||||||
|
u":/testdata/entrylist/directory/dummy"_s,
|
||||||
|
u":/testdata/entrylist/file"_s};
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDirListing::iterateResource()
|
void tst_QDirListing::iterateResource()
|
||||||
{
|
{
|
||||||
QFETCH(QString, dirName);
|
QFETCH(QString, dirName);
|
||||||
QFETCH(QDirListing::IteratorFlags, flags);
|
QFETCH(QDirListing::IteratorFlags, flags);
|
||||||
QFETCH(QDir::Filters, filters);
|
|
||||||
QFETCH(QStringList, nameFilters);
|
QFETCH(QStringList, nameFilters);
|
||||||
QFETCH(QStringList, entries);
|
QFETCH(QStringList, entries);
|
||||||
|
|
||||||
QStringList list;
|
QStringList list;
|
||||||
for (const auto &dirEntry : QDirListing(dirName, nameFilters, filters, flags)) {
|
for (const auto &dirEntry : QDirListing(dirName, nameFilters, flags)) {
|
||||||
QString dir = dirEntry.fileInfo().filePath();
|
QString dir = dirEntry.fileInfo().filePath();
|
||||||
if (!dir.startsWith(":/qt-project.org"))
|
if (!dir.startsWith(":/qt-project.org"))
|
||||||
list.emplace_back(std::move(dir));
|
list.emplace_back(std::move(dir));
|
||||||
@ -404,7 +479,7 @@ void tst_QDirListing::stopLinkLoop()
|
|||||||
createLink("..", "entrylist/directory/entrylist4.lnk");
|
createLink("..", "entrylist/directory/entrylist4.lnk");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr auto flags = ItFlag::Recursive | ItFlag::FollowSymlinks;
|
constexpr auto flags = ItFlag::Recursive | ItFlag::FollowDirSymlinks;
|
||||||
QDirListing dirIter(u"entrylist"_s, flags);
|
QDirListing dirIter(u"entrylist"_s, flags);
|
||||||
QStringList list;
|
QStringList list;
|
||||||
int max = 200;
|
int max = 200;
|
||||||
@ -424,7 +499,8 @@ public:
|
|||||||
: QFSFileEngine(fileName)
|
: QFSFileEngine(fileName)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
IteratorUniquePtr beginEntryList(const QString &, QDir::Filters, const QStringList &) override
|
IteratorUniquePtr beginEntryList(const QString &, QDirListing::IteratorFlags,
|
||||||
|
const QStringList &) override
|
||||||
{ return nullptr; }
|
{ return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -468,7 +544,6 @@ void tst_QDirListing::testQFsFileEngineIterator()
|
|||||||
{
|
{
|
||||||
QFETCH(QString, dirName);
|
QFETCH(QString, dirName);
|
||||||
QFETCH(QStringList, nameFilters);
|
QFETCH(QStringList, nameFilters);
|
||||||
QFETCH(QDir::Filters, filters);
|
|
||||||
QFETCH(QDirListing::IteratorFlags, flags);
|
QFETCH(QDirListing::IteratorFlags, flags);
|
||||||
|
|
||||||
if (dirName == u"empty")
|
if (dirName == u"empty")
|
||||||
@ -476,7 +551,7 @@ void tst_QDirListing::testQFsFileEngineIterator()
|
|||||||
|
|
||||||
CustomEngineHandler handler;
|
CustomEngineHandler handler;
|
||||||
bool isEmpty = true;
|
bool isEmpty = true;
|
||||||
for (const auto &dirEntry : QDirListing(u"entrylist"_s, nameFilters, filters, flags)) {
|
for (const auto &dirEntry : QDirListing(u"entrylist"_s, nameFilters, flags)) {
|
||||||
if (dirEntry.filePath().contains(u"entrylist"))
|
if (dirEntry.filePath().contains(u"entrylist"))
|
||||||
isEmpty = false; // At least one entry in `entrylist` dir
|
isEmpty = false; // At least one entry in `entrylist` dir
|
||||||
}
|
}
|
||||||
@ -486,7 +561,7 @@ void tst_QDirListing::testQFsFileEngineIterator()
|
|||||||
|
|
||||||
void tst_QDirListing::absoluteFilePathsFromRelativeIteratorPath()
|
void tst_QDirListing::absoluteFilePathsFromRelativeIteratorPath()
|
||||||
{
|
{
|
||||||
for (const auto &dirEntry : QDirListing(u"entrylist/"_s, QDir::NoDotAndDotDot))
|
for (const auto &dirEntry : QDirListing(u"entrylist/"_s, QDirListing::IteratorFlag::Recursive))
|
||||||
QVERIFY(dirEntry.absoluteFilePath().contains("entrylist"));
|
QVERIFY(dirEntry.absoluteFilePath().contains("entrylist"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,12 +572,11 @@ void tst_QDirListing::recurseWithFilters() const
|
|||||||
expectedEntries.insert(QString::fromLatin1("recursiveDirs/dir1/textFileB.txt"));
|
expectedEntries.insert(QString::fromLatin1("recursiveDirs/dir1/textFileB.txt"));
|
||||||
expectedEntries.insert(QString::fromLatin1("recursiveDirs/textFileA.txt"));
|
expectedEntries.insert(QString::fromLatin1("recursiveDirs/textFileA.txt"));
|
||||||
|
|
||||||
for (const auto &dirEntry : QDirListing(u"recursiveDirs/"_s, QStringList{u"*.txt"_s},
|
constexpr auto flags = ItFlag::ExcludeDirs | ItFlag::ExcludeSpecial| ItFlag::Recursive;
|
||||||
QDir::Files, ItFlag::Recursive)) {
|
for (const auto &dirEntry : QDirListing(u"recursiveDirs/"_s, QStringList{u"*.txt"_s}, flags))
|
||||||
actualEntries.insert(dirEntry.filePath());
|
actualEntries.insert(dirEntry.filePath());
|
||||||
}
|
|
||||||
|
|
||||||
QCOMPARE(actualEntries, expectedEntries);
|
QCOMPARE_EQ(actualEntries, expectedEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QDirListing::longPath()
|
void tst_QDirListing::longPath()
|
||||||
@ -518,7 +592,8 @@ void tst_QDirListing::longPath()
|
|||||||
dirName.append('x');
|
dirName.append('x');
|
||||||
}
|
}
|
||||||
|
|
||||||
QDirListing dirList(dir.absolutePath(), QDir::NoDotAndDotDot|QDir::Dirs, ItFlag::Recursive);
|
constexpr auto flags = ItFlag::ExcludeFiles | ItFlag::ExcludeSpecial| ItFlag::Recursive;
|
||||||
|
QDirListing dirList(dir.absolutePath(), flags);
|
||||||
qsizetype m = 0;
|
qsizetype m = 0;
|
||||||
for (auto it = dirList.begin(); it != dirList.end(); ++it)
|
for (auto it = dirList.begin(); it != dirList.end(); ++it)
|
||||||
++m;
|
++m;
|
||||||
@ -562,8 +637,7 @@ void tst_QDirListing::uncPaths_data()
|
|||||||
void tst_QDirListing::uncPaths()
|
void tst_QDirListing::uncPaths()
|
||||||
{
|
{
|
||||||
QFETCH(QString, dirName);
|
QFETCH(QString, dirName);
|
||||||
constexpr auto dirFilters = QDir::AllEntries | QDir::NoDotAndDotDot;
|
for (const auto &dirEntry : QDirListing(dirName, ItFlag::Recursive)) {
|
||||||
for (const auto &dirEntry : QDirListing(dirName, dirFilters, ItFlag::Recursive)) {
|
|
||||||
const QString &filePath = dirEntry.filePath();
|
const QString &filePath = dirEntry.filePath();
|
||||||
QCOMPARE(filePath, QDir::cleanPath(filePath));
|
QCOMPARE(filePath, QDir::cleanPath(filePath));
|
||||||
}
|
}
|
||||||
@ -588,15 +662,13 @@ void tst_QDirListing::hiddenFiles()
|
|||||||
};
|
};
|
||||||
expected.sort();
|
expected.sort();
|
||||||
|
|
||||||
constexpr auto filters = QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot;
|
constexpr auto flags = ItFlag::ExcludeDirs | ItFlag::IncludeHidden | ItFlag::Recursive;
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list.reserve(expected.size());
|
list.reserve(expected.size());
|
||||||
for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters,
|
for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, flags)) {
|
||||||
ItFlag::Recursive)) {
|
|
||||||
QVERIFY(dirEntry.isFile());
|
QVERIFY(dirEntry.isFile());
|
||||||
list.emplace_back(dirEntry.filePath());
|
list.emplace_back(dirEntry.filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
list.sort();
|
list.sort();
|
||||||
|
|
||||||
QCOMPARE_EQ(list, expected);
|
QCOMPARE_EQ(list, expected);
|
||||||
@ -614,11 +686,10 @@ void tst_QDirListing::hiddenDirs()
|
|||||||
};
|
};
|
||||||
expected.sort();
|
expected.sort();
|
||||||
|
|
||||||
constexpr auto filters = QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot;
|
constexpr auto flags = ItFlag::ExcludeFiles | ItFlag::IncludeHidden | ItFlag::Recursive;
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list.reserve(expected.size());
|
list.reserve(expected.size());
|
||||||
for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters,
|
for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, flags)) {
|
||||||
ItFlag::Recursive)) {
|
|
||||||
QVERIFY(dirEntry.isDir());
|
QVERIFY(dirEntry.isDir());
|
||||||
list.emplace_back(dirEntry.filePath());
|
list.emplace_back(dirEntry.filePath());
|
||||||
}
|
}
|
||||||
@ -631,7 +702,7 @@ void tst_QDirListing::hiddenDirs()
|
|||||||
|
|
||||||
void tst_QDirListing::withStdAlgorithms()
|
void tst_QDirListing::withStdAlgorithms()
|
||||||
{
|
{
|
||||||
QDirListing dirList(u"entrylist"_s, QDir::AllEntries | QDir::NoDotAndDotDot, ItFlag::Recursive);
|
QDirListing dirList(u"entrylist"_s, ItFlag::Recursive);
|
||||||
|
|
||||||
std::for_each(dirList.cbegin(), dirList.cend(), [](const auto &dirEntry) {
|
std::for_each(dirList.cbegin(), dirList.cend(), [](const auto &dirEntry) {
|
||||||
QVERIFY(dirEntry.absoluteFilePath().contains("entrylist"));
|
QVERIFY(dirEntry.absoluteFilePath().contains("entrylist"));
|
||||||
|
@ -2327,7 +2327,8 @@ public:
|
|||||||
MyEngine(int n) { number = n; }
|
MyEngine(int n) { number = n; }
|
||||||
|
|
||||||
qint64 size() const override { return 123 + number; }
|
qint64 size() const override { return 123 + number; }
|
||||||
QStringList entryList(QDir::Filters, const QStringList &) const override { return QStringList(); }
|
QStringList entryList(QDirListing::IteratorFlags, const QStringList &) const override
|
||||||
|
{ return QStringList(); }
|
||||||
QString fileName(FileName) const override { return name; }
|
QString fileName(FileName) const override { return name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -206,12 +206,14 @@ void tst_QDirIterator::dirlisting()
|
|||||||
{
|
{
|
||||||
QFETCH(QByteArray, dirpath);
|
QFETCH(QByteArray, dirpath);
|
||||||
|
|
||||||
|
using F = QDirListing::IteratorFlag;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
QBENCHMARK {
|
QBENCHMARK {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
QDirListing dir(dirpath, dirFilters, QDirListing::IteratorFlag::Recursive);
|
QDirListing dir(dirpath, F::Recursive | F::IncludeHidden);
|
||||||
|
|
||||||
for (const auto &dirEntry : dir) {
|
for (const auto &dirEntry : dir) {
|
||||||
const auto path = dirEntry.filePath();
|
const auto path = dirEntry.filePath();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user