X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FFileMonitor.h;h=07a8dc532c93335007ab4f9b79e5b24afa445dd6;hb=82b3a26a320f1056b09d4061bfbe704e838b7487;hp=09d85e81a11eb2ac3b2ab279c8ec550f340f791f;hpb=f96d7a8b2cb45e98382e2d88f1156e74e7898f5e;p=lyx.git diff --git a/src/support/FileMonitor.h b/src/support/FileMonitor.h index 09d85e81a1..07a8dc532c 100644 --- a/src/support/FileMonitor.h +++ b/src/support/FileMonitor.h @@ -4,6 +4,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * + * \author Angus Leeming * \author Guillaume Munch * * Full author contact details are available in file CREDITS. @@ -15,26 +16,28 @@ #ifndef FILEMONITOR_H #define FILEMONITOR_H +#include "support/FileName.h" +#include "support/signals.h" + #include #include #include - -#include +#include namespace lyx { namespace support { -class FileName; - /// /// FileMonitor, a file monitor based on QFileSystemWatcher /// class FileMonitor; +class ActiveFileMonitor; class FileMonitorGuard; -using FileMonitorPtr = std::unique_ptr; +typedef std::unique_ptr FileMonitorPtr; +typedef std::unique_ptr ActiveFileMonitorPtr; /// /// Watch a file: @@ -57,37 +60,32 @@ using FileMonitorPtr = std::unique_ptr; /// monitor.connect(...); /// (stops watching the first) /// -/// Block notifications for the duration of a scope: -/// { -/// FileMonitorBlocker block = monitor.block(); -/// ... -/// } -/// -/// Reset connections: -/// monitor.disconnect(); -/// or the disconnect method of the connection object for the boost signal. -/// class FileSystemWatcher { public: - // as described above - static FileMonitorPtr monitor(FileName const & file_with_path); - // Output whether the paths tracked by qwatcher_ and the active - // FileMonitorGuards are in correspondence. + /// as described above + static FileMonitorPtr monitor(FileName const & filename); + /// same but with an ActiveFileMonitor + static ActiveFileMonitorPtr activeMonitor(FileName const & filename, + int interval = 10000); + /// Output whether the paths tracked by qwatcher_ and the active + /// FileMonitorGuards are in correspondence. static void debug(); private: FileSystemWatcher(); - // A global instance is created automatically on first call to monitor + /// A global instance is created automatically on first call static FileSystemWatcher & instance(); - // Caches the monitor guards but allow them to be destroyed + /// + std::shared_ptr getGuard(FileName const & filename); + /// Caches the monitor guards but allow them to be destroyed std::map> store_; - // This class is a wrapper for QFileSystemWatcher + /// This class is a wrapper for QFileSystemWatcher std::unique_ptr const qwatcher_; }; -// Must be unique per path -// Ends the watch when deleted +/// Must be unique per path +/// Ends the watch when deleted class FileMonitorGuard : public QObject { Q_OBJECT @@ -100,16 +98,16 @@ public: ~FileMonitorGuard(); /// absolute path being tracked std::string const & filename() { return filename_; } + +public Q_SLOTS: /// Make sure it is being monitored, after e.g. a deletion. See /// . This is called /// automatically. - /// \param new_file If true, emit fileChanged if the file exists and was - /// successfully added. - void refresh(bool new_file = false); + void refresh(bool emit = true); Q_SIGNALS: /// Connect to this to be notified when the file changes - void fileChanged() const; + void fileChanged(bool exists) const; private Q_SLOTS: /// Receive notifications from the QFileSystemWatcher @@ -118,73 +116,81 @@ private Q_SLOTS: private: std::string const filename_; QFileSystemWatcher * qwatcher_; + /// for emitting fileChanged() when the file is created or deleted + bool exists_; }; -class FileMonitorBlockerGuard : public QObject -{ - Q_OBJECT - FileMonitor * parent_; - int delay_; - -public: - FileMonitorBlockerGuard(FileMonitor * parent); - ~FileMonitorBlockerGuard(); - void setDelay(int delay); -}; - - -using FileMonitorBlocker = std::shared_ptr; - - /// Main class class FileMonitor : public QObject { Q_OBJECT - friend class FileMonitorBlockerGuard; public: FileMonitor(std::shared_ptr monitor); - using sig = boost::signals2::signal; + typedef signals2::signal sig; + typedef sig::slot_type slot; /// Connect and you'll be informed when the file has changed. - boost::signals2::connection connect(sig::slot_type const &); - /// disconnect all slots connected to the boost signal fileChanged_ or to - /// the qt signal fileChanged() - void disconnect(); + signals2::connection connect(slot const &); /// absolute path being tracked std::string const & filename() { return monitor_->filename(); } - /// Creates a guard that blocks notifications. Copyable. Notifications from - /// this monitor are blocked as long as there are copies around. - /// \param delay is the amount waited in ms after expiration of the guard - /// before reconnecting. This delay thing is to deal with asynchronous - /// notifications in a not so elegant fashion. But it can also be used to - /// slow down incoming events. - FileMonitorBlocker block(int delay = 0); /// Make sure the good file is being monitored, after e.g. a move or a /// deletion. See . This is /// called automatically. - void refresh() { return monitor_->refresh(); } + void refresh() { monitor_->refresh(); } Q_SIGNALS: /// Connect to this to be notified when the file changes - void fileChanged() const; + void fileChanged(bool exists) const; -private Q_SLOTS: +protected Q_SLOTS: /// Receive notifications from the FileMonitorGuard - void changed(); + void changed(bool exists); + /// + void connectToFileMonitorGuard(); private: - void connectToFileMonitorGuard(); - // boost signal + /// boost signal sig fileChanged_; - // the unique watch for our file + /// the unique watch for our file std::shared_ptr const monitor_; - // - std::weak_ptr blocker_; }; +/// When a more active monitoring style is needed. +/// For instance because QFileSystemWatcher does not work for remote file +/// systems. +class ActiveFileMonitor : public FileMonitor +{ + Q_OBJECT +public: + ActiveFileMonitor(std::shared_ptr monitor, + FileName const & filename, int interval); + /// call checkModified asynchronously + void checkModifiedAsync(); + +public Q_SLOTS: + /// Check explicitly for a modification, but not more than once every + /// interval ms. + void checkModified(); + +private Q_SLOTS: + void setCooldown() { cooldown_ = true; } + void clearCooldown() { cooldown_ = false; } + +private: + FileName const filename_; + /// + int const interval_; + /// + time_t timestamp_; + /// + unsigned long checksum_; + /// + bool cooldown_; +}; + } // namespace support } // namespace lyx