Mercurial > hg > easyhg
comparison src/fswatcher.h @ 548:dca5bd5b2a06
Merge from branch "fswatcher"
author | Chris Cannam |
---|---|
date | Tue, 14 Feb 2012 17:55:39 +0000 |
parents | 7829da6abe97 |
children | 533519ebc0cb |
comparison
equal
deleted
inserted
replaced
537:a4e699d32a9a | 548:dca5bd5b2a06 |
---|---|
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 #ifndef FSWATCHER_H | |
19 #define FSWATCHER_H | |
20 | |
21 #include <QObject> | |
22 #include <QMutex> | |
23 #include <QString> | |
24 #include <QSet> | |
25 #include <QHash> | |
26 #include <QMap> | |
27 #include <QStringList> | |
28 #include <QFileSystemWatcher> | |
29 | |
30 class FsWatcher : public QObject | |
31 { | |
32 Q_OBJECT | |
33 | |
34 public: | |
35 FsWatcher(); | |
36 virtual ~FsWatcher(); | |
37 | |
38 /** | |
39 * Set the root path of the work directory to be monitored. This | |
40 * directory and all its subdirectories (recursively) will be | |
41 * monitored for changes. | |
42 * | |
43 * If this path differs from the currently set work dir path, then | |
44 * the tracked file paths will also be cleared. Call | |
45 * setTrackedFilePaths afterwards to ensure non-directory files | |
46 * are monitored. | |
47 */ | |
48 void setWorkDirPath(QString path); | |
49 | |
50 /** | |
51 * Provide a set of paths for files which should be tracked. These | |
52 * will be the only non-directory files monitored for changes. The | |
53 * paths should be relative to the work directory. | |
54 */ | |
55 void setTrackedFilePaths(QStringList paths); | |
56 | |
57 /** | |
58 * Provide a set of prefixes to ignore. Files whose names start | |
59 * with a prefix in this set will be ignored when they change. | |
60 */ | |
61 void setIgnoredFilePrefixes(QStringList prefixes); | |
62 | |
63 /** | |
64 * Provide a set of suffixes to ignore. Files whose names end | |
65 * with a suffix in this set will be ignored when they change. | |
66 */ | |
67 void setIgnoredFileSuffixes(QStringList suffixes); | |
68 | |
69 /** | |
70 * Return a token to identify the current caller in subsequent | |
71 * calls to getChangedPaths(). Only changes that occur after this | |
72 * has been called can be detected by the caller. | |
73 */ | |
74 int getNewToken(); | |
75 | |
76 /** | |
77 * Return a list of all non-ignored file paths that have been | |
78 * observed to have changed since the last call to getChangedPaths | |
79 * with the same token. | |
80 */ | |
81 QSet<QString> getChangedPaths(int token); | |
82 | |
83 signals: | |
84 /** | |
85 * Emitted when something has changed. Use the asynchronous | |
86 * interface to find out what. | |
87 */ | |
88 void changed(); | |
89 | |
90 private slots: | |
91 void fsDirectoryChanged(QString); | |
92 void fsFileChanged(QString); | |
93 | |
94 private: | |
95 // call with lock already held | |
96 void addWorkDirectory(QString path); | |
97 | |
98 // call with lock already held | |
99 bool shouldIgnore(QString path); | |
100 | |
101 // call with lock already held. Returns set of non-ignored files in dir | |
102 QSet<QString> scanDirectory(QString path); | |
103 | |
104 // call with lock already held | |
105 void debugPrint(); | |
106 | |
107 private: | |
108 /** | |
109 * A change associates a filename with a counter (the | |
110 * size_t). Each time a file is changed, its counter is assigned | |
111 * from m_lastCounter and m_lastCounter is incremented. | |
112 * | |
113 * This is not especially efficient -- we often want to find "all | |
114 * files whose counter is greater than X" which involves a | |
115 * traversal. Maybe something better later. | |
116 */ | |
117 QHash<QString, size_t> m_changes; | |
118 | |
119 /** | |
120 * Associates a token (the client identifier) with a counter. The | |
121 * counter represents the value of m_lastCounter at the moment | |
122 * getChangedPaths last completed for that token. Any files in | |
123 * m_changes whose counters are larger must have been modified. | |
124 */ | |
125 QMap<int, size_t> m_tokenMap; | |
126 | |
127 /** | |
128 * Associates a directory path with a list of all the files in it | |
129 * that do not match our ignore patterns. When a directory is | |
130 * signalled as having changed, then we need to rescan it and | |
131 * compare against this list before we can determine whether to | |
132 * notify about the change or not. | |
133 */ | |
134 QHash<QString, QSet<QString> > m_dirContents; | |
135 | |
136 QStringList m_ignoredPrefixes; | |
137 QStringList m_ignoredSuffixes; | |
138 | |
139 /// Everything in this class is synchronised. | |
140 QMutex m_mutex; | |
141 | |
142 QString m_workDirPath; | |
143 int m_lastToken; | |
144 size_t m_lastCounter; | |
145 QFileSystemWatcher m_watcher; | |
146 }; | |
147 | |
148 #endif |