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 "FileMonitor.h"
15 #include "frontends/Timeout.h"
17 #include "support/FileInfo.h"
18 #include "support/lyxlib.h"
20 #include <boost/bind.hpp>
21 #include <boost/signals/trackable.hpp>
26 struct FileMonitor::Impl : public boost::signals::trackable {
29 Impl(string const & file_with_path, int interval);
40 /// This signal is emitted if the file is modified (has a new checksum).
41 boost::signal0<void> fileChanged_;
43 /** We use these to ascertain whether a file (once loaded successfully)
48 unsigned long checksum_;
52 FileMonitor::FileMonitor(string const & file_with_path, int interval)
53 : pimpl_(new Impl(file_with_path, interval))
57 FileMonitor::~FileMonitor()
61 void FileMonitor::reset(string const & file_with_path) const
63 if (pimpl_->filename_ == file_with_path)
66 bool const monitor = pimpl_->timer_.running();
70 pimpl_->filename_ = file_with_path;
77 string const & FileMonitor::filename() const
79 return pimpl_->filename_;
83 void FileMonitor::start() const
88 FileInfo finfo(pimpl_->filename_);
92 pimpl_->timestamp_ = finfo.getModificationTime();
93 pimpl_->checksum_ = sum(pimpl_->filename_);
95 if (pimpl_->timestamp_ && pimpl_->checksum_) {
96 pimpl_->timer_.start();
98 pimpl_->timestamp_ = 0;
99 pimpl_->checksum_ = 0;
104 void FileMonitor::stop() const
106 pimpl_->timestamp_ = 0;
107 pimpl_->checksum_ = 0;
108 pimpl_->timer_.stop();
112 bool FileMonitor::monitoring() const
114 return pimpl_->timer_.running();
118 unsigned long FileMonitor::checksum() const
120 // If we aren't actively monitoring the file, then recompute the
121 // checksum explicitly.
122 if (!pimpl_->timer_.running() && !pimpl_->filename_.empty())
123 return sum(pimpl_->filename_);
125 return pimpl_->checksum_;
129 boost::signals::connection FileMonitor::connect(slot_type const & slot) const
131 return pimpl_->fileChanged_.connect(slot);
135 //------------------------------
136 // Implementation details follow
137 //------------------------------
140 FileMonitor::Impl::Impl(string const & file_with_path, int interval)
141 : filename_(file_with_path),
142 timer_(interval, Timeout::ONETIME),
146 timer_.timeout.connect(boost::bind(&Impl::monitorFile, this));
150 void FileMonitor::Impl::monitorFile()
152 bool changed = false;
154 FileInfo finfo(filename_);
156 changed = timestamp_ || checksum_;
161 time_t const new_timestamp = finfo.getModificationTime();
163 if (new_timestamp != timestamp_) {
164 timestamp_ = new_timestamp;
166 unsigned long const new_checksum = sum(filename_);
167 if (new_checksum != checksum_) {
168 checksum_ = new_checksum;
179 } // namespace support