mirror of https://github.com/qt/qtbase.git
QFileSystemModel/Windows: Make file name checking case-insensitive
Introduce a special hash modeled on the one used for QFileSystemWatcher on Windows. Task-number: QTBUG-31103 Task-number: QTBUG-64147 Change-Id: I69ebabe841716e4957ae3fb04fa5c43d233a3552 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
d196036024
commit
fcbaa8ec38
|
@ -1100,8 +1100,8 @@ void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent
|
|||
return;
|
||||
|
||||
QVector<QFileSystemModelPrivate::QFileSystemNode*> values;
|
||||
QHash<QString, QFileSystemNode *>::const_iterator iterator;
|
||||
for(iterator = indexNode->children.constBegin() ; iterator != indexNode->children.constEnd() ; ++iterator) {
|
||||
|
||||
for (auto iterator = indexNode->children.constBegin(), cend = indexNode->children.constEnd(); iterator != cend; ++iterator) {
|
||||
if (filtersAcceptsNode(iterator.value())) {
|
||||
values.append(iterator.value());
|
||||
} else {
|
||||
|
@ -1661,13 +1661,10 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
|
|||
QStringList toRemove;
|
||||
QStringList newFiles = files;
|
||||
std::sort(newFiles.begin(), newFiles.end());
|
||||
QHash<QString, QFileSystemNode*>::const_iterator i = parentNode->children.constBegin();
|
||||
while (i != parentNode->children.constEnd()) {
|
||||
for (auto i = parentNode->children.constBegin(), cend = parentNode->children.constEnd(); i != cend; ++i) {
|
||||
QStringList::iterator iterator = std::lower_bound(newFiles.begin(), newFiles.end(), i.value()->fileName);
|
||||
if ((iterator == newFiles.end()) || (i.value()->fileName < *iterator))
|
||||
toRemove.append(i.value()->fileName);
|
||||
|
||||
++i;
|
||||
}
|
||||
for (int i = 0 ; i < toRemove.count() ; ++i )
|
||||
removeNode(parentNode, toRemove[i]);
|
||||
|
|
|
@ -72,6 +72,23 @@ class ExtendedInformation;
|
|||
class QFileSystemModelPrivate;
|
||||
class QFileIconProvider;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
class QFileSystemModelNodePathKey : public QString
|
||||
{
|
||||
public:
|
||||
QFileSystemModelNodePathKey() {}
|
||||
QFileSystemModelNodePathKey(const QString &other) : QString(other) {}
|
||||
QFileSystemModelNodePathKey(const QFileSystemModelNodePathKey &other) : QString(other) {}
|
||||
bool operator==(const QFileSystemModelNodePathKey &other) const { return !compare(other, Qt::CaseInsensitive); }
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QFileSystemModelNodePathKey, Q_MOVABLE_TYPE);
|
||||
|
||||
inline uint qHash(const QFileSystemModelNodePathKey &key) { return qHash(key.toCaseFolded()); }
|
||||
#else // Q_OS_WIN
|
||||
typedef QString QFileSystemModelNodePathKey;
|
||||
#endif
|
||||
|
||||
class Q_AUTOTEST_EXPORT QFileSystemModelPrivate : public QAbstractItemModelPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFileSystemModel)
|
||||
|
@ -189,7 +206,7 @@ public:
|
|||
|
||||
bool populatedChildren;
|
||||
bool isVisible;
|
||||
QHash<QString,QFileSystemNode *> children;
|
||||
QHash<QFileSystemModelNodePathKey, QFileSystemNode *> children;
|
||||
QList<QString> visibleChildren;
|
||||
int dirtyChildrenIndex;
|
||||
QFileSystemNode *parent;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#if defined(Q_OS_WIN)
|
||||
# include <qt_windows.h> // for SetFileAttributes
|
||||
#endif
|
||||
#include <private/qfilesystemengine_p.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -883,6 +884,18 @@ void tst_QFileSystemModel::deleteFile()
|
|||
QVERIFY(!newFile.exists());
|
||||
}
|
||||
|
||||
static QString flipCase(QString s)
|
||||
{
|
||||
for (int i = 0, size = s.size(); i < size; ++i) {
|
||||
const QChar c = s.at(i);
|
||||
if (c.isUpper())
|
||||
s[i] = c.toLower();
|
||||
else if (c.isLower())
|
||||
s[i] = c.toUpper();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void tst_QFileSystemModel::caseSensitivity()
|
||||
{
|
||||
QString tmp = flatDirTestPath;
|
||||
|
@ -890,9 +903,23 @@ void tst_QFileSystemModel::caseSensitivity()
|
|||
files << "a" << "c" << "C";
|
||||
QVERIFY(createFiles(tmp, files));
|
||||
QModelIndex root = model->index(tmp);
|
||||
QStringList paths;
|
||||
QModelIndexList indexes;
|
||||
QCOMPARE(model->rowCount(root), 0);
|
||||
for (int i = 0; i < files.count(); ++i) {
|
||||
QVERIFY(model->index(tmp + '/' + files.at(i)).isValid());
|
||||
const QString path = tmp + '/' + files.at(i);
|
||||
const QModelIndex index = model->index(path);
|
||||
QVERIFY(index.isValid());
|
||||
paths.append(path);
|
||||
indexes.append(index);
|
||||
}
|
||||
|
||||
if (!QFileSystemEngine::isCaseSensitive()) {
|
||||
// QTBUG-31103, QTBUG-64147: Verify that files can be accessed by paths with fLipPeD case.
|
||||
for (int i = 0; i < paths.count(); ++i) {
|
||||
const QModelIndex flippedCaseIndex = model->index(flipCase(paths.at(i)));
|
||||
QCOMPARE(indexes.at(i), flippedCaseIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue