Skip to content

Commit

Permalink
Allow multiple files in qt-based file watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
variar committed Mar 15, 2016
1 parent 955c213 commit 22f22cf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 55 deletions.
111 changes: 59 additions & 52 deletions src/qtfilewatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@

QtFileWatcher::QtFileWatcher() : FileWatcher(), qtFileWatcher_( this )
{
monitoringState_ = None;

connect( &qtFileWatcher_, SIGNAL( fileChanged( const QString& ) ),
this, SLOT( fileChangedOnDisk( const QString& ) ) );
this, SLOT( fileChangedOnDisk( const QString& ) ),
Qt::QueuedConnection );

connect( &qtFileWatcher_, SIGNAL( directoryChanged( const QString& ) ),
this, SLOT( directoryChangedOnDisk( const QString& ) ) );
this, SLOT( directoryChangedOnDisk( const QString& ) ),
Qt::QueuedConnection );
}

QtFileWatcher::~QtFileWatcher()
Expand All @@ -46,26 +46,20 @@ void QtFileWatcher::addFile( const QString& fileName )

QFileInfo fileInfo = QFileInfo( fileName );

if ( fileMonitored_.isEmpty() ) {
fileMonitored_ = fileName;

// Initialise the Qt file watcher
qtFileWatcher_.addPath( fileInfo.path() );
if (monitoredFiles_.contains(fileName)) {
LOG(logDEBUG) << "QtFileWatcher::addFile: already monitoring " << fileName.toStdString();
return;
}

if ( fileInfo.exists() ) {
LOG(logDEBUG) << "QtFileWatcher::addFile: file exists.";
qtFileWatcher_.addPath( fileName );
monitoringState_ = FileExists;
}
else {
LOG(logDEBUG) << "QtFileWatcher::addFile: file doesn't exist.";
monitoringState_ = FileRemoved;
}
qtFileWatcher_.addPath( fileInfo.path() );
if ( fileInfo.exists() ) {
LOG(logDEBUG) << "QtFileWatcher::addFile: file exists.";
qtFileWatcher_.addPath( fileName );
monitoredFiles_[fileName] = FileExists;
}
else {
LOG(logWARNING) << "QtFileWatcher::addFile " << fileName.toStdString()
<< "- Already watching a file (" << fileMonitored_.toStdString()
<< ")!";
LOG(logDEBUG) << "QtFileWatcher::addFile: file doesn't exist.";
monitoredFiles_[fileName] = FileRemoved;
}
}

Expand All @@ -75,12 +69,24 @@ void QtFileWatcher::removeFile( const QString& fileName )

QFileInfo fileInfo = QFileInfo( fileName );

if ( fileName == fileMonitored_ ) {
if ( monitoringState_ == FileExists )
if ( monitoredFiles_.contains( fileName ) ) {
const MonitoringState state = monitoredFiles_[fileName];
if ( state == FileExists) {
qtFileWatcher_.removePath( fileName );
qtFileWatcher_.removePath( fileInfo.path() );
fileMonitored_.clear();
monitoringState_ = None;
}
else {
bool needWatchDirectory = false;
foreach ( const QString& monitoredFile, monitoredFiles_.keys() ) {
if ( QFileInfo( monitoredFile ).path() == fileInfo.path() ) {
needWatchDirectory = true;
break;
}
}
if ( !needWatchDirectory ) {
qtFileWatcher_.removePath( fileInfo.path() );
}
}
monitoredFiles_.remove( fileName );
}
else {
LOG(logWARNING) << "QtFileWatcher::removeFile - The file is not watched!";
Expand All @@ -103,13 +109,12 @@ void QtFileWatcher::fileChangedOnDisk( const QString& filename )
{
LOG(logDEBUG) << "QtFileWatcher::fileChangedOnDisk " << filename.toStdString();

if ( ( monitoringState_ == FileExists ) && ( filename == fileMonitored_ ) )
{
if ( monitoredFiles_.contains( filename ) && monitoredFiles_[filename] == FileExists ) {
emit fileChanged( filename );

// If the file has been removed...
if ( !QFileInfo( filename ).exists() )
monitoringState_ = FileRemoved;
monitoredFiles_[filename] = FileRemoved;
}
else
LOG(logWARNING) << "QtFileWatcher::fileChangedOnDisk - call from Qt but no file monitored";
Expand All @@ -119,35 +124,37 @@ void QtFileWatcher::directoryChangedOnDisk( const QString& filename )
{
LOG(logDEBUG) << "QtFileWatcher::directoryChangedOnDisk " << filename.toStdString();

if ( monitoringState_ == FileRemoved ) {
if ( QFileInfo( fileMonitored_ ).exists() ) {
LOG(logDEBUG) << "QtFileWatcher::directoryChangedOnDisk - our file reappeared!";
foreach( const QString& monitoredFile, monitoredFiles_.keys() ) {
const MonitoringState currentState = monitoredFiles_[monitoredFile];
if ( currentState == FileRemoved ) {
if ( QFileInfo( monitoredFile ).exists() ) {
LOG(logDEBUG) << "QtFileWatcher::directoryChangedOnDisk - our file reappeared!";

// The file has been recreated, we have to watch it again.
monitoringState_ = FileExists;
// The file has been recreated, we have to watch it again.
monitoredFiles_[monitoredFile] = FileExists;

// Restore the Qt file watcher (automatically cancelled
// when the file is deleted)
qtFileWatcher_.addPath( fileMonitored_ );
// Restore the Qt file watcher (automatically cancelled
// when the file is deleted)
qtFileWatcher_.addPath( monitoredFile );

emit fileChanged( fileMonitored_ );
}
else {
LOG(logWARNING) << "QtFileWatcher::directoryChangedOnDisk - not the file we are watching";
emit fileChanged( monitoredFile );
}
else {
LOG(logWARNING) << "QtFileWatcher::directoryChangedOnDisk - not the file we are watching";
}
}
}
else if ( monitoringState_ == FileExists )
{
if ( ! QFileInfo( fileMonitored_ ).exists() ) {
LOG(logDEBUG) << "QtFileWatcher::directoryChangedOnDisk - our file disappeared!";
else if ( currentState == FileExists ) {
if ( !QFileInfo( monitoredFile ).exists() ) {
LOG(logDEBUG) << "QtFileWatcher::directoryChangedOnDisk - our file disappeared!";

monitoringState_ = FileRemoved;
monitoredFiles_[monitoredFile] = FileRemoved;

emit fileChanged( filename );
emit fileChanged( monitoredFile );
}
else {
LOG(logWARNING) << "QtFileWatcher::directoryChangedOnDisk - not the file we are watching";
}
}
else {
LOG(logWARNING) << "QtFileWatcher::directoryChangedOnDisk - not the file we are watching";
}
}

}
}
5 changes: 2 additions & 3 deletions src/qtfilewatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
#include "filewatcher.h"

#include <QFileSystemWatcher>
#include <QMap>

// This class encapsulate Qt's QFileSystemWatcher and additionally support
// watching a file that doesn't exist yet (the class will watch the owning
// directory)
// Only supports one file at the moment.
class QtFileWatcher : public FileWatcher {
Q_OBJECT

Expand Down Expand Up @@ -56,8 +56,7 @@ class QtFileWatcher : public FileWatcher {
enum MonitoringState { None, FileExists, FileRemoved };

QFileSystemWatcher qtFileWatcher_;
QString fileMonitored_;
MonitoringState monitoringState_;
QMap<QString, MonitoringState> monitoredFiles_;
};

#endif

0 comments on commit 22f22cf

Please sign in to comment.