QFileInfoGatherer: Make it possible to turn off file watching
Add a boolean watch property and delay-create the file system watcher in watchPaths(). De-inline the watchedFiles(), watchedDirectories(), watchPaths(), unwatchPaths() helpers and a check for the watcher. Task-number: QTBUG-76493 Change-Id: Ie02ac496c8c0246be62bc67ff7e0fcdb990b5ca6 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
e8c7124768
commit
9cae146c42
@ -82,21 +82,6 @@ QFileInfoGatherer::QFileInfoGatherer(QObject *parent)
|
||||
: QThread(parent)
|
||||
, m_iconProvider(&defaultProvider)
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
watcher = new QFileSystemWatcher(this);
|
||||
connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(list(QString)));
|
||||
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(updateFile(QString)));
|
||||
|
||||
# if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
const QVariant listener = watcher->property("_q_driveListener");
|
||||
if (listener.canConvert<QObject *>()) {
|
||||
if (QObject *driveListener = listener.value<QObject *>()) {
|
||||
connect(driveListener, SIGNAL(driveAdded()), this, SLOT(driveAdded()));
|
||||
connect(driveListener, SIGNAL(driveRemoved()), this, SLOT(driveRemoved()));
|
||||
}
|
||||
}
|
||||
# endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
#endif
|
||||
start(LowPriority);
|
||||
}
|
||||
|
||||
@ -177,8 +162,8 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr
|
||||
if (files.isEmpty()
|
||||
&& !path.isEmpty()
|
||||
&& !path.startsWith(QLatin1String("//")) /*don't watch UNC path*/) {
|
||||
if (!watcher->directories().contains(path))
|
||||
watcher->addPath(path);
|
||||
if (!watchedDirectories().contains(path))
|
||||
watchPaths(QStringList(path));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -195,6 +180,91 @@ void QFileInfoGatherer::updateFile(const QString &filePath)
|
||||
fetchExtendedInformation(dir, QStringList(fileName));
|
||||
}
|
||||
|
||||
QStringList QFileInfoGatherer::watchedFiles() const
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
if (m_watcher)
|
||||
return m_watcher->files();
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QFileInfoGatherer::watchedDirectories() const
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
if (m_watcher)
|
||||
return m_watcher->directories();
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
void QFileInfoGatherer::createWatcher()
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
m_watcher = new QFileSystemWatcher(this);
|
||||
connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &QFileInfoGatherer::list);
|
||||
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &QFileInfoGatherer::updateFile);
|
||||
# if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
const QVariant listener = m_watcher->property("_q_driveListener");
|
||||
if (listener.canConvert<QObject *>()) {
|
||||
if (QObject *driveListener = listener.value<QObject *>()) {
|
||||
connect(driveListener, SIGNAL(driveAdded()), this, SLOT(driveAdded()));
|
||||
connect(driveListener, SIGNAL(driveRemoved()), this, SLOT(driveRemoved()));
|
||||
}
|
||||
}
|
||||
# endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
#endif
|
||||
}
|
||||
|
||||
void QFileInfoGatherer::watchPaths(const QStringList &paths)
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
if (m_watching) {
|
||||
if (m_watcher == nullptr)
|
||||
createWatcher();
|
||||
m_watcher->addPaths(paths);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(paths);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QFileInfoGatherer::unwatchPaths(const QStringList &paths)
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
if (m_watcher)
|
||||
m_watcher->removePaths(paths);
|
||||
#else
|
||||
Q_UNUSED(paths);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QFileInfoGatherer::isWatching() const
|
||||
{
|
||||
bool result = false;
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
QMutexLocker locker(&mutex);
|
||||
result = m_watching;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void QFileInfoGatherer::setWatching(bool v)
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
QMutexLocker locker(&mutex);
|
||||
if (v != m_watching) {
|
||||
if (!v) {
|
||||
delete m_watcher;
|
||||
m_watcher = nullptr;
|
||||
}
|
||||
m_watching = v;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
List all files in \a directoryPath
|
||||
|
||||
@ -204,8 +274,8 @@ void QFileInfoGatherer::clear()
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
QMutexLocker locker(&mutex);
|
||||
watcher->removePaths(watcher->files());
|
||||
watcher->removePaths(watcher->directories());
|
||||
unwatchPaths(watchedFiles());
|
||||
unwatchPaths(watchedDirectories());
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -218,7 +288,7 @@ void QFileInfoGatherer::removePath(const QString &path)
|
||||
{
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
QMutexLocker locker(&mutex);
|
||||
watcher->removePath(path);
|
||||
unwatchPaths(QStringList(path));
|
||||
#else
|
||||
Q_UNUSED(path);
|
||||
#endif
|
||||
@ -265,12 +335,13 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
|
||||
static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES");
|
||||
if (watchFiles) {
|
||||
if (!fileInfo.exists() && !fileInfo.isSymLink()) {
|
||||
watcher->removePath(fileInfo.absoluteFilePath());
|
||||
const_cast<QFileInfoGatherer *>(this)->
|
||||
unwatchPaths(QStringList(fileInfo.absoluteFilePath()));
|
||||
} else {
|
||||
const QString path = fileInfo.absoluteFilePath();
|
||||
if (!path.isEmpty() && fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable()
|
||||
&& !watcher->files().contains(path)) {
|
||||
watcher->addPath(path);
|
||||
&& !watchedFiles().contains(path)) {
|
||||
const_cast<QFileInfoGatherer *>(this)->watchPaths(QStringList(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,12 +169,13 @@ public:
|
||||
explicit QFileInfoGatherer(QObject *parent = nullptr);
|
||||
~QFileInfoGatherer();
|
||||
|
||||
#if QT_CONFIG(filesystemwatcher) && defined(Q_OS_WIN)
|
||||
QStringList watchedFiles() const { return watcher->files(); }
|
||||
QStringList watchedDirectories() const { return watcher->directories(); }
|
||||
void watchPaths(const QStringList &paths) { watcher->addPaths(paths); }
|
||||
void unwatchPaths(const QStringList &paths) { watcher->removePaths(paths); }
|
||||
#endif // filesystemwatcher && Q_OS_WIN
|
||||
QStringList watchedFiles() const;
|
||||
QStringList watchedDirectories() const;
|
||||
void watchPaths(const QStringList &paths);
|
||||
void unwatchPaths(const QStringList &paths);
|
||||
|
||||
bool isWatching() const;
|
||||
void setWatching(bool v);
|
||||
|
||||
// only callable from this->thread():
|
||||
void clear();
|
||||
@ -201,6 +202,8 @@ private:
|
||||
void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime, QVector<QPair<QString, QFileInfo> > &updatedFiles, const QString &path);
|
||||
|
||||
private:
|
||||
void createWatcher();
|
||||
|
||||
mutable QMutex mutex;
|
||||
// begin protected by mutex
|
||||
QWaitCondition condition;
|
||||
@ -210,13 +213,16 @@ private:
|
||||
QAtomicInt abort;
|
||||
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
QFileSystemWatcher *watcher = nullptr;
|
||||
QFileSystemWatcher *m_watcher = nullptr;
|
||||
#endif
|
||||
QFileIconProvider *m_iconProvider; // not accessed by run()
|
||||
QFileIconProvider defaultProvider;
|
||||
#ifdef Q_OS_WIN
|
||||
bool m_resolveSymlinks = true; // not accessed by run()
|
||||
#endif
|
||||
#if QT_CONFIG(filesystemwatcher)
|
||||
bool m_watching = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user