Skip to content

Commit

Permalink
QFileSystemModel: respect dir filters
Browse files Browse the repository at this point in the history
Given a dir A that has some files and a subdir B, when a model is set to
only show files, setting the root path to A, the filters are initially
respected. Setting the root path to B then back to A, the filters would
be ignored and B would be visible in the model.

Traversing the path elements in node() led to dir B getting added to
the bypassFilters hash table, which made filtersAcceptNode() bypass the
filters.

I couldn't find a commit explaining the logic behind using bypassFilters
(the trail goes cold at the 'Qt 4.5' mega commit). The only clue I found
was the "// always accept drives" comment in the code, which hints at
this being useful only on Windows(?).

Fixes: QTBUG-74471
Pick-to: 6.7 6.6 6.5
Change-Id: Icb9055524a28990c591e924634a63e29a49835aa
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
  • Loading branch information
ahmadsamir authored and vohi committed Jan 26, 2024
1 parent 5e237f1 commit 83e5d74
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/gui/itemmodels/qfilesystemmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2126,8 +2126,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
Expand All @@ -2136,7 +2142,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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <algorithm>

using namespace Qt::StringLiterals;
using namespace std::chrono;

#define WAITTIME 1000

Expand Down Expand Up @@ -79,6 +80,8 @@ private slots:
void filters_data();
void filters();

void showFilesOnly();

void nameFilters();

void setData_data();
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 83e5d74

Please sign in to comment.