otherwise the fileChanged() signal is emitted when \a path is
modified, renamed or removed.
- \note There is a system dependent limit to the number of files and
- directories that can be monitored simultaneously. If this limit
- has been reached, \a path will not be added to the file system
- watcher, and a warning message will be printed to \e{stderr}.
+ If the watch was successful, true is returned.
+
+ Reasons for a watch failure are generally system-dependent, but
+ may include the resource not existing, access failures, or the
+ total watch count limit, if the platform has one.
+
+ \note There may be a system dependent limit to the number of
+ files and directories that can be monitored simultaneously.
+ If this limit is been reached, \a path will not be monitored,
+ and false is returned.
\sa addPaths(), removePath()
*/
-void QFileSystemWatcher::addPath(const QString &path)
+bool QFileSystemWatcher::addPath(const QString &path)
{
if (path.isEmpty()) {
qWarning("QFileSystemWatcher::addPath: path is empty");
- return;
+ return true;
}
- addPaths(QStringList(path));
+
+ QStringList paths = addPaths(QStringList(path));
+ return paths.isEmpty();
}
/*!
otherwise the fileChanged() signal is emitted when the path is
modified, renamed, or removed.
- \note There is a system dependent limit to the number of files and
- directories that can be monitored simultaneously. If this limit
- has been reached, the excess \a paths will not be added to the
- file system watcher, and a warning message will be printed to
- \e{stderr} for each path that could not be added.
+ The return value is a list of paths that could not be watched.
+
+ Reasons for a watch failure are generally system-dependent, but
+ may include the resource not existing, access failures, or the
+ total watch count limit, if the platform has one.
+
+ \note There may be a system dependent limit to the number of
+ files and directories that can be monitored simultaneously.
+ If this limit has been reached, the excess \a paths will not
+ be monitored, and they will be added to the returned QStringList.
\sa addPath(), removePaths()
*/
-void QFileSystemWatcher::addPaths(const QStringList &paths)
+QStringList QFileSystemWatcher::addPaths(const QStringList &paths)
{
Q_D(QFileSystemWatcher);
- if (paths.isEmpty()) {
+
+ QStringList p = paths;
+ QMutableListIterator<QString> it(p);
+
+ while (it.hasNext()) {
+ const QString &path = it.next();
+ if (path.isEmpty())
+ it.remove();
+ }
+
+ if (p.isEmpty()) {
qWarning("QFileSystemWatcher::addPaths: list is empty");
- return;
+ return QStringList();
}
- QStringList p = paths;
QFileSystemWatcherEngine *engine = 0;
if(!objectName().startsWith(QLatin1String("_qt_autotest_force_engine_"))) {
if(engine)
p = engine->addPaths(p, &d->files, &d->directories);
- if (!p.isEmpty())
- qWarning("QFileSystemWatcher: failed to add paths: %s",
- qPrintable(p.join(QLatin1String(", "))));
+ return p;
}
/*!
Removes the specified \a path from the file system watcher.
+ If the watch is successfully removed, true is returned.
+
+ Reasons for watch removal failing are generally system-dependent,
+ but may be due to the path having already been deleted, for example.
+
\sa removePaths(), addPath()
*/
-void QFileSystemWatcher::removePath(const QString &path)
+bool QFileSystemWatcher::removePath(const QString &path)
{
if (path.isEmpty()) {
qWarning("QFileSystemWatcher::removePath: path is empty");
- return;
+ return true;
}
- removePaths(QStringList(path));
+
+ QStringList paths = removePaths(QStringList(path));
+ return paths.isEmpty();
}
/*!
Removes the specified \a paths from the file system watcher.
+ The return value is a list of paths which were not able to be
+ unwatched successfully.
+
+ Reasons for watch removal failing are generally system-dependent,
+ but may be due to the path having already been deleted, for example.
+
\sa removePath(), addPaths()
*/
-void QFileSystemWatcher::removePaths(const QStringList &paths)
+QStringList QFileSystemWatcher::removePaths(const QStringList &paths)
{
- if (paths.isEmpty()) {
- qWarning("QFileSystemWatcher::removePaths: list is empty");
- return;
- }
Q_D(QFileSystemWatcher);
+
QStringList p = paths;
+ QMutableListIterator<QString> it(p);
+
+ while (it.hasNext()) {
+ const QString &path = it.next();
+ if (path.isEmpty())
+ it.remove();
+ }
+
+ if (p.isEmpty()) {
+ qWarning("QFileSystemWatcher::removePaths: list is empty");
+ return QStringList();
+ }
+
if (d->native)
p = d->native->removePaths(p, &d->files, &d->directories);
if (d->poller)
p = d->poller->removePaths(p, &d->files, &d->directories);
+
+ return p;
}
/*!
// create watcher, forcing it to use a specific backend
QFileSystemWatcher watcher;
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
- watcher.removePath(testFile.fileName());
- watcher.addPath(testFile.fileName());
+ QVERIFY(watcher.addPath(testFile.fileName()));
QSignalSpy changedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
QVERIFY(changedSpy.isValid());
changedSpy.clear();
// remove the watch and modify the file, should not get a signal from the watcher
- watcher.removePath(testFile.fileName());
+ QVERIFY(watcher.removePath(testFile.fileName()));
testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
testFile.write(QByteArray("hello universe!"));
testFile.close();
QCOMPARE(changedSpy.count(), 0);
// readd the file watch with a relative path
- watcher.addPath(testFile.fileName().prepend("./"));
+ QVERIFY(watcher.addPath(testFile.fileName().prepend("./")));
testFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
testFile.write(QByteArray("hello multiverse!"));
testFile.close();
QTRY_VERIFY(changedSpy.count() > 0);
- watcher.removePath(testFile.fileName().prepend("./"));
+ QVERIFY(watcher.removePath(testFile.fileName().prepend("./")));
changedSpy.clear();
// readd the file watch
- watcher.addPath(testFile.fileName());
+ QVERIFY(watcher.addPath(testFile.fileName()));
// change the permissions, should get a signal from the watcher
testFile.setPermissions(QFile::ReadOwner);
changedSpy.clear();
// remove the watch and modify file permissions, should not get a signal from the watcher
- watcher.removePath(testFile.fileName());
+ QVERIFY(watcher.removePath(testFile.fileName()));
testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOther);
// waiting max 5 seconds for notification for file modification to trigger
QCOMPARE(changedSpy.count(), 0);
// readd the file watch
- watcher.addPath(testFile.fileName());
+ QVERIFY(watcher.addPath(testFile.fileName()));
// remove the file, should get a signal from the watcher
QVERIFY(testFile.remove());
QFileSystemWatcher watcher;
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
- watcher.addPath(testDir.dirName());
+ QVERIFY(watcher.addPath(testDir.dirName()));
QSignalSpy changedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
QVERIFY(changedSpy.isValid());
QString fileName;
// remove the watch, should not get notification of a new file
- watcher.removePath(testDir.dirName());
+ QVERIFY(watcher.removePath(testDir.dirName()));
QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
testFile.close();
QCOMPARE(changedSpy.count(), 0);
- watcher.addPath(testDir.dirName());
+ QVERIFY(watcher.addPath(testDir.dirName()));
// remove the file again, should get a signal from the watcher
QVERIFY(testFile.remove());
{
QFileSystemWatcher watcher;
QString home = QDir::homePath();
- watcher.addPath(home);
+ QVERIFY(watcher.addPath(home));
QCOMPARE(watcher.directories().count(), 1);
QCOMPARE(watcher.directories().first(), home);
- watcher.addPath(home);
+
+ // second watch on an already-watched path should fail
+ QVERIFY(!watcher.addPath(home));
QCOMPARE(watcher.directories().count(), 1);
// With empty string
QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPath: path is empty");
- watcher.addPath(QString());
+ QVERIFY(watcher.addPath(QString()));
}
void tst_QFileSystemWatcher::removePath()
{
QFileSystemWatcher watcher;
QString home = QDir::homePath();
- watcher.addPath(home);
- watcher.removePath(home);
+ QVERIFY(watcher.addPath(home));
+ QVERIFY(watcher.removePath(home));
QCOMPARE(watcher.directories().count(), 0);
- watcher.removePath(home);
+ QVERIFY(!watcher.removePath(home));
QCOMPARE(watcher.directories().count(), 0);
// With empty string
QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::removePath: path is empty");
- watcher.removePath(QString());
+ QVERIFY(watcher.removePath(QString()));
}
void tst_QFileSystemWatcher::addPaths()
QFileSystemWatcher watcher;
QStringList paths;
paths << QDir::homePath() << QDir::currentPath();
- watcher.addPaths(paths);
+ QCOMPARE(watcher.addPaths(paths), QStringList());
QCOMPARE(watcher.directories().count(), 2);
// With empty list
paths.clear();
QTest::ignoreMessage(QtWarningMsg, "QFileSystemWatcher::addPaths: list is empty");
- watcher.addPaths(paths);
+ QCOMPARE(watcher.addPaths(paths), QStringList());
}
void tst_QFileSystemWatcher::removePaths()
QFileSystemWatcher watcher;
QStringList paths;
paths << QDir::homePath() << QDir::currentPath();
- watcher.addPaths(paths);
+ QCOMPARE(watcher.addPaths(paths), QStringList());
QCOMPARE(watcher.directories().count(), 2);
- watcher.removePaths(paths);
+ QCOMPARE(watcher.removePaths(paths), QStringList());
QCOMPARE(watcher.directories().count(), 0);
//With empty list
QFileSystemWatcher watcher;
watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend);
- watcher.addPath(testDir.dirName());
- watcher.addPath(testFileName);
+ QVERIFY(watcher.addPath(testDir.dirName()));
+ QVERIFY(watcher.addPath(testFileName));
QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(const QString &)));
QSignalSpy dirChangedSpy(&watcher, SIGNAL(directoryChanged(const QString &)));
fileChangedSpy.clear();
dirChangedSpy.clear();
- watcher.removePath(testFileName);
+ // removing a deleted file should fail
+ QVERIFY(!watcher.removePath(testFileName));
QFile::remove(secondFileName);
timer.start(3000);
{
// Don't crash...
QFileSystemWatcher watcher;
- watcher.addPath("file_that_does_not_exist.txt");
- QVERIFY(true);
+ QVERIFY(!watcher.addPath("file_that_does_not_exist.txt"));
+
+ // Test that the paths returned in error aren't messed with
+ QCOMPARE(watcher.addPaths(QStringList() << "../..//./does-not-exist"),
+ QStringList() << "../..//./does-not-exist");
+
+ // empty path is not actually a failure
+ QCOMPARE(watcher.addPaths(QStringList() << QString()), QStringList());
+
+ // empty path is not actually a failure
+ QCOMPARE(watcher.removePaths(QStringList() << QString()), QStringList());
}
void tst_QFileSystemWatcher::removeFileAndUnWatch()
testFile.open(QIODevice::WriteOnly);
testFile.close();
}
- watcher.addPath(filename);
+ QVERIFY(watcher.addPath(filename));
QFile::remove(filename);
- watcher.removePath(filename);
+ QVERIFY(watcher.removePath(filename));
{
QFile testFile(filename);
testFile.open(QIODevice::WriteOnly);
testFile.close();
}
- watcher.addPath(filename);
+ QVERIFY(watcher.addPath(filename));
}
class SomeSingleton : public QObject