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
14 #pragma implementation
17 #include "FileMonitor.h"
19 #include "frontends/Timeout.h"
21 #include "support/FileInfo.h"
22 #include "support/lyxlib.h"
24 #include <boost/bind.hpp>
25 #include <boost/signals/trackable.hpp>
27 struct FileMonitor::Impl : public boost::signals::trackable {
30 Impl(string const & file_with_path, int interval);
41 /// This signal is emitted if the file is modified (has a new checksum).
42 boost::signal0<void> fileChanged_;
44 /** We use these to ascertain whether a file (once loaded successfully)
49 unsigned long checksum_;
53 FileMonitor::FileMonitor(string const & file_with_path, int interval)
54 : pimpl_(new Impl(file_with_path, interval))
58 FileMonitor::~FileMonitor()
62 void FileMonitor::reset(string const & file_with_path) const
64 if (pimpl_->filename_ == file_with_path)
67 bool const monitor = pimpl_->timer_.running();
71 pimpl_->filename_ = file_with_path;
78 string const & FileMonitor::filename() const
80 return pimpl_->filename_;
84 void FileMonitor::start() const
89 FileInfo finfo(pimpl_->filename_);
93 pimpl_->timestamp_ = finfo.getModificationTime();
94 pimpl_->checksum_ = lyx::sum(pimpl_->filename_);
96 if (pimpl_->timestamp_ && pimpl_->checksum_) {
97 pimpl_->timer_.start();
99 pimpl_->timestamp_ = 0;
100 pimpl_->checksum_ = 0;
105 void FileMonitor::stop() const
107 pimpl_->timestamp_ = 0;
108 pimpl_->checksum_ = 0;
109 pimpl_->timer_.stop();
113 bool FileMonitor::monitoring() const
115 return pimpl_->timer_.running();
119 unsigned long FileMonitor::checksum() const
121 // If we aren't actively monitoring the file, then recompute the
122 // checksum explicitly.
123 if (!pimpl_->timer_.running() && !pimpl_->filename_.empty())
124 return lyx::sum(pimpl_->filename_);
126 return pimpl_->checksum_;
130 boost::signals::connection FileMonitor::connect(slot_type const & slot) const
132 return pimpl_->fileChanged_.connect(slot);
136 //------------------------------
137 // Implementation details follow
138 //------------------------------
141 FileMonitor::Impl::Impl(string const & file_with_path, int interval)
142 : filename_(file_with_path),
143 timer_(interval, Timeout::ONETIME),
147 timer_.timeout.connect(boost::bind(&Impl::monitorFile, this));
151 void FileMonitor::Impl::monitorFile()
153 bool changed = false;
155 FileInfo finfo(filename_);
157 changed = timestamp_ || checksum_;
162 time_t const new_timestamp = finfo.getModificationTime();
164 if (new_timestamp != timestamp_) {
165 timestamp_ = new_timestamp;
167 unsigned long const new_checksum = lyx::sum(filename_);
168 if (new_checksum != checksum_) {
169 checksum_ = new_checksum;