annotate src/fswatcher.cpp @ 538:bdc9de794839 fswatcher

Start separate FsWatcher class to manage filesystem watch policy
author Chris Cannam
date Fri, 10 Feb 2012 17:53:04 +0000
parents
children 3935a7e621ca
rev   line source
Chris@538 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@538 2
Chris@538 3 /*
Chris@538 4 EasyMercurial
Chris@538 5
Chris@538 6 Based on hgExplorer by Jari Korhonen
Chris@538 7 Copyright (c) 2010 Jari Korhonen
Chris@538 8 Copyright (c) 2011 Chris Cannam
Chris@538 9 Copyright (c) 2011 Queen Mary, University of London
Chris@538 10
Chris@538 11 This program is free software; you can redistribute it and/or
Chris@538 12 modify it under the terms of the GNU General Public License as
Chris@538 13 published by the Free Software Foundation; either version 2 of the
Chris@538 14 License, or (at your option) any later version. See the file
Chris@538 15 COPYING included with this distribution for more information.
Chris@538 16 */
Chris@538 17
Chris@538 18 #include "fswatcher.h"
Chris@538 19
Chris@538 20 #include <QMutexLocker>
Chris@538 21 #include <QDir>
Chris@538 22
Chris@538 23 #include <deque>
Chris@538 24
Chris@538 25 FsWatcher::FsWatcher() :
Chris@538 26 m_lastToken(0),
Chris@538 27 m_lastCounter(0)
Chris@538 28 {
Chris@538 29 connect(&m_watcher, SIGNAL(directoryChanged(QString)),
Chris@538 30 this, SLOT(fsDirectoryChanged(QString)));
Chris@538 31 connect(&m_watcher, SIGNAL(fileChanged(QString)),
Chris@538 32 this, SLOT(fsFileChanged(QString)));
Chris@538 33 }
Chris@538 34
Chris@538 35 FsWatcher::~FsWatcher()
Chris@538 36 {
Chris@538 37 }
Chris@538 38
Chris@538 39 void
Chris@538 40 FsWatcher::setWorkDirPath(QString path)
Chris@538 41 {
Chris@538 42 QMutexLocker locker(&m_mutex);
Chris@538 43 m_watcher.removePaths(m_watcher.directories());
Chris@538 44 m_watcher.removePaths(m_watcher.files());
Chris@538 45 m_workDirPath = path;
Chris@538 46 addWorkDirectory(path);
Chris@538 47 }
Chris@538 48
Chris@538 49 void
Chris@538 50 FsWatcher::addWorkDirectory(QString path)
Chris@538 51 {
Chris@538 52 // QFileSystemWatcher will refuse to add a file or directory to
Chris@538 53 // its watch list that it is already watching -- fine -- but it
Chris@538 54 // prints a warning when this happens, which we wouldn't want. So
Chris@538 55 // we'll check for duplicates ourselves.
Chris@538 56 QSet<QString> alreadyWatched =
Chris@538 57 QSet<QString>::fromList(m_watcher.directories());
Chris@538 58
Chris@538 59 std::deque<QString> pending;
Chris@538 60 pending.push_back(path);
Chris@538 61
Chris@538 62 while (!pending.empty()) {
Chris@538 63
Chris@538 64 QString path = pending.front();
Chris@538 65 pending.pop_front();
Chris@538 66 if (!alreadyWatched.contains(path)) {
Chris@538 67 m_watcher.addPath(path);
Chris@538 68 }
Chris@538 69
Chris@538 70 QDir d(path);
Chris@538 71 if (d.exists()) {
Chris@538 72 d.setFilter(QDir::Dirs | QDir::NoDotAndDotDot |
Chris@538 73 QDir::Readable | QDir::NoSymLinks);
Chris@538 74 foreach (QString entry, d.entryList()) {
Chris@538 75 if (entry.startsWith('.')) continue;
Chris@538 76 QString entryPath = d.absoluteFilePath(entry);
Chris@538 77 pending.push_back(entryPath);
Chris@538 78 }
Chris@538 79 }
Chris@538 80 }
Chris@538 81 }
Chris@538 82
Chris@538 83 void
Chris@538 84 FsWatcher::setIgnoredFilePrefixes(QStringList prefixes)
Chris@538 85 {
Chris@538 86 QMutexLocker locker(&m_mutex);
Chris@538 87 m_ignoredPrefixes = prefixes;
Chris@538 88 }
Chris@538 89
Chris@538 90 void
Chris@538 91 FsWatcher::setIgnoredFileSuffixes(QStringList suffixes)
Chris@538 92 {
Chris@538 93 QMutexLocker locker(&m_mutex);
Chris@538 94 m_ignoredSuffixes = suffixes;
Chris@538 95 }
Chris@538 96
Chris@538 97 int
Chris@538 98 FsWatcher::getNewToken()
Chris@538 99 {
Chris@538 100 QMutexLocker locker(&m_mutex);
Chris@538 101 int token = ++m_lastToken;
Chris@538 102 m_tokenMap[token] = m_lastCounter;
Chris@538 103 return token;
Chris@538 104 }
Chris@538 105
Chris@538 106 QSet<QString>
Chris@538 107 FsWatcher::getChangedPaths(int token)
Chris@538 108 {
Chris@538 109 QMutexLocker locker(&m_mutex);
Chris@538 110 size_t lastUpdatedAt = m_tokenMap[token];
Chris@538 111 QSet<QString> changed;
Chris@538 112 for (QHash<QString, size_t>::const_iterator i = m_changes.begin();
Chris@538 113 i != m_changes.end(); ++i) {
Chris@538 114 if (i.value() > lastUpdatedAt) {
Chris@538 115 changed.insert(i.key());
Chris@538 116 }
Chris@538 117 }
Chris@538 118 m_tokenMap[token] = m_lastCounter;
Chris@538 119 return changed;
Chris@538 120 }
Chris@538 121
Chris@538 122 void
Chris@538 123 FsWatcher::fsDirectoryChanged(QString path)
Chris@538 124 {
Chris@538 125 {
Chris@538 126 QMutexLocker locker(&m_mutex);
Chris@538 127 if (shouldIgnore(path)) return;
Chris@538 128 size_t counter = ++m_lastCounter;
Chris@538 129 m_changes[path] = counter;
Chris@538 130 }
Chris@538 131 emit changed();
Chris@538 132 }
Chris@538 133
Chris@538 134 void
Chris@538 135 FsWatcher::fsFileChanged(QString path)
Chris@538 136 {
Chris@538 137 QMutexLocker locker(&m_mutex);
Chris@538 138 }
Chris@538 139
Chris@538 140 bool
Chris@538 141 FsWatcher::shouldIgnore(QString path)
Chris@538 142 {
Chris@538 143
Chris@538 144 }
Chris@538 145