KCoreAddons

kdirwatch.h
1 /*
2  This file is part of the KDE libraries
3 
4  SPDX-FileCopyrightText: 1998 Sven Radej <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-only
7 */
8 #ifndef _KDIRWATCH_H
9 #define _KDIRWATCH_H
10 
11 #include <QDateTime>
12 #include <QObject>
13 #include <QString>
14 
15 #include <kcoreaddons_export.h>
16 
17 class KDirWatchPrivate;
18 
19 /**
20  * @class KDirWatch kdirwatch.h KDirWatch
21  *
22  * @short Class for watching directory and file changes.
23  *
24  * Watch directories and files for changes.
25  * The watched directories or files don't have to exist yet.
26  *
27  * When a watched directory is changed, i.e. when files therein are
28  * created or deleted, KDirWatch will emit the signal dirty().
29  *
30  * When a watched, but previously not existing directory gets created,
31  * KDirWatch will emit the signal created().
32  *
33  * When a watched directory gets deleted, KDirWatch will emit the
34  * signal deleted(). The directory is still watched for new
35  * creation.
36  *
37  * When a watched file is changed, i.e. attributes changed or written
38  * to, KDirWatch will emit the signal dirty().
39  *
40  * Scanning of particular directories or files can be stopped temporarily
41  * and restarted. The whole class can be stopped and restarted.
42  * Directories and files can be added/removed from the list in any state.
43  *
44  * The implementation uses the INOTIFY functionality on LINUX.
45  * Otherwise the FAM service is used, when available.
46  * As a last resort, a regular polling for change of modification times
47  * is done; the polling interval is a global config option:
48  * DirWatch/PollInterval and DirWatch/NFSPollInterval for NFS mounted
49  * directories.
50  * The choice of implementation can be adjusted by the user, with the key
51  * [DirWatch] PreferredMethod={Fam|Stat|QFSWatch|inotify}
52  *
53  * @see self()
54  * @author Sven Radej (in 1998)
55  */
56 class KCOREADDONS_EXPORT KDirWatch : public QObject
57 {
58  Q_OBJECT
59 
60 public:
61  /**
62  * Available watch modes for directory monitoring
63  * @see WatchModes
64  **/
65  enum WatchMode {
66  WatchDirOnly = 0, ///< Watch just the specified directory
67  WatchFiles = 0x01, ///< Watch also all files contained by the directory
68  WatchSubDirs = 0x02, ///< Watch also all the subdirs contained by the directory
69  };
70  /**
71  * Stores a combination of #WatchMode values.
72  */
73  Q_DECLARE_FLAGS(WatchModes, WatchMode)
74 
75  /**
76  * Constructor.
77  *
78  * Scanning begins immediately when a dir/file watch
79  * is added.
80  * @param parent the parent of the QObject (or @c nullptr for parent-less KDataTools)
81  */
82  explicit KDirWatch(QObject *parent = nullptr);
83 
84  /**
85  * Destructor.
86  *
87  * Stops scanning and cleans up.
88  */
89  ~KDirWatch();
90 
91  /**
92  * Adds a directory to be watched.
93  *
94  * The directory does not have to exist. When @p watchModes is set to
95  * WatchDirOnly (the default), the signals dirty(), created(), deleted()
96  * can be emitted, all for the watched directory.
97  * When @p watchModes is set to WatchFiles, all files in the watched
98  * directory are watched for changes, too. Thus, the signals dirty(),
99  * created(), deleted() can be emitted.
100  * When @p watchModes is set to WatchSubDirs, all subdirs are watched using
101  * the same flags specified in @p watchModes (symlinks aren't followed).
102  * If the @p path points to a symlink to a directory, the target directory
103  * is watched instead. If you want to watch the link, use @p addFile().
104  *
105  * @param path the path to watch
106  * @param watchModes watch modes
107  *
108  * @sa KDirWatch::WatchMode
109  */
110  void addDir(const QString &path, WatchModes watchModes = WatchDirOnly);
111 
112  /**
113  * Adds a file to be watched.
114  * If it's a symlink to a directory, it watches the symlink itself.
115  * @param file the file to watch
116  */
117  void addFile(const QString &file);
118 
119  /**
120  * Returns the time the directory/file was last changed.
121  * @param path the file to check
122  * @return the date of the last modification
123  */
124  QDateTime ctime(const QString &path) const;
125 
126  /**
127  * Removes a directory from the list of scanned directories.
128  *
129  * If specified path is not in the list this does nothing.
130  * @param path the path of the dir to be removed from the list
131  */
132  void removeDir(const QString &path);
133 
134  /**
135  * Removes a file from the list of watched files.
136  *
137  * If specified path is not in the list this does nothing.
138  * @param file the file to be removed from the list
139  */
140  void removeFile(const QString &file);
141 
142  /**
143  * Stops scanning the specified path.
144  *
145  * The @p path is not deleted from the internal list, it is just skipped.
146  * Call this function when you perform an huge operation
147  * on this directory (copy/move big files or many files). When finished,
148  * call restartDirScan(path).
149  *
150  * @param path the path to skip
151  * @return true if the @p path is being watched, otherwise false
152  * @see restartDirScan()
153  */
154  bool stopDirScan(const QString &path);
155 
156  /**
157  * Restarts scanning for specified path.
158  *
159  * It doesn't notify about the changes (by emitting a signal).
160  * The ctime value is reset.
161  *
162  * Call it when you are finished with big operations on that path,
163  * @em and when @em you have refreshed that path.
164  *
165  * @param path the path to restart scanning
166  * @return true if the @p path is being watched, otherwise false
167  * @see stopDirScan()
168  */
169  bool restartDirScan(const QString &path);
170 
171  /**
172  * Starts scanning of all dirs in list.
173  *
174  * @param notify If true, all changed directories (since
175  * stopScan() call) will be notified for refresh. If notify is
176  * false, all ctimes will be reset (except those who are stopped,
177  * but only if @p skippedToo is false) and changed dirs won't be
178  * notified. You can start scanning even if the list is
179  * empty. First call should be called with @p false or else all
180  * directories
181  * in list will be notified.
182  * @param skippedToo if true, the skipped directories (scanning of which was
183  * stopped with stopDirScan() ) will be reset and notified
184  * for change. Otherwise, stopped directories will continue to be
185  * unnotified.
186  */
187  void startScan(bool notify = false, bool skippedToo = false);
188 
189  /**
190  * Stops scanning of all directories in internal list.
191  *
192  * The timer is stopped, but the list is not cleared.
193  */
194  void stopScan();
195 
196  /**
197  * Is scanning stopped?
198  * After creation of a KDirWatch instance, this is false.
199  * @return true when scanning stopped
200  */
201  bool isStopped();
202 
203  /**
204  * Check if a directory is being watched by this KDirWatch instance
205  * @param path the directory to check
206  * @return true if the directory is being watched
207  */
208  bool contains(const QString &path) const;
209 
210  void deleteQFSWatcher(); // KF6 TODO: remove from public API
211 
212  /**
213  * Dump statistic information about the KDirWatch::self() instance.
214  * This checks for consistency, too.
215  */
216  static void statistics(); // TODO implement a QDebug operator for KDirWatch instead.
217 
218  enum Method {
219  FAM,
220  INotify,
221  Stat,
222  QFSWatch,
223  };
224  /**
225  * Returns the preferred internal method to
226  * watch for changes.
227  */
228  Method internalMethod() const;
229 
230  /**
231  * The KDirWatch instance usually globally used in an application.
232  * It is automatically deleted when the application exits.
233  *
234  * However, you can create an arbitrary number of KDirWatch instances
235  * aside from this one - for those you have to take care of memory management.
236  *
237  * This function returns an instance of KDirWatch. If there is none, it
238  * will be created.
239  *
240  * @return a KDirWatch instance
241  */
242  static KDirWatch *self();
243  /**
244  * Returns true if there is an instance of KDirWatch.
245  * @return true if there is an instance of KDirWatch.
246  * @see KDirWatch::self()
247  */
248  static bool exists();
249 
250 public Q_SLOTS:
251 
252  /**
253  * Emits created().
254  * @param path the path of the file or directory
255  */
256  void setCreated(const QString &path);
257 
258  /**
259  * Emits dirty().
260  * @param path the path of the file or directory
261  */
262  void setDirty(const QString &path);
263 
264  /**
265  * Emits deleted().
266  * @param path the path of the file or directory
267  */
268  void setDeleted(const QString &path);
269 
270 Q_SIGNALS:
271 
272  /**
273  * Emitted when a watched object is changed.
274  * For a directory this signal is emitted when files
275  * therein are created or deleted.
276  * For a file this signal is emitted when its size or attributes change.
277  *
278  * When you watch a directory, changes in the size or attributes of
279  * contained files may or may not trigger this signal to be emitted
280  * depending on which backend is used by KDirWatch.
281  *
282  * The new ctime is set before the signal is emitted.
283  * @param path the path of the file or directory
284  */
285  void dirty(const QString &path);
286 
287  /**
288  * Emitted when a file or directory (being watched explicitly) is created.
289  * This is not emitted when creating a file is created in a watched directory.
290  * @param path the path of the file or directory
291  */
292  void created(const QString &path);
293 
294  /**
295  * Emitted when a file or directory is deleted.
296  *
297  * The object is still watched for new creation.
298  * @param path the path of the file or directory
299  */
300  void deleted(const QString &path);
301 
302 private:
303  KDirWatchPrivate *d;
304 };
305 
306 Q_DECLARE_OPERATORS_FOR_FLAGS(KDirWatch::WatchModes)
307 
308 #endif
WatchMode
Available watch modes for directory monitoring.
Definition: kdirwatch.h:65
Class for watching directory and file changes.
Definition: kdirwatch.h:56
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Apr 18 2021 23:02:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.