summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-07-09 13:22:26 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-08-13 17:26:22 +0200
commit9cae146c42376868432040bf7427c0b995f2bb64 (patch)
tree62e52e28b69768721c199ff1ff157d4afd8f72e7
parente8c7124768b0e3e556a8ae53629478284bbdca8e (diff)
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>
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp117
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h20
2 files changed, 107 insertions, 30 deletions
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 9ab75e0b0a..0beca82f28 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -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));
}
}
}
diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h
index 829c620c1e..3d30a98d04 100644
--- a/src/widgets/dialogs/qfileinfogatherer_p.h
+++ b/src/widgets/dialogs/qfileinfogatherer_p.h
@@ -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