diff --git a/src/gui/itemmodels/qfilesystemmodel.cpp b/src/gui/itemmodels/qfilesystemmodel.cpp index 482b8537d51..6b717baaa93 100644 --- a/src/gui/itemmodels/qfilesystemmodel.cpp +++ b/src/gui/itemmodels/qfilesystemmodel.cpp @@ -2124,8 +2124,14 @@ void QFileSystemModelPrivate::init() */ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) const { + // When the model is set to only show files, then a node representing a dir + // should be hidden regardless of bypassFilters. + // QTBUG-74471 + const bool hideDirs = (filters & (QDir::Dirs | QDir::AllDirs)) == 0; + const bool shouldHideDirNode = hideDirs && node->isDir(); + // always accept drives - if (node->parent == &root || bypassFilters.contains(node)) + if (node->parent == &root || (!shouldHideDirNode && bypassFilters.contains(node))) return true; // If we don't know anything yet don't accept it @@ -2134,7 +2140,6 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co const bool filterPermissions = ((filters & QDir::PermissionMask) && (filters & QDir::PermissionMask) != QDir::PermissionMask); - const bool hideDirs = !(filters & (QDir::Dirs | QDir::AllDirs)); const bool hideFiles = !(filters & QDir::Files); const bool hideReadable = !(!filterPermissions || (filters & QDir::Readable)); const bool hideWritable = !(!filterPermissions || (filters & QDir::Writable)); diff --git a/tests/auto/gui/itemmodels/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/gui/itemmodels/qfilesystemmodel/tst_qfilesystemmodel.cpp index 6f7aa0e1804..483be7c7e49 100644 --- a/tests/auto/gui/itemmodels/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/gui/itemmodels/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -29,6 +29,7 @@ #include using namespace Qt::StringLiterals; +using namespace std::chrono; #define WAITTIME 1000 @@ -79,6 +80,8 @@ private slots: void filters_data(); void filters(); + void showFilesOnly(); + void nameFilters(); void setData_data(); @@ -675,6 +678,37 @@ void tst_QFileSystemModel::filters() #endif } +void tst_QFileSystemModel::showFilesOnly() +{ + QString tmp = flatDirTestPath; + QFileSystemModel model; + QAbstractItemModelTester tester(&model); + tester.setUseFetchMore(false); + QVERIFY(createFiles(&model, tmp, QStringList())); + const QStringList files{u"a"_s, u"b"_s, u"c"_s}; + const auto subdir = u"sub_directory"_s; + QVERIFY(createFiles(&model, tmp, files, 0, {subdir})); + + // QTBUG-74471 + // WHAT: setting the root path of the model to a dir with some files and a subdir + QModelIndex root = model.setRootPath(tmp); + QTRY_COMPARE(model.rowCount(root), files.size() + 1); + + // Change the model to only show files + model.setFilter(QDir::Files); + QTRY_COMPARE(model.rowCount(root), files.size()); + + // WHEN: setting the root path to a subdir + QModelIndex subIndex = model.setRootPath(tmp + u'/' + subdir); + QTRY_COMPARE(model.rowCount(subIndex), 0); + + // THEN: setting the root path to the previous (parent) dir, the model should + // still only show files. + root = model.setRootPath(tmp); + // Doubling the default timeout (5s) as this test to fails on macos on the CI + QTRY_COMPARE_WITH_TIMEOUT(model.rowCount(root), files.size(), (10s).count()); +} + void tst_QFileSystemModel::nameFilters() { QStringList list;