QFileSystemModel: Enable experimental code path for per-file watching

QFileSystemModel had a #ifdefed out experimental code path for watching
single files to track changes in size, which got outdated over time.

Replace the #ifdef 0 by a check for the environment variable
QT_FILESYSTEMMODEL_WATCH_FILES, fix it up and apply some fixes to
related code to make it work:
- Split file names signaled by QFileSystemWatcher on '/' always.
- Do not instantiate QDirIterator on "", which means "current directory"
  and results in mixed-up directories.
- Check on lastModified() in QExtendedInformation::operator==() so
  that changes trigger an update in _q_fileSystemChanged().
- Fix the #ifdefed out part to compile and not to add directories
  to the watcher.

[ChangeLog][QtWidgets][QFileSystemModel] It is now possible to enable
per-file watching by setting the environment variable
QT_FILESYSTEMMODEL_WATCH_FILES, allowing to track for example
changes in file size.

Task-number: QTBUG-46684
Change-Id: Ia5da9170866416c9529251f889814b23d7a7d069
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Friedemann Kleint 2017-07-28 09:00:18 +02:00
parent 81b5155e82
commit 9e1b6b6e53
2 changed files with 20 additions and 18 deletions

View File

@ -196,7 +196,7 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr
*/
void QFileInfoGatherer::updateFile(const QString &filePath)
{
QString dir = filePath.mid(0, filePath.lastIndexOf(QDir::separator()));
QString dir = filePath.mid(0, filePath.lastIndexOf(QLatin1Char('/')));
QString fileName = filePath.mid(dir.length() + 1);
fetchExtendedInformation(dir, QStringList(fileName));
}
@ -267,19 +267,19 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
info.icon = m_iconProvider->icon(fileInfo);
info.displayType = m_iconProvider->type(fileInfo);
#ifndef QT_NO_FILESYSTEMWATCHER
// ### Not ready to listen all modifications
#if 0
// Enable the next two commented out lines to get updates when the file sizes change...
// ### Not ready to listen all modifications by default
static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES");
if (watchFiles) {
if (!fileInfo.exists() && !fileInfo.isSymLink()) {
info.size = -1;
//watcher->removePath(fileInfo.absoluteFilePath());
watcher->removePath(fileInfo.absoluteFilePath());
} else {
if (!fileInfo.absoluteFilePath().isEmpty() && fileInfo.exists() && fileInfo.isReadable()
&& !watcher->files().contains(fileInfo.absoluteFilePath())) {
//watcher->addPath(fileInfo.absoluteFilePath());
const QString path = fileInfo.absoluteFilePath();
if (!path.isEmpty() && fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable()
&& !watcher->files().contains(path)) {
watcher->addPath(path);
}
}
#endif
}
#endif
#ifdef Q_OS_WIN
@ -329,14 +329,15 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
QVector<QPair<QString, QFileInfo> > updatedFiles;
QStringList filesToCheck = files;
QString itPath = QDir::fromNativeSeparators(files.isEmpty() ? path : QLatin1String(""));
QDirIterator dirIt(itPath, QDir::AllEntries | QDir::System | QDir::Hidden);
QStringList allFiles;
while (!abort.load() && dirIt.hasNext()) {
dirIt.next();
fileInfo = dirIt.fileInfo();
allFiles.append(fileInfo.fileName());
fetch(fileInfo, base, firstTime, updatedFiles, path);
if (files.isEmpty()) {
QDirIterator dirIt(path, QDir::AllEntries | QDir::System | QDir::Hidden);
while (!abort.load() && dirIt.hasNext()) {
dirIt.next();
fileInfo = dirIt.fileInfo();
allFiles.append(fileInfo.fileName());
fetch(fileInfo, base, firstTime, updatedFiles, path);
}
}
if (!allFiles.isEmpty())
emit newListOfFiles(path, allFiles);

View File

@ -84,7 +84,8 @@ public:
bool operator ==(const QExtendedInformation &fileInfo) const {
return mFileInfo == fileInfo.mFileInfo
&& displayType == fileInfo.displayType
&& permissions() == fileInfo.permissions();
&& permissions() == fileInfo.permissions()
&& lastModified() == fileInfo.lastModified();
}
#ifndef QT_NO_FSFILEENGINE