nextcloud-desktop/src/mirall/folderwatcher.cpp
Duncan Mac-Vicar P bd5effe78c - fix inotify/folderwatcher so that it uses full paths
- make the test pass using QSignalSpy
2011-03-18 13:54:32 +01:00

116 lines
3.1 KiB
C++

// event masks
#include <sys/inotify.h>
#include <QFileInfo>
#include <QFlags>
#include <QDebug>
#include <QDir>
#include <QMutexLocker>
#include <QStringList>
#include <QTimer>
#include "mirall/inotify.h"
#include "mirall/folderwatcher.h"
static const uint32_t standard_event_mask =
IN_MODIFY | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ISDIR | IN_DONT_FOLLOW;
namespace Mirall {
enum SubFolderListOption {
SubFolderNoOptions = 0x0,
SubFolderRecursive = 0x1,
};
Q_DECLARE_FLAGS(SubFolderListOptions, SubFolderListOption)
Q_DECLARE_OPERATORS_FOR_FLAGS(SubFolderListOptions)
// Forgive me using a bool as a flag
static QStringList subFoldersList(QString folder,
SubFolderListOptions options = SubFolderNoOptions )
{
QDir dir(folder);
dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
QFileInfoList list = dir.entryInfoList();
QStringList dirList;
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
dirList << fileInfo.absoluteFilePath();
if (options & SubFolderRecursive )
dirList << subFoldersList(fileInfo.absoluteFilePath(), options);
}
return dirList;
}
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
: QObject(parent),
_root(root)
{
_inotify = new INotify(standard_event_mask);
slotAddFolderRecursive(root);
QObject::connect(_inotify, SIGNAL(notifyEvent(int, const QString &)),
SLOT(slotDirectoryChanged(int, const QString &)));
}
FolderWatcher::~FolderWatcher()
{
}
QStringList FolderWatcher::folders() const
{
return _inotify->directories();
}
void FolderWatcher::slotAddFolderRecursive(const QString &path)
{
qDebug() << "Recursive adding " << path;
QStringList watchedFolders(_inotify->directories());
qDebug() << "currently watching " << watchedFolders;
QStringListIterator subfoldersIt(subFoldersList(path, SubFolderRecursive));
while (subfoldersIt.hasNext()) {
QDir folder (subfoldersIt.next());
if (folder.exists() && !watchedFolders.contains(folder.path())) {
qDebug() << "`-> adding " << folder.path();
_inotify->addPath(folder.path());
}
else
qDebug() << "`-> discarding " << folder.path();
}
qDebug() << "`-> adding " << path;
_inotify->addPath(path);
}
void FolderWatcher::slotDirectoryChanged(int mask, const QString &path)
{
QMutexLocker locker(&_mutex);
if (mask & IN_CREATE) {
qDebug() << "CREATE: " << path;
if (QFileInfo(path).isDir()) {
slotAddFolderRecursive(path);
}
}
else if (mask & IN_DELETE) {
qDebug() << "DELETE: " << path;
if (_inotify->directories().contains(path));
qDebug() << "`-> removing " << path;
_inotify->removePath(path);
}
else if (mask & IN_MODIFY) {
qDebug() << "MODIFIED: " << path;
}
else if (mask & IN_MOVE) {
qDebug() << "MOVE: " << path;
}
else {
qDebug() << "OTHER " << mask << " :" << path;
}
emit folderChanged(path);
}
}
#include "folderwatcher.moc"