This file is part of the KDE libraries
SPDX-FileCopyrightText: 1998 Sven Radej <sven@lisa.exp.univie.ac.at>
SPDX-License-Identifier: LGPL-2.0-only
*/
#ifndef _KDIRWATCH_H
#define _KDIRWATCH_H
#include <QDateTime>
#include <QObject>
#include <QString>
#include <kcoreaddons_export.h>
class KDirWatchPrivate;
* @class KDirWatch kdirwatch.h KDirWatch
*
* @short Class for watching directory and file changes.
*
* Watch directories and files for changes.
* The watched directories or files don't have to exist yet.
*
* When a watched directory is changed, i.e. when files therein are
* created or deleted, KDirWatch will emit the signal dirty().
*
* When a watched, but previously not existing directory gets created,
* KDirWatch will emit the signal created().
*
* When a watched directory gets deleted, KDirWatch will emit the
* signal deleted(). The directory is still watched for new
* creation.
*
* When a watched file is changed, i.e. attributes changed or written
* to, KDirWatch will emit the signal dirty().
*
* Scanning of particular directories or files can be stopped temporarily
* and restarted. The whole class can be stopped and restarted.
* Directories and files can be added/removed from the list in any state.
*
* The implementation uses the INOTIFY functionality on LINUX.
* As a last resort, a regular polling for change of modification times
* is done; the polling interval is a global config option:
* DirWatch/PollInterval and DirWatch/NFSPollInterval for NFS mounted
* directories.
* The choice of implementation can be adjusted by the user, with the key
* [DirWatch] PreferredMethod={Stat|QFSWatch|inotify}
*
* @see self()
* @author Sven Radej (in 1998)
*/
class KCOREADDONS_EXPORT KDirWatch : public QObject
{
Q_OBJECT
public:
* Available watch modes for directory monitoring
* @see WatchModes
**/
enum WatchMode {
WatchDirOnly = 0,
WatchFiles = 0x01,
WatchSubDirs = 0x02,
};
* Stores a combination of #WatchMode values.
*/
Q_DECLARE_FLAGS(WatchModes, WatchMode)
* Constructor.
*
* Scanning begins immediately when a dir/file watch
* is added.
* @param parent the parent of the QObject (or @c nullptr for parent-less KDataTools)
*/
explicit KDirWatch(QObject *parent = nullptr);
* Destructor.
*
* Stops scanning and cleans up.
*/
~KDirWatch() override;
* Adds a directory to be watched.
*
* The directory does not have to exist. When @p watchModes is set to
* WatchDirOnly (the default), the signals dirty(), created(), deleted()
* can be emitted, all for the watched directory.
* When @p watchModes is set to WatchFiles, all files in the watched
* directory are watched for changes, too. Thus, the signals dirty(),
* created(), deleted() can be emitted.
* When @p watchModes is set to WatchSubDirs, all subdirs are watched using
* the same flags specified in @p watchModes (symlinks aren't followed).
* If the @p path points to a symlink to a directory, the target directory
* is watched instead. If you want to watch the link, use @p addFile().
*
* @param path the path to watch
* @param watchModes watch modes
*
* @sa KDirWatch::WatchMode
*/
void addDir(const QString &path, WatchModes watchModes = WatchDirOnly);
* Adds a file to be watched.
* If it's a symlink to a directory, it watches the symlink itself.
* @param file the file to watch
*/
void addFile(const QString &file);
* Returns the time the directory/file was last changed.
* @param path the file to check
* @return the date of the last modification
*/
QDateTime ctime(const QString &path) const;
* Removes a directory from the list of scanned directories.
*
* If specified path is not in the list this does nothing.
* @param path the path of the dir to be removed from the list
*/
void removeDir(const QString &path);
* Removes a file from the list of watched files.
*
* If specified path is not in the list this does nothing.
* @param file the file to be removed from the list
*/
void removeFile(const QString &file);
* Stops scanning the specified path.
*
* The @p path is not deleted from the internal list, it is just skipped.
* Call this function when you perform an huge operation
* on this directory (copy/move big files or many files). When finished,
* call restartDirScan(path).
*
* @param path the path to skip
* @return true if the @p path is being watched, otherwise false
* @see restartDirScan()
*/
bool stopDirScan(const QString &path);
* Restarts scanning for specified path.
*
* It doesn't notify about the changes (by emitting a signal).
* The ctime value is reset.
*
* Call it when you are finished with big operations on that path,
* @em and when @em you have refreshed that path.
*
* @param path the path to restart scanning
* @return true if the @p path is being watched, otherwise false
* @see stopDirScan()
*/
bool restartDirScan(const QString &path);
* Starts scanning of all dirs in list.
*
* @param notify If true, all changed directories (since
* stopScan() call) will be notified for refresh. If notify is
* false, all ctimes will be reset (except those who are stopped,
* but only if @p skippedToo is false) and changed dirs won't be
* notified. You can start scanning even if the list is
* empty. First call should be called with @p false or else all
* directories
* in list will be notified.
* @param skippedToo if true, the skipped directories (scanning of which was
* stopped with stopDirScan() ) will be reset and notified
* for change. Otherwise, stopped directories will continue to be
* unnotified.
*/
void startScan(bool notify = false, bool skippedToo = false);
* Stops scanning of all directories in internal list.
*
* The timer is stopped, but the list is not cleared.
*/
void stopScan();
* Is scanning stopped?
* After creation of a KDirWatch instance, this is false.
* @return true when scanning stopped
*/
bool isStopped();
* Check if a directory is being watched by this KDirWatch instance
* @param path the directory to check
* @return true if the directory is being watched
*/
bool contains(const QString &path) const;
enum Method {
INotify,
Stat,
QFSWatch,
};
* Returns the preferred internal method to
* watch for changes.
*/
Method internalMethod() const;
* The KDirWatch instance usually globally used in an application.
* It is automatically deleted when the application exits.
*
* However, you can create an arbitrary number of KDirWatch instances
* aside from this one - for those you have to take care of memory management.
*
* This function returns an instance of KDirWatch. If there is none, it
* will be created.
*
* @return a KDirWatch instance
*/
static KDirWatch *self();
* Returns true if there is an instance of KDirWatch.
* @return true if there is an instance of KDirWatch.
* @see KDirWatch::self()
*/
static bool exists();
* @brief Trivial override. See QObject::event.
*/
bool event(QEvent *event) override;
public Q_SLOTS:
* Emits created().
* @param path the path of the file or directory
*/
void setCreated(const QString &path);
* Emits dirty().
* @param path the path of the file or directory
*/
void setDirty(const QString &path);
* Emits deleted().
* @param path the path of the file or directory
*/
void setDeleted(const QString &path);
Q_SIGNALS:
* Emitted when a watched object is changed.
* For a directory this signal is emitted when files
* therein are created or deleted.
* For a file this signal is emitted when its size or attributes change.
*
* When you watch a directory, changes in the size or attributes of
* contained files may or may not trigger this signal to be emitted
* depending on which backend is used by KDirWatch.
*
* The new ctime is set before the signal is emitted.
* @param path the path of the file or directory
*/
void dirty(const QString &path);
* Emitted when a file or directory (being watched explicitly) is created.
* This is not emitted when creating a file is created in a watched directory.
* @param path the path of the file or directory
*/
void created(const QString &path);
* Emitted when a file or directory is deleted.
*
* The object is still watched for new creation.
* @param path the path of the file or directory
*/
void deleted(const QString &path);
private:
KDirWatchPrivate *d;
friend class KDirWatchPrivate;
friend class KDirWatch_UnitTest;
};
* Dump debug information about the KDirWatch::self() instance.
* This checks for consistency, too.
*/
KCOREADDONS_EXPORT QDebug operator<<(QDebug debug, const KDirWatch &watch);
Q_DECLARE_OPERATORS_FOR_FLAGS(KDirWatch::WatchModes)
#endif