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