LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
LimaFileSystemWatcher.cpp
Go to the documentation of this file.
1// Copyright 2015 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
8#include "common/LimaCommon.h"
9
10#include <QStringList>
11#include <QFileInfo>
12#include <QDir>
13#include <QTime>
14#include <QCoreApplication>
15
16#include <iostream>
17
18namespace Lima
19{
20
21LimaFileSystemWatcherPrivate::LimaFileSystemWatcherPrivate ( LimaFileSystemWatcher* q, QObject* parent ) : QObject(parent), q_ptr ( q ), m_pathToDeletedFileMapMutex()
22{
23// MISCLOGINIT;
24 if (!connect(&m_watcher, SIGNAL(directoryChanged(QString)),this, SLOT(slotDirectoryChanged(QString)) ))
25 {
26 std::cerr << "LimaFileSystemWatcherPrivate::LimaFileSystemWatcherPrivate failed to connect directoryChanged signal" << std::endl;
27 }
28 if (!connect(&m_watcher, SIGNAL(fileChanged(QString)),this, SLOT(slotFileChanged(QString)) ))
29 {
30 std::cerr << "LimaFileSystemWatcherPrivate::LimaFileSystemWatcherPrivate failed to connect fileChanged signal" << std::endl;
31 }
32}
33
37
38
39void LimaFileSystemWatcherPrivate::delay( int millisecondsToWait )
40{
41 QTime dieTime = QTime::currentTime().addMSecs( millisecondsToWait );
42 while( QTime::currentTime() < dieTime )
43 {
44 QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
45 }
46}
47void LimaFileSystemWatcherPrivate::slotDirectoryChanged ( const QString & path )
48{
49
50 std::cerr << "LimaFileSystemWatcherPrivate::slotDirectoryChanged" << path.toUtf8().constData() << std::endl;
51 QMutexLocker locker(&m_pathToDeletedFileMapMutex);
52 if (m_pathToDeletedFileMap.contains(path))
53 {
54 // for each of the files associated to the dir 'path', check if it exists again.
55 QList<QString> files = m_pathToDeletedFileMap.values(path);
56 for(auto& file : files)
57 {
58 // file has been recreated: watch it again, remove it from list of deleted and signal the change
59 if (QFileInfo::exists(file))
60 {
61 // Wait a few time to let the creator of the file to finish its work on it
62 delay(1000);
63 // remove file from list of deleted
64 m_pathToDeletedFileMap.remove(path, file);
65 // if there is no more deleted file in path, stop to watch it
66 if (!m_pathToDeletedFileMap.contains(path))
67 {
68 m_watcher.removePath(path);
69 }
70 std::cerr << "LimaFileSystemWatcherPrivate::slotDirectoryChanged watching again" << file.toUtf8().constData() << std::endl ;
71 // watch file again
72 m_watcher.addPath(file);
73 // signal the change
74 Q_EMIT fileChanged(file);
75 }
76 }
77 }
78}
79
80void LimaFileSystemWatcherPrivate::slotFileChanged ( const QString & path )
81{
82 std::cerr << "LimaFileSystemWatcherPrivate::slotFileChanged " << path.toUtf8().constData() << std::endl;
83 delay(500);
84 // File just disapeared
85 if (!QFileInfo::exists(path))
86 {
87 std::cerr << "LimaFileSystemWatcherPrivate::slotFileChanged removed" << path.toUtf8().constData() << std::endl;
88 QMutexLocker locker(&m_pathToDeletedFileMapMutex);
89 // explicitely remove the file from the watcher, otherwise, even if it is no longer
90 // monitored, it cannot be added again
91 m_watcher.removePath(path);
92 // get file dir
93 QString dir = QFileInfo(path).absoluteDir().absolutePath();
94 // add the link dir -file to the list of deleted files
95 m_pathToDeletedFileMap.insert(dir, path);
96 // add the dir to the watcher
97 m_watcher.addPath(dir);
98 }
99 // In all cases, transmit the signal
100 std::cerr << "LimaFileSystemWatcherPrivate::slotFileChanged emiting fileChanged from private " << path.toUtf8().constData() << std::endl;
101 Q_EMIT fileChanged(path);
102}
103
105 : QObject(parent), m_d ( new LimaFileSystemWatcherPrivate ( this ) )
106{
107 if (!connect(m_d, SIGNAL(fileChanged(QString)),this,SIGNAL(fileChanged(QString))))
108 {
109 std::cerr << "LimaFileSystemWatcher::LimaFileSystemWatcher failed to connect fileChanged signal" << std::endl;
110 }
111}
112
114 : QObject(other.parent()), m_d ( new LimaFileSystemWatcherPrivate ( this ) )
115{
116 if (!connect(m_d, SIGNAL(fileChanged(QString)),this,SIGNAL(fileChanged(QString))))
117 {
118 std::cerr << "LimaFileSystemWatcher::LimaFileSystemWatcher failed to connect fileChanged signal" << std::endl;
119 }
120 m_d->m_watcher.removePaths(m_d->m_watcher.directories());
121 m_d->m_watcher.removePaths(m_d->m_watcher.files());
122 m_d->m_watcher.addPaths(other.m_d->m_watcher.directories());
123 m_d->m_watcher.addPaths(other.m_d->m_watcher.files());
124}
125
130
131void LimaFileSystemWatcher::addPath ( const QString & path )
132{
133 if(!m_d->m_watcher.files().contains(path))
134 m_d->m_watcher.addPath(path);
135}
136
137void LimaFileSystemWatcher::removePath ( const QString & path )
138{
139 m_d->m_watcher.removePath(path);
140}
141
143{
144 m_d->m_watcher.removePaths(m_d->m_watcher.directories());
145 m_d->m_watcher.removePaths(m_d->m_watcher.files());
146 m_d->m_watcher.addPaths(other.m_d->m_watcher.directories());
147 m_d->m_watcher.addPaths(other.m_d->m_watcher.files());
148 return *this;
149}
150
152{
153 return m_d->m_watcher.directories() == other.m_d->m_watcher.directories()
154 && m_d->m_watcher.files() == other.m_d->m_watcher.files();
155}
156
157} // Lima
LimaFileSystemWatcherPrivate(LimaFileSystemWatcher *q, QObject *parent=0)
void fileChanged(const QString &path)
LimaFileSystemWatcher extends QFileSystemWatcher to work on replaced files
void addPath(const QString &path)
void fileChanged(const QString &path)
This signal is emited whenever path change, either modified, suppressed or recreated.
void removePath(const QString &path)
bool operator==(const LimaFileSystemWatcher &other)
LimaFileSystemWatcher & operator=(const LimaFileSystemWatcher &other)
NAUTITIA.