diff --git a/src/kioexec/kioexecd.h b/src/kioexec/kioexecd.h --- a/src/kioexec/kioexecd.h +++ b/src/kioexec/kioexecd.h @@ -25,6 +25,8 @@ #include #include +#include +#include class KDirWatch; @@ -43,10 +45,17 @@ private Q_SLOTS: void slotDirty(const QString &path); void slotDeleted(const QString &path); + void slotCreated(const QString &path); + void slotCheckDeletedFiles(); private: KDirWatch *m_watcher; + // temporary file and associated remote file QMap m_watched; + // temporary file and the last date it was removed + QMap m_deleted; + QMutex m_deleted_mutex; + QTimer m_timer; }; #endif diff --git a/src/kioexec/kioexecd.cpp b/src/kioexec/kioexecd.cpp --- a/src/kioexec/kioexecd.cpp +++ b/src/kioexec/kioexecd.cpp @@ -33,6 +33,8 @@ #include #include +const int predefinedTimeout = 30000; // 30s + K_PLUGIN_FACTORY_WITH_JSON(KIOExecdFactory, "kioexecd.json", registerPlugin();) @@ -46,17 +48,21 @@ m_watcher = new KDirWatch(this); connect(m_watcher, &KDirWatch::dirty, this, &KIOExecd::slotDirty); + connect(m_watcher, &KDirWatch::created, this, &KIOExecd::slotCreated); connect(m_watcher, &KDirWatch::deleted, this, &KIOExecd::slotDeleted); + m_timer.setSingleShot(true); + m_timer.setInterval(predefinedTimeout); + connect(&m_timer, &QTimer::timeout, this, &KIOExecd::slotCheckDeletedFiles); } KIOExecd::~KIOExecd() { + // Remove the remaining temporary directories with all their files. for (auto it = m_watched.constBegin(); it != m_watched.constEnd(); ++it) { QFileInfo info(it.key()); const auto parentDir = info.path(); qCDebug(KIOEXEC) << "About to delete" << parentDir << "containing" << info.fileName(); - QFile::remove(it.key()); - QDir().rmdir(parentDir); + QDir(parentDir).removeRecursively(); } } @@ -69,10 +75,20 @@ qCDebug(KIOEXEC) << "Going to watch" << path << "for changes, remote destination is" << destUrl; + // Watch the temporary file for modifications, creations or deletions m_watcher->addFile(path); m_watched.insert(path, QUrl(destUrl)); } +void KIOExecd::slotCreated(const QString &path) +{ + m_deleted_mutex.lock(); + m_deleted.remove(path); + m_deleted_mutex.unlock(); + + slotDirty(path); +} + void KIOExecd::slotDirty(const QString &path) { if (!m_watched.contains(path)) { @@ -102,9 +118,34 @@ return; } - qCDebug(KIOEXEC) << "Going to forget" << path; - m_watcher->removeFile(path); - m_watched.remove(path); + m_deleted_mutex.lock(); + m_deleted.insert(path, QDateTime::currentDateTime()); + m_deleted_mutex.unlock(); + m_timer.start(predefinedTimeout); +} + +void KIOExecd::slotCheckDeletedFiles() +{ + m_deleted_mutex.lock(); + // check if the deleted (and not recreated) files where deleted 30s ago or more + for (auto it = m_deleted.begin(); it != m_deleted.end();) { + if (it.value().msecsTo(QDateTime::currentDateTime()) >= predefinedTimeout) { + qCDebug(KIOEXEC) << "Going to forget" << it.key(); + m_watcher->removeFile(it.key()); + m_watched.remove(it.key()); + QFileInfo info(it.key()); + const auto parentDir = info.path(); + qCDebug(KIOEXEC) << "About to delete" << parentDir << "containing" << info.fileName(); + QDir(parentDir).removeRecursively(); + it = m_deleted.erase(it); + } else { + ++it; + } + } + if (!m_deleted.isEmpty()) { + m_timer.start(predefinedTimeout); + } + m_deleted_mutex.unlock(); } #include "kioexecd.moc" diff --git a/src/kioexec/main.cpp b/src/kioexec/main.cpp --- a/src/kioexec/main.cpp +++ b/src/kioexec/main.cpp @@ -258,8 +258,7 @@ QThread::currentThread()->sleep(180); // 3 mn const QString parentDir = info.path(); qDebug() << "about to delete" << parentDir << "containing" << info.fileName(); - QFile(QFile::encodeName(src)).remove(); - QDir().rmdir(parentDir); + QDir(parentDir).removeRecursively(); } }