2 * \file FileMonitor.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
8 * Full author contact details are available in file CREDITS.
13 #include "support/FileMonitor.h"
15 #include "support/FileName.h"
16 #include "support/Timeout.h"
18 #include "support/bind.h"
19 #include <boost/signals2/trackable.hpp>
26 class FileMonitor::Impl : public boost::signals2::trackable {
30 Impl(FileName const & file_with_path, int interval);
41 /// This signal is emitted if the file is modified (has a new checksum).
42 FileMonitor::FileChangedSig fileChanged_;
44 /** We use these to ascertain whether a file (once loaded successfully)
49 unsigned long checksum_;
53 FileMonitor::FileMonitor(FileName const & file_with_path, int interval)
54 : pimpl_(new Impl(file_with_path, interval))
58 FileMonitor::~FileMonitor()
64 void FileMonitor::reset(FileName const & file_with_path) const
66 if (pimpl_->filename_ == file_with_path)
69 bool const monitor = pimpl_->timer_.running();
73 pimpl_->filename_ = file_with_path;
80 FileName const & FileMonitor::filename() const
82 return pimpl_->filename_;
86 void FileMonitor::start() const
91 if (!pimpl_->filename_.exists())
94 pimpl_->timestamp_ = pimpl_->filename_.lastModified();
95 pimpl_->checksum_ = pimpl_->filename_.checksum();
97 if (pimpl_->timestamp_ && pimpl_->checksum_) {
98 pimpl_->timer_.start();
100 pimpl_->timestamp_ = 0;
101 pimpl_->checksum_ = 0;
106 void FileMonitor::stop() const
108 pimpl_->timestamp_ = 0;
109 pimpl_->checksum_ = 0;
110 pimpl_->timer_.stop();
114 bool FileMonitor::monitoring() const
116 return pimpl_->timer_.running();
120 unsigned long FileMonitor::checksum() const
122 // If we aren't actively monitoring the file, then recompute the
123 // checksum explicitly.
124 if (!pimpl_->timer_.running() && !pimpl_->filename_.empty())
125 return pimpl_->filename_.checksum();
127 return pimpl_->checksum_;
131 boost::signals2::connection FileMonitor::connect(slot_type const & slot) const
133 return pimpl_->fileChanged_.connect(slot);
137 //------------------------------
138 // Implementation details follow
139 //------------------------------
142 FileMonitor::Impl::Impl(FileName const & file_with_path, int interval)
143 : filename_(file_with_path),
144 timer_(interval, Timeout::ONETIME),
148 timer_.timeout.connect(bind(&Impl::monitorFile, this));
152 void FileMonitor::Impl::monitorFile()
154 bool changed = false;
156 if (!filename_.exists()) {
157 changed = timestamp_ || checksum_;
162 time_t const new_timestamp = filename_.lastModified();
164 if (new_timestamp != timestamp_) {
165 timestamp_ = new_timestamp;
167 unsigned long const new_checksum = filename_.checksum();
168 if (new_checksum != checksum_) {
169 checksum_ = new_checksum;
180 } // namespace support