* 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.
{}
-//static
-FileMonitorPtr FileSystemWatcher::monitor(FileName const & file_with_path)
+shared_ptr<FileMonitorGuard>
+FileSystemWatcher::getGuard(FileName const & filename)
{
- FileSystemWatcher & f = instance();
- string const filename = file_with_path.absFileName();
- weak_ptr<FileMonitorGuard> & wptr = f.store_[filename];
+ string const absfilename = filename.absFileName();
+ weak_ptr<FileMonitorGuard> & wptr = store_[absfilename];
if (shared_ptr<FileMonitorGuard> mon = wptr.lock())
- return make_unique<FileMonitor>(mon);
- auto mon = make_shared<FileMonitorGuard>(filename, f.qwatcher_.get());
+ return mon;
+ auto mon = make_shared<FileMonitorGuard>(absfilename, qwatcher_.get());
wptr = mon;
- return make_unique<FileMonitor>(mon);
+ return mon;
+}
+
+
+//static
+FileMonitorPtr FileSystemWatcher::monitor(FileName const & filename)
+{
+ return make_unique<FileMonitor>(instance().getGuard(filename));
+}
+
+
+//static
+ActiveFileMonitorPtr FileSystemWatcher::activeMonitor(FileName const & filename,
+ int interval)
+{
+ return make_unique<ActiveFileMonitor>(instance().getGuard(filename),
+ filename, interval);
}
QTimer::singleShot(delay_, monitor_, SLOT(reconnectToFileMonitorGuard()));
}
+
+ActiveFileMonitor::ActiveFileMonitor(std::shared_ptr<FileMonitorGuard> monitor,
+ FileName const & filename, int interval)
+ : FileMonitor(monitor), filename_(filename), interval_(interval),
+ timestamp_(0), checksum_(0), cooldown_(true)
+{
+ QObject::connect(this, SIGNAL(fileChanged()), this, SLOT(setCooldown()));
+ QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
+ if (!filename_.exists())
+ return;
+ timestamp_ = filename_.lastModified();
+ checksum_ = filename_.checksum();
+}
+
+
+void ActiveFileMonitor::checkModified()
+{
+ if (cooldown_)
+ return;
+
+ cooldown_ = true;
+ bool changed = false;
+ if (!filename_.exists()) {
+ changed = timestamp_ || checksum_;
+ timestamp_ = 0;
+ checksum_ = 0;
+ } else {
+ time_t const new_timestamp = filename_.lastModified();
+
+ if (new_timestamp != timestamp_) {
+ timestamp_ = new_timestamp;
+
+ unsigned long const new_checksum = filename_.checksum();
+ if (new_checksum != checksum_) {
+ checksum_ = new_checksum;
+ changed = true;
+ }
+ }
+ }
+ if (changed)
+ FileMonitor::changed();
+ QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
+}
+
+
+void ActiveFileMonitor::checkModifiedAsync()
+{
+ if (!cooldown_)
+ QTimer::singleShot(0, this, SLOT(checkModified()));
+}
+
+
+
} // namespace support
} // namespace lyx
* 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.
#ifndef FILEMONITOR_H
#define FILEMONITOR_H
+#include "support/FileName.h"
+
#include <memory>
#include <QFileSystemWatcher>
namespace lyx {
namespace support {
-class FileName;
-
///
/// FileMonitor, a file monitor based on QFileSystemWatcher
///
class FileMonitor;
+class ActiveFileMonitor;
class FileMonitorGuard;
typedef std::unique_ptr<FileMonitor> FileMonitorPtr;
+typedef std::unique_ptr<ActiveFileMonitor> ActiveFileMonitorPtr;
///
/// Watch a file:
{
public:
// as described above
- static FileMonitorPtr monitor(FileName const & file_with_path);
+ 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();
+ ///
+ std::shared_ptr<FileMonitorGuard> getGuard(FileName const & filename);
// Caches the monitor guards but allow them to be destroyed
std::map<std::string, std::weak_ptr<FileMonitorGuard>> store_;
// This class is a wrapper for QFileSystemWatcher
};
-// 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
/// Connect to this to be notified when the file changes
void fileChanged() const;
-private Q_SLOTS:
+protected Q_SLOTS:
/// Receive notifications from the FileMonitorGuard
void changed();
///
};
+/// 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<FileMonitorGuard> 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